LocalMode
Core

Network Logging

Monitor and log network requests including model downloads

LocalMode provides network logging utilities to monitor downloads, track progress, and debug network issues. This is especially useful for tracking model downloads and displaying progress to users.

Overview

The network logging system tracks:

  • Model downloads with progress
  • API requests (if any external services are used)
  • Upload/download byte counts
  • Request timing and statistics

Network logging is opt-in and local-only. No data is sent anywhere—this is purely for local debugging and UI progress indicators.

Quick Start

import { onNetworkRequest, getNetworkStats } from '@localmode/core';

// Subscribe to network events
const unsubscribe = onNetworkRequest((entry) => {
  if (entry.category === 'model' && entry.state === 'in-progress') {
    console.log(`Downloading: ${entry.url} (${entry.progress}%)`);
  }
});

// Later: get statistics
const stats = getNetworkStats();
console.log(`Downloaded: ${stats.totalDownloadBytes} bytes`);

// Clean up when done
unsubscribe();

Creating a Network Logger

import { createNetworkLogger } from '@localmode/core';

const logger = createNetworkLogger({
  maxEntries: 500, // Keep last 500 entries
  logHeaders: false, // Don't log request headers
  categories: ['model'], // Only log model downloads
});

Configuration Options

Prop

Type

Subscribing to Events

Real-time Progress Updates

import { onNetworkRequest } from '@localmode/core';

const unsubscribe = onNetworkRequest((entry) => {
  switch (entry.state) {
    case 'pending':
      console.log(`Starting: ${entry.url}`);
      break;
    case 'in-progress':
      console.log(`Progress: ${entry.progress}%`);
      updateProgressBar(entry.progress);
      break;
    case 'completed':
      console.log(`Completed: ${entry.url} (${entry.duration}ms)`);
      break;
    case 'failed':
      console.error(`Failed: ${entry.url} - ${entry.error}`);
      break;
  }
});

Model Download Progress UI

import { onNetworkRequest } from '@localmode/core';

function ModelDownloadProgress() {
  const [progress, setProgress] = useState<number | null>(null);
  const [downloading, setDownloading] = useState(false);

  useEffect(() => {
    const unsubscribe = onNetworkRequest((entry) => {
      if (entry.category === 'model') {
        if (entry.state === 'in-progress') {
          setDownloading(true);
          setProgress(entry.progress ?? 0);
        } else if (entry.state === 'completed' || entry.state === 'failed') {
          setDownloading(false);
          setProgress(null);
        }
      }
    });

    return unsubscribe;
  }, []);

  if (!downloading) return null;

  return (
    <div className="progress-bar">
      <div style={{ width: `${progress}%` }} />
      <span>{progress}%</span>
    </div>
  );
}

Retrieving Logs

Get All Logs

import { getNetworkLogs } from '@localmode/core';

const logs = getNetworkLogs();
console.log(`Total requests: ${logs.length}`);

Filter Logs

import { getNetworkLogs } from '@localmode/core';

// Get model downloads only
const modelLogs = getNetworkLogs({
  category: 'model',
});

// Get failed requests
const failedLogs = getNetworkLogs({
  state: 'failed',
});

// Get recent requests (last hour)
const recentLogs = getNetworkLogs({
  since: new Date(Date.now() - 60 * 60 * 1000),
  limit: 50,
  order: 'desc',
});

// Filter by URL pattern
const huggingFaceLogs = getNetworkLogs({
  urlPattern: /huggingface\.co/,
});

Filter Options

Prop

Type

Network Statistics

import { getNetworkStats } from '@localmode/core';

const stats = getNetworkStats();

console.log(`Total requests: ${stats.totalRequests}`);
console.log(`Completed: ${stats.completedRequests}`);
console.log(`Failed: ${stats.failedRequests}`);
console.log(`Downloaded: ${(stats.totalDownloadBytes / 1024 / 1024).toFixed(2)} MB`);
console.log(`Average speed: ${(stats.averageSpeed / 1024).toFixed(2)} KB/s`);
console.log(`Requests/min: ${stats.requestsPerMinute}`);

// Stats by category
console.log('By category:', stats.byCategory);

// Stats by HTTP status
console.log('By status:', stats.byStatus);

Stats Structure

Prop

Type

Clearing Logs

import { clearNetworkLogs } from '@localmode/core';

// Clear all logs
clearNetworkLogs();

// Clear logs older than 7 days
clearNetworkLogs({ olderThan: '7d' });

// Clear logs older than specific date
clearNetworkLogs({ olderThan: new Date('2024-01-01') });

Duration formats: s (seconds), m (minutes), h (hours), d (days), w (weeks)

Log Entry Structure

Prop

Type

Wrapping Fetch

For full request logging, wrap the global fetch:

import { wrapFetchWithLogging, unwrapFetch, isFetchWrapped } from '@localmode/core';

// Wrap global fetch
wrapFetchWithLogging({
  category: 'api',
  logHeaders: true,
});

// Now all fetch calls are logged
await fetch('https://api.example.com/data');

// Check if fetch is wrapped
console.log(isFetchWrapped()); // true

// Restore original fetch
unwrapFetch();

Wrapping fetch affects all requests in your application. Use with care in production environments.

On this page