perf: report top-5 processes by CPU and memory
Collect every named process per sample, then send the top-5 by CPU and the top-5 by memory as a `top_processes` object alongside the existing single top-CPU/top-memory scalars (kept for backward compatibility). opsbase shows these as 5-row lists in the device's Live performance card. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+43
-15
@@ -57,6 +57,9 @@ struct PendingSample {
|
||||
top_cpu_pct: f64,
|
||||
top_mem_name: String,
|
||||
top_mem_mb: i64,
|
||||
/// Top-5 processes by CPU (name, normalised %) and by memory (name, MB).
|
||||
top_cpu_procs: Vec<(String, f64)>,
|
||||
top_mem_procs: Vec<(String, i64)>,
|
||||
attempts: u32,
|
||||
}
|
||||
|
||||
@@ -156,33 +159,48 @@ fn collect_sample(sys: &mut hbb_common::sysinfo::System) -> Option<PendingSample
|
||||
// CPU% reading (both 0-100 of the whole machine).
|
||||
let cpu_count = sys.cpus().len().max(1) as f64;
|
||||
|
||||
let mut top_cpu: Option<(&str, f32)> = None;
|
||||
let mut top_mem: Option<(&str, u64)> = None;
|
||||
// Collect every (named) process once, then derive the top-5 by CPU and by
|
||||
// memory. The single top_cpu_*/top_mem_* scalars are kept for backward
|
||||
// compatibility (older servers ignore top_processes).
|
||||
let mut procs: Vec<(&str, f64, i64)> = Vec::new();
|
||||
let mut proc_count = 0i64;
|
||||
for proc in sys.processes().values() {
|
||||
proc_count += 1;
|
||||
let name = proc.name();
|
||||
// Some kernel-side rows show up with empty names on Windows;
|
||||
// skip them so we don't ever render a top-CPU row with no
|
||||
// label.
|
||||
// skip them so we don't ever render a top row with no label.
|
||||
if name.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let cu = proc.cpu_usage();
|
||||
if cu.is_finite() && cu > top_cpu.map(|(_, v)| v).unwrap_or(0.0) {
|
||||
top_cpu = Some((name, cu));
|
||||
}
|
||||
let mu = proc.memory();
|
||||
if mu > top_mem.map(|(_, v)| v).unwrap_or(0) {
|
||||
top_mem = Some((name, mu));
|
||||
}
|
||||
let cu = if cu.is_finite() { (cu as f64 / cpu_count).min(100.0) } else { 0.0 };
|
||||
let mb = (proc.memory() / 1024 / 1024) as i64;
|
||||
procs.push((name, cu, mb));
|
||||
}
|
||||
|
||||
let (top_cpu_name, top_cpu_pct) = top_cpu
|
||||
.map(|(n, v)| (n.to_string(), (v as f64 / cpu_count).min(100.0)))
|
||||
let mut by_cpu = procs.clone();
|
||||
by_cpu.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
|
||||
let top_cpu_procs: Vec<(String, f64)> = by_cpu
|
||||
.iter()
|
||||
.take(5)
|
||||
.map(|(n, c, _)| (n.to_string(), *c))
|
||||
.collect();
|
||||
|
||||
let mut by_mem = procs;
|
||||
by_mem.sort_by(|a, b| b.2.cmp(&a.2));
|
||||
let top_mem_procs: Vec<(String, i64)> = by_mem
|
||||
.iter()
|
||||
.take(5)
|
||||
.map(|(n, _, m)| (n.to_string(), *m))
|
||||
.collect();
|
||||
|
||||
let (top_cpu_name, top_cpu_pct) = top_cpu_procs
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let (top_mem_name, top_mem_mb) = top_mem
|
||||
.map(|(n, v)| (n.to_string(), (v / 1024 / 1024) as i64))
|
||||
let (top_mem_name, top_mem_mb) = top_mem_procs
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
||||
Some(PendingSample {
|
||||
@@ -196,6 +214,8 @@ fn collect_sample(sys: &mut hbb_common::sysinfo::System) -> Option<PendingSample
|
||||
top_cpu_pct,
|
||||
top_mem_name,
|
||||
top_mem_mb,
|
||||
top_cpu_procs,
|
||||
top_mem_procs,
|
||||
attempts: 0,
|
||||
})
|
||||
}
|
||||
@@ -277,6 +297,14 @@ async fn post_batch(batch: &[PendingSample]) -> Result<()> {
|
||||
"top_cpu_pct": s.top_cpu_pct,
|
||||
"top_mem_name": s.top_mem_name,
|
||||
"top_mem_mb": s.top_mem_mb,
|
||||
"top_processes": {
|
||||
"cpu": s.top_cpu_procs.iter()
|
||||
.map(|(n, p)| hbb_common::serde_json::json!({"name": n, "pct": p}))
|
||||
.collect::<Vec<_>>(),
|
||||
"mem": s.top_mem_procs.iter()
|
||||
.map(|(n, m)| hbb_common::serde_json::json!({"name": n, "mb": m}))
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Reference in New Issue
Block a user