Add server-side metrics ring buffer, seed dashboard charts from server history
Background task samples system (CPU/RAM/GPU) and per-target (FPS/timing) metrics every 1s into a 120-sample ring buffer (~2 min). New API endpoint GET /system/metrics-history returns the buffer. Dashboard charts now seed from server history on load instead of sessionStorage, surviving page refreshes. Also removes emoji from brightness source labels. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,10 +10,9 @@ import { renderPerfSection, initPerfCharts, startPerfPolling, stopPerfPolling }
|
||||
import { startAutoRefresh } from './tabs.js';
|
||||
|
||||
const DASHBOARD_COLLAPSED_KEY = 'dashboard_collapsed';
|
||||
const FPS_HISTORY_KEY = 'dashboard_fps_history';
|
||||
const MAX_FPS_SAMPLES = 30;
|
||||
const MAX_FPS_SAMPLES = 120;
|
||||
|
||||
let _fpsHistory = _loadFpsHistory(); // { targetId: number[] }
|
||||
let _fpsHistory = {}; // { targetId: number[] }
|
||||
let _fpsCharts = {}; // { targetId: Chart }
|
||||
let _lastRunningIds = []; // sorted target IDs from previous render
|
||||
let _uptimeBase = {}; // { targetId: { seconds, timestamp } }
|
||||
@@ -21,19 +20,6 @@ let _uptimeTimer = null;
|
||||
let _uptimeElements = {}; // { targetId: HTMLElement } — cached DOM refs
|
||||
let _metricsElements = new Map();
|
||||
|
||||
function _loadFpsHistory() {
|
||||
try {
|
||||
const raw = sessionStorage.getItem(FPS_HISTORY_KEY);
|
||||
if (raw) return JSON.parse(raw);
|
||||
} catch {}
|
||||
return {};
|
||||
}
|
||||
|
||||
function _saveFpsHistory() {
|
||||
try { sessionStorage.setItem(FPS_HISTORY_KEY, JSON.stringify(_fpsHistory)); }
|
||||
catch {}
|
||||
}
|
||||
|
||||
function _pushFps(targetId, value) {
|
||||
if (!_fpsHistory[targetId]) _fpsHistory[targetId] = [];
|
||||
_fpsHistory[targetId].push(value);
|
||||
@@ -120,8 +106,26 @@ function _createFpsChart(canvasId, history, fpsTarget) {
|
||||
});
|
||||
}
|
||||
|
||||
function _initFpsCharts(runningTargetIds) {
|
||||
async function _initFpsCharts(runningTargetIds) {
|
||||
_destroyFpsCharts();
|
||||
|
||||
// Seed FPS history from server ring buffer on first load
|
||||
if (Object.keys(_fpsHistory).length === 0 && runningTargetIds.length > 0) {
|
||||
try {
|
||||
const resp = await fetch(`${API_BASE}/system/metrics-history`, { headers: getHeaders() });
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
const serverTargets = data.targets || {};
|
||||
for (const id of runningTargetIds) {
|
||||
const samples = serverTargets[id] || [];
|
||||
_fpsHistory[id] = samples.map(s => s.fps).filter(v => v != null);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Silently ignore — charts will fill from polling
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up history for targets that are no longer running
|
||||
for (const id of Object.keys(_fpsHistory)) {
|
||||
if (!runningTargetIds.includes(id)) delete _fpsHistory[id];
|
||||
@@ -133,7 +137,7 @@ function _initFpsCharts(runningTargetIds) {
|
||||
const fpsTarget = parseFloat(canvas.dataset.fpsTarget) || 30;
|
||||
_fpsCharts[id] = _createFpsChart(`dashboard-fps-${id}`, history, fpsTarget);
|
||||
}
|
||||
_saveFpsHistory();
|
||||
|
||||
_cacheMetricsElements(runningTargetIds);
|
||||
}
|
||||
|
||||
@@ -194,7 +198,7 @@ function _updateRunningMetrics(enrichedRunning) {
|
||||
}
|
||||
}
|
||||
}
|
||||
_saveFpsHistory();
|
||||
|
||||
}
|
||||
|
||||
function _updateProfilesInPlace(profiles) {
|
||||
@@ -412,7 +416,7 @@ export async function loadDashboard(forceFullRender = false) {
|
||||
${_sectionContent('perf', renderPerfSection())}
|
||||
</div>
|
||||
<div class="dashboard-dynamic">${dynamicHtml}</div>`;
|
||||
initPerfCharts();
|
||||
await initPerfCharts();
|
||||
} else {
|
||||
const dynamic = container.querySelector('.dashboard-dynamic');
|
||||
if (dynamic.innerHTML !== dynamicHtml) {
|
||||
@@ -421,7 +425,7 @@ export async function loadDashboard(forceFullRender = false) {
|
||||
}
|
||||
_lastRunningIds = runningIds;
|
||||
_cacheUptimeElements();
|
||||
_initFpsCharts(runningIds);
|
||||
await _initFpsCharts(runningIds);
|
||||
_startUptimeTimer();
|
||||
startPerfPolling();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user