diff --git a/containers/libreportal/frontend/js/components/admin/admin-system.js b/containers/libreportal/frontend/js/components/admin/admin-system.js index b764f1d..46b05c7 100644 --- a/containers/libreportal/frontend/js/components/admin/admin-system.js +++ b/containers/libreportal/frontend/js/components/admin/admin-system.js @@ -201,11 +201,26 @@ class AdminSystem { `; + + // Load is read relative to core count: a load equal to the number of + // cores means "fully used, no queue" — normal, not alarming. Only flag + // it red once load clearly exceeds capacity (tasks genuinely queuing). + // The ring fills toward 2x cores so load == cores sits mid-gauge + // instead of maxing out (which read as a constant red alarm on a + // low-core box). The old backend load1_percent capped at cores == 100%, + // so anything near capacity pinned the gauge red. + const cores = cpu.cores || 1; + const load1 = Number(cpu.load1 ?? 0); + const loadRatio = load1 / cores; + const loadColor = loadRatio >= 1.7 ? 'status-danger' + : loadRatio >= 1.0 ? 'status-warning' + : 'status-success'; + return ` ${wrap('cpu', C.gauge(cpu.percent || 0, { label: 'CPU', sublabel: `${cpu.cores || '?'} cores` }))} ${wrap('mem', C.gauge(mem.percent || 0, { label: 'Memory', sublabel: `${this.bytes(mem.used)} / ${this.bytes(mem.total)}` }))} ${wrap('disk', C.gauge(rootDisk.percent || 0, { label: 'Disk', sublabel: rootDisk.mount || '/' }))} - ${wrap('load1', C.gauge(cpu.load1_percent || 0, { label: 'Load', display: (cpu.load1 ?? 0), suffix: '', sublabel: `1m · ${cpu.load5 ?? '–'}/${cpu.load15 ?? '–'}` }))}`; + ${wrap('load1', C.gauge(load1, { label: 'Load', display: load1.toFixed(2), suffix: '', max: cores * 2, color: loadColor, sublabel: `1m · ${cpu.load5 ?? '–'}/${cpu.load15 ?? '–'}` }))}`; } _applyLive(s) {