From 6aaf04e25be66b708582b9aa304335de5ae772e8 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Thu, 4 Jun 2026 16:29:45 -0400 Subject: [PATCH] Monitor: 1-second CPU/mem/net updates via fast endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split slow cached monitor endpoint from the live stats. monitor_fast.php reads /proc/stat, /proc/meminfo, ZFS arcstats, and /proc/net/dev directly — no cache wrapper, 87ms response. Docker/vm/swap pulled from last full cache so mem card stays complete. Full monitor poll stays at 2s for everything else (GPU, containers, storage, etc). --- Plugin/unraid/api/monitor_fast.php | 48 ++++++++++++ Plugin/unraid/pages/monitor.php | 120 +++++++++++++++-------------- 2 files changed, 112 insertions(+), 56 deletions(-) create mode 100644 Plugin/unraid/api/monitor_fast.php diff --git a/Plugin/unraid/api/monitor_fast.php b/Plugin/unraid/api/monitor_fast.php new file mode 100644 index 0000000..8cd616f --- /dev/null +++ b/Plugin/unraid/api/monitor_fast.php @@ -0,0 +1,48 @@ + vv_cpu_per_core(), + 'mem' => [ + 'total_kb' => $_totalKb, + 'free_kb' => $_freeKb, + 'used_kb' => max(0, $_totalKb - $_freeKb), + 'arc_kb' => $_arcKb, + 'docker_kb' => $_dockerKb, + 'vm_kb' => $_vmKb, + 'system_kb' => max(0, $_totalKb - $_freeKb - $_arcKb - $_dockerKb - $_vmKb), + 'swap_total_kb' => $_swapTotal, + 'swap_used_kb' => $_swapUsed, + 'top_procs' => $_topProcs, + ], + 'net' => vv_network_stats(), + 'ts' => time(), +]); diff --git a/Plugin/unraid/pages/monitor.php b/Plugin/unraid/pages/monitor.php index bcaf999..3eb00a7 100644 --- a/Plugin/unraid/pages/monitor.php +++ b/Plugin/unraid/pages/monitor.php @@ -898,62 +898,7 @@ function vvPollMonitor() { } })(); - // ── CPU ───────────────────────────────────────────────────────────────── - const cpu = d.cpu ?? {}; - document.getElementById('vv-cpu-body').innerHTML = vvRenderCpu(cpu); - - vvCpuHistory.push(cpu.overall ?? 0); - if (vvCpuHistory.length > VV_HIST_MAX) vvCpuHistory.shift(); - vvDrawChart(document.getElementById('vv-cpu-canvas'), vvCpuHistory, '#4caf50', 'rgba(76,175,80,0.18)', true); - - // ── Memory ────────────────────────────────────────────────────────────── - const mem = d.mem ?? {}; - document.getElementById('vv-memory-body').innerHTML = vvRenderMemory(mem); - - // ── Network ───────────────────────────────────────────────────────────── - const net = d.net ?? {}; - if (net.available) { - const rx = net.rx_bps ?? 0; - const tx = net.tx_bps ?? 0; - const linkMbps = net.speed_mbps ?? 0; - const linkLabel = linkMbps >= 1000 ? (linkMbps / 1000) + ' Gb/s' : linkMbps ? linkMbps + ' Mb/s' : '—'; - const linkBps = linkMbps * 1e6; - - vvNetRxHistory.push(rx); - vvNetTxHistory.push(tx); - if (vvNetRxHistory.length > VV_HIST_MAX) vvNetRxHistory.shift(); - if (vvNetTxHistory.length > VV_HIST_MAX) vvNetTxHistory.shift(); - - const maxSeen = Math.max(...vvNetRxHistory, ...vvNetTxHistory, 1); - const maxBps = maxSeen * 1.25; // auto-scale with 25% headroom - const peakRx = Math.max(...vvNetRxHistory, 0); // window peak (last 2 min) - const peakTx = Math.max(...vvNetTxHistory, 0); - - const ipRows = [ - net.local_ip ? `
LAN  ${net.local_ip}
` : '', - net.ext_ip ? `
EXT  ${net.ext_ip}
` : '', - net.ts_ip ? `
TS   ${net.ts_ip}
` : '', - ].filter(Boolean).join(''); - - document.getElementById('vv-network-body').innerHTML = - `
-
-
${net.iface}  ·  ${linkLabel}
-
- ━ IN (RX)${vvFmtBps(rx)}peak ${vvFmtBps(peakRx)} - ━ OUT (TX)${vvFmtBps(tx)}peak ${vvFmtBps(peakTx)} -
-
-
${ipRows}
-
- `; - - vvDrawNetChart(document.getElementById('vv-net-canvas'), vvNetRxHistory, vvNetTxHistory, maxBps); - } else { - document.getElementById('vv-network-body').innerHTML = '

No network interface detected

'; - } - - // ── CPU title (core count + temp to its right) ──────────────────────────── + // ── CPU title (core count + temp — watchdog data only comes from full poll) ── const _cpuTitleEl = document.getElementById('vv-cpu-title'); if (_cpuTitleEl) { const _cpuTemp = d.watchdog?.stability?.cpu_temp ?? null; @@ -1634,6 +1579,69 @@ function vvPollMonitor() { vvPollMonitor(); setInterval(vvPollMonitor, 2000); +// ── Fast poll: CPU, memory, network — 1-second live updates ────────────────── +function vvPollFast() { + fetch('/plugins/varaverk/api/monitor_fast.php') + .then(r => r.json()) + .then(d => { + // CPU + const cpu = d.cpu ?? {}; + document.getElementById('vv-cpu-body').innerHTML = vvRenderCpu(cpu); + vvCpuHistory.push(cpu.overall ?? 0); + if (vvCpuHistory.length > VV_HIST_MAX) vvCpuHistory.shift(); + vvDrawChart(document.getElementById('vv-cpu-canvas'), vvCpuHistory, '#4caf50', 'rgba(76,175,80,0.18)', true); + + // Memory + document.getElementById('vv-memory-body').innerHTML = vvRenderMemory(d.mem ?? {}); + + // Network + const net = d.net ?? {}; + if (net.available) { + const rx = net.rx_bps ?? 0; + const tx = net.tx_bps ?? 0; + const linkMbps = net.speed_mbps ?? 0; + const linkLabel = linkMbps >= 1000 ? (linkMbps / 1000) + ' Gb/s' : linkMbps ? linkMbps + ' Mb/s' : '—'; + + vvNetRxHistory.push(rx); + vvNetTxHistory.push(tx); + if (vvNetRxHistory.length > VV_HIST_MAX) vvNetRxHistory.shift(); + if (vvNetTxHistory.length > VV_HIST_MAX) vvNetTxHistory.shift(); + + const maxSeen = Math.max(...vvNetRxHistory, ...vvNetTxHistory, 1); + const maxBps = maxSeen * 1.25; + const peakRx = Math.max(...vvNetRxHistory, 0); + const peakTx = Math.max(...vvNetTxHistory, 0); + + const ipRows = [ + net.local_ip ? `
LAN  ${net.local_ip}
` : '', + net.ext_ip ? `
EXT  ${net.ext_ip}
` : '', + net.ts_ip ? `
TS   ${net.ts_ip}
` : '', + ].filter(Boolean).join(''); + + document.getElementById('vv-network-body').innerHTML = + `
+
+
${net.iface}  ·  ${linkLabel}
+
+ ━ IN (RX)${vvFmtBps(rx)}peak ${vvFmtBps(peakRx)} + ━ OUT (TX)${vvFmtBps(tx)}peak ${vvFmtBps(peakTx)} +
+
+
${ipRows}
+
+ `; + + vvDrawNetChart(document.getElementById('vv-net-canvas'), vvNetRxHistory, vvNetTxHistory, maxBps); + } else { + document.getElementById('vv-network-body').innerHTML = '

No network interface detected

'; + } + }) + .catch(() => {}); +} + +vvPollFast(); +setInterval(vvPollFast, 1000); + // Pin pools card width to CPU card width across rows function vvSyncCardWidths() { const cpu = document.getElementById('vv-cpu');