"use client"; /** * SystemMonitor — Real-time system metrics widget * * Displays CPU/memory/uptime and token throughput metrics. * Fetches from /api/monitoring/health periodically. * * @module shared/components/SystemMonitor */ import { useState, useEffect, useRef } from "react"; import Card from "./Card"; const REFRESH_INTERVAL = 10000; // 10s function formatUptime(seconds) { if (!seconds) return "N/A"; const d = Math.floor(seconds / 86400); const h = Math.floor((seconds % 86400) / 3600); const m = Math.floor((seconds % 3600) / 60); if (d > 0) return `${d}d ${h}h`; if (h > 0) return `${h}h ${m}m`; return `${m}m`; } function formatBytes(bytes) { if (!bytes) return "0 B"; const units = ["B", "KB", "MB", "GB"]; let i = 0; let val = bytes; while (val >= 1024 && i < units.length - 1) { val /= 1024; i++; } return `${val.toFixed(1)} ${units[i]}`; } function MetricRow({ icon, label, value, color = "text-text-main" }) { return (
{label}
{value}
); } export default function SystemMonitor({ compact = false }) { const [metrics, setMetrics] = useState(null); const [error, setError] = useState(false); const mountedRef = useRef(true); useEffect(() => { mountedRef.current = true; async function poll() { try { const res = await fetch("/api/monitoring/health"); if (!mountedRef.current) return; if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); if (!mountedRef.current) return; setMetrics(data); setError(false); } catch { if (mountedRef.current) setError(true); } } poll(); const interval = setInterval(poll, REFRESH_INTERVAL); return () => { mountedRef.current = false; clearInterval(interval); }; }, []); if (error && !metrics) { return (
error Unable to load system metrics
); } if (!metrics) { return (
); } const memUsed = metrics.memory?.heapUsed || metrics.memoryUsage?.heapUsed || 0; const memTotal = metrics.memory?.heapTotal || metrics.memoryUsage?.heapTotal || 1; const memPercent = Math.round((memUsed / memTotal) * 100); const memColor = memPercent > 80 ? "text-red-400" : memPercent > 60 ? "text-amber-400" : "text-green-400"; if (compact) { return (
{memPercent}% mem ⏱ {formatUptime(metrics.uptime)}
); } return (

System Monitor

{metrics.version && ( )} {metrics.activeConnections !== undefined && ( )} {metrics.circuitBreakers && ( 0 ? "text-amber-400" : "text-green-400"} /> )}
{/* Memory bar */}
80 ? "bg-red-400" : memPercent > 60 ? "bg-amber-400" : "bg-green-400" }`} style={{ width: `${memPercent}%` }} role="progressbar" aria-valuenow={memPercent} aria-valuemin={0} aria-valuemax={100} aria-label={`Memory usage: ${memPercent}%`} />
); }