feat(containers): toon totale CPU/MEM per pod en onderscheid inactive vs stats-pauze

This commit is contained in:
kodi
2026-02-20 08:06:46 +01:00
parent 427d7b47a1
commit d18d0c0f77
+51 -30
View File
@@ -229,6 +229,10 @@
.pod-group-row:hover td { .pod-group-row:hover td {
background: rgba(255,255,255,0.07); background: rgba(255,255,255,0.07);
} }
.stale {
opacity: 0.65;
font-style: italic;
}
</style> </style>
</head> </head>
@@ -770,8 +774,8 @@
<td class="muted">-</td> <td class="muted">-</td>
<td>${isRealPod ? '<span class="btn small muted">pod</span>' : '<span class="muted">-</span>'}</td> <td>${isRealPod ? '<span class="btn small muted">pod</span>' : '<span class="muted">-</span>'}</td>
<td class="muted num" id="podcpu-${cssSafeId(pod)}">-</td> <td class="muted num" id="podcpu-${cssSafeId(pod)}" data-podstatus="${esc((podStatus && podStatus[pod]) || '')}">-</td>
<td class="muted num" id="podmem-${cssSafeId(pod)}">-</td> <td class="muted num" id="podmem-${cssSafeId(pod)}" data-podstatus="${esc((podStatus && podStatus[pod]) || '')}">-</td>
<td class="mono">${esc(podPortsText)}</td> <td class="mono">${esc(podPortsText)}</td>
<td> <td>
${isRealPod ? ` ${isRealPod ? `
@@ -820,10 +824,9 @@
} }
async function fetchContainers() { async function fetchContainers() {
const [containers, pods] = await Promise.all([
const [containers, pods] = await Promise.all([ api('/containers-dashboard', 'GET'),
api('/containers-dashboard', 'GET'), api('/pods-dashboard', 'GET')
api('/pods-dashboard', 'GET')
]); ]);
const list = Array.isArray(containers) ? containers : (containers?.containers || []); const list = Array.isArray(containers) ? containers : (containers?.containers || []);
@@ -862,42 +865,45 @@
if (!cname) continue; if (!cname) continue;
const key = cssSafeId(cname); const key = cssSafeId(cname);
const cpuPct = Number(st?.CPUPerc ?? st?.CPU ?? st?.AvgCPU ?? 0);
const memBytes = Number(st?.MemUsage ?? 0);
const memPct = Number(st?.MemPerc ?? 0);
const pod = containersC2P.get(cname); const pod = containersC2P.get(cname);
if (pod) { if (pod) {
const cpuPct = Number(st?.CPUPerc ?? st?.CPU ?? st?.AvgCPU ?? 0);
const memBytes = Number(st?.MemUsage ?? 0);
const memPct = Number(st?.MemPerc ?? 0);
podCpu.set(pod, (podCpu.get(pod) || 0) + cpuPct); podCpu.set(pod, (podCpu.get(pod) || 0) + cpuPct);
podMem.set(pod, (podMem.get(pod) || 0) + memBytes); podMem.set(pod, (podMem.get(pod) || 0) + memBytes);
podMemPct.set(pod, (podMemPct.get(pod) || 0) + memPct); podMemPct.set(pod, (podMemPct.get(pod) || 0) + memPct);
} }
for (const [pod, cpuSum] of podCpu.entries()) {
const el = document.getElementById(`podcpu-${cssSafeId(pod)}`);
if (el) el.textContent = cpuSum.toFixed(2) + "%";
}
for (const [pod, memSum] of podMem.entries()) {
const el = document.getElementById(`podmem-${cssSafeId(pod)}`);
if (el) {
const memPct = podMemPct.get(pod) || 0;
el.textContent = `${formatBytes(memSum)} (${memPct.toFixed(1)}%)`;
}
}
// CPU: jouw API geeft CPU als fractie (0.00384 -> 0.384%) // CPU: jouw API geeft CPU als fractie (0.00384 -> 0.384%)
const cpuPct = Number(st?.CPUPerc ?? st?.CPU ?? st?.AvgCPU ?? 0);
const cpuEl = document.getElementById(`cpu-${key}`); const cpuEl = document.getElementById(`cpu-${key}`);
if (cpuEl) cpuEl.textContent = cpuPct.toFixed(2) + "%"; if (cpuEl) cpuEl.textContent = cpuPct.toFixed(2) + "%";
// MEM: bytes + percentage // MEM: bytes + percentage
const memEl = document.getElementById(`mem-${key}`); const memEl = document.getElementById(`mem-${key}`);
if (memEl) { if (memEl) {
const mem = formatBytes(st?.MemUsage); const mem = formatBytes(memBytes);
const memp = Number(st?.MemPerc ?? 0); memEl.textContent = `${mem} (${memPct.toFixed(1)}%)`;
memEl.textContent = `${mem} (${memp.toFixed(1)}%)`; }
}
// NA de container-loop: pod totals renderen
for (const [pod, cpuSum] of podCpu.entries()) {
const el = document.getElementById(`podcpu-${cssSafeId(pod)}`);
if (el) {
el.textContent = cpuSum.toFixed(2) + "%";
el.classList.remove('stale');
}
}
for (const [pod, memSum] of podMem.entries()) {
const el = document.getElementById(`podmem-${cssSafeId(pod)}`);
if (el) {
const mp = podMemPct.get(pod) || 0;
el.textContent = `${formatBytes(memSum)} (${mp.toFixed(1)}%)`;
el.classList.remove('stale');
} }
} }
}); });
@@ -916,12 +922,27 @@
function resetPodTotals() { function resetPodTotals() {
document.querySelectorAll('[id^="podcpu-"]').forEach(el => { document.querySelectorAll('[id^="podcpu-"]').forEach(el => {
el.textContent = '-'; const ps = String(el.getAttribute('data-podstatus') || '').toLowerCase();
if (ps === 'inactive') {
el.textContent = '-';
el.classList.remove('stale');
} else {
el.textContent = '—';
el.classList.add('stale');
}
}); });
document.querySelectorAll('[id^="podmem-"]').forEach(el => { document.querySelectorAll('[id^="podmem-"]').forEach(el => {
el.textContent = '-'; const ps = String(el.getAttribute('data-podstatus') || '').toLowerCase();
if (ps === 'inactive') {
el.textContent = '-';
el.classList.remove('stale');
} else {
el.textContent = '—';
el.classList.add('stale');
}
}); });
} }
async function containerInspect(name) { async function containerInspect(name) {
try { try {