Report container CPU as a share of the machine, matching Unraid's Docker page

docker stats sums CPU across every logical processor, so Jellyfin's "227%" is
2.3 threads busy — 7% of a 32-thread host, which is what Unraid shows and what
the operator was reading. The card was printing the raw figure and colouring it
against thresholds meant for a percentage, so ordinary background work looked
like an emergency; I twice flagged Jellyfin as pegged on that basis and was
wrong both times. Divides by nproc, not the watchdog's `cores` — that field is
the physical 16 because it compares load averages, and borrowing it here would
have looked reasonable and doubled every reading.
This commit is contained in:
Gmer4Lfe
2026-08-14 19:39:14 -04:00
parent 04a0dcb39a
commit dbc0c8c6d2
2 changed files with 32 additions and 5 deletions
+7 -4
View File
@@ -450,10 +450,12 @@ function _mediaServersSection(nodes) {
const cards = shown.map(s => {
const up = !!s.online;
const dot = !up ? '#c62828' : s.pending_restart || s.update_available ? '#ffb74d' : '#4caf50';
// Colour the CPU against cores, not against 100%: these are containers on a 16-core host, so
// 145% is busy rather than broken, and 1500% would be the number that matters.
// cpu_pct is a share of the whole machine, matching Unraid's Docker page. Thresholds are set
// against that: a single container taking a quarter of the host is worth noticing, half is
// worth alarming about. The earlier version coloured docker's raw per-core-summed figure and
// called 145% alarming when it was 4.5% of a 32-thread machine.
const cpu = s.cpu_pct;
const cpuCol = cpu == null ? '#555' : cpu > 400 ? '#ef5350' : cpu > 150 ? '#ffb74d' : '#888';
const cpuCol = cpu == null ? '#555' : cpu > 50 ? '#ef5350' : cpu > 25 ? '#ffb74d' : '#888';
const flags = [];
if (s.update_available) flags.push(['update available', '#ffb74d']);
@@ -477,7 +479,8 @@ function _mediaServersSection(nodes) {
<div class="vv-arr-stat"><div class="vv-arr-stat-n${s.users ? '' : ' dim'}">${_n(s.users)}</div><div class="vv-arr-stat-l">Users</div></div>
<div class="vv-arr-stat"><div class="vv-arr-stat-n${s.transcodes ? '' : ' dim'}">${_n(s.transcodes)}</div><div class="vv-arr-stat-l">Transcode</div></div>
</div>
${row('CPU', `<span style="color:${cpuCol}">${cpu == null ? '—' : cpu.toFixed(1) + '%'}</span>`)}
${row('CPU', `<span style="color:${cpuCol}" title="${vvEscAttr(s.cpu_raw != null ? s.cpu_raw.toFixed(1) + '% as docker stats reports it — summed across all threads' : '')}">${cpu == null ? '—' : cpu.toFixed(1) + '%'}</span>`
+ (s.cpu_cores ? ` <span style="color:#3a3a3a">${s.cpu_cores.toFixed(1)} cores</span>` : ''))}
${row('Memory', vvEscHtml(s.mem_used || '—') + (s.mem_pct != null ? ` <span style="color:#3a3a3a">${s.mem_pct.toFixed(1)}%</span>` : ''))}
${row('Uptime', s.uptime != null ? _uptime(s.uptime) : '—')}
${s.os ? row('Host OS', vvEscHtml(s.os)) : ''}