varaverk: memory card — top 5 procs by RSS as horizontal strip under total
This commit is contained in:
@@ -145,6 +145,19 @@ function vv_memory_breakdown(): array {
|
|||||||
$freeKb = max(0, $mem['MemAvailable'] ?? 0);
|
$freeKb = max(0, $mem['MemAvailable'] ?? 0);
|
||||||
$systemKb = max(0, $totalKb - $freeKb - $arcKb - $dockerKb - $vmKb);
|
$systemKb = max(0, $totalKb - $freeKb - $arcKb - $dockerKb - $vmKb);
|
||||||
|
|
||||||
|
// Top processes by RSS — group same-named procs, take top 5
|
||||||
|
$grouped = [];
|
||||||
|
$psOut = shell_exec("ps -eo comm,rss --sort=-rss 2>/dev/null | tail -n +2 | head -40") ?: '';
|
||||||
|
foreach (explode("\n", trim($psOut)) as $line) {
|
||||||
|
$parts = preg_split('/\s+/', trim($line), 2);
|
||||||
|
if (count($parts) === 2 && is_numeric($parts[1]) && (int)$parts[1] > 0)
|
||||||
|
$grouped[$parts[0]] = ($grouped[$parts[0]] ?? 0) + (int)$parts[1];
|
||||||
|
}
|
||||||
|
arsort($grouped);
|
||||||
|
$topProcs = [];
|
||||||
|
foreach (array_slice($grouped, 0, 5, true) as $name => $kb)
|
||||||
|
$topProcs[] = ['name' => $name, 'kb' => $kb];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'total_kb' => $totalKb,
|
'total_kb' => $totalKb,
|
||||||
'system_kb' => $systemKb,
|
'system_kb' => $systemKb,
|
||||||
@@ -152,6 +165,7 @@ function vv_memory_breakdown(): array {
|
|||||||
'zfs_kb' => $arcKb,
|
'zfs_kb' => $arcKb,
|
||||||
'docker_kb' => $dockerKb,
|
'docker_kb' => $dockerKb,
|
||||||
'free_kb' => $freeKb,
|
'free_kb' => $freeKb,
|
||||||
|
'top_procs' => $topProcs,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -260,24 +260,16 @@ function vvRenderMemory(mem) {
|
|||||||
const usedPct = Math.round(usedKb / total * 100);
|
const usedPct = Math.round(usedKb / total * 100);
|
||||||
const totalColor = usedPct >= 85 ? '#f44336' : usedPct >= 65 ? '#ff9800' : '#ccc';
|
const totalColor = usedPct >= 85 ? '#f44336' : usedPct >= 65 ? '#ff9800' : '#ccc';
|
||||||
|
|
||||||
const buckets = [
|
const procs = mem.top_procs ?? [];
|
||||||
{ label: 'System', kb: mem.system_kb ?? 0, color: VV_MEM_COLORS.system },
|
const procStrip = procs.map(p =>
|
||||||
{ label: 'VM', kb: mem.vm_kb ?? 0, color: VV_MEM_COLORS.vm },
|
`<span style="white-space:nowrap;color:#888;font-size:10px;">${p.name} <span style="color:#aaa;font-weight:600;">${vvFmtGib(p.kb)}</span></span>`
|
||||||
{ label: 'ZFS', kb: mem.zfs_kb ?? 0, color: VV_MEM_COLORS.zfs },
|
).join('<span style="color:#333;margin:0 6px;">·</span>');
|
||||||
{ label: 'Docker', kb: mem.docker_kb ?? 0, color: VV_MEM_COLORS.docker },
|
|
||||||
];
|
|
||||||
const top3 = [...buckets].sort((a, b) => b.kb - a.kb).slice(0, 3);
|
|
||||||
const top3Html = top3.map(b =>
|
|
||||||
`<div><span style="color:${b.color};font-size:9px;margin-right:3px;">●</span>`+
|
|
||||||
`<span style="color:#888;font-size:9px;">${b.label} </span>`+
|
|
||||||
`<span style="color:#aaa;font-size:10px;font-weight:600;">${vvFmtGib(b.kb)}</span></div>`
|
|
||||||
).join('');
|
|
||||||
|
|
||||||
let html = `<div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px;">
|
let html = `<div style="margin-bottom:6px;">
|
||||||
<div style="font-size:14px;font-weight:600;color:${totalColor};">
|
<div style="font-size:14px;font-weight:600;color:${totalColor};margin-bottom:5px;">
|
||||||
${vvFmtGib(usedKb)} <span style="font-size:11px;color:#555;font-weight:400;">/ ${vvFmtGib(total)}</span>
|
${vvFmtGib(usedKb)} <span style="font-size:11px;color:#555;font-weight:400;">/ ${vvFmtGib(total)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align:right;line-height:1.7;">${top3Html}</div>
|
<div style="font-size:10px;color:#666;flex-wrap:wrap;line-height:1.8;">${procStrip}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
html += vvMemRow('System', mem.system_kb ?? 0, total, VV_MEM_COLORS.system)
|
html += vvMemRow('System', mem.system_kb ?? 0, total, VV_MEM_COLORS.system)
|
||||||
+ vvMemRow('VM', mem.vm_kb ?? 0, total, VV_MEM_COLORS.vm)
|
+ vvMemRow('VM', mem.vm_kb ?? 0, total, VV_MEM_COLORS.vm)
|
||||||
|
|||||||
Reference in New Issue
Block a user