Add top CPU and RAM process monitoring to System widget

- Implement get_top_cpu_process() and get_top_ram_process() functions in SystemCollector
- Add top_cpu_process and top_ram_process fields to SystemSummary data structure
- Update System widget to display top processes as description rows
- Show process name and percentage usage for highest CPU and RAM consumers
- Skip kernel threads and filter out processes with minimal usage (<0.1%)
This commit is contained in:
2025-10-14 21:47:52 +02:00
parent 2bffbaa000
commit f3b6d12f68
5 changed files with 85 additions and 5 deletions

View File

@@ -60,6 +60,10 @@ pub struct SystemSummary {
pub cpu_cstate: Option<Vec<String>>,
#[serde(default)]
pub logged_in_users: Option<Vec<String>>,
#[serde(default)]
pub top_cpu_process: Option<String>,
#[serde(default)]
pub top_ram_process: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]

View File

@@ -109,10 +109,10 @@ fn render_metrics(
// Add latency information for nginx sites if available
let service_name_with_latency = if let Some(parent) = &svc.sub_service {
if parent == "nginx" {
match (&svc.latency_ms, &svc.description) {
(Some(latency), _) => format!("{} {:.0}ms", svc.name, latency),
(None, Some(desc)) if !desc.is_empty() => format!("{} {}", svc.name, desc[0]),
_ => svc.name.clone(),
match &svc.latency_ms {
Some(latency) if *latency >= 5000.0 => format!("{} unreachable", svc.name), // Timeout (5s+)
Some(latency) => format!("{} {:.0}ms", svc.name, latency),
None => format!("{} unreachable", svc.name), // Connection failed
}
} else {
svc.name.clone()

View File

@@ -90,6 +90,16 @@ fn render_metrics(
description_lines.push(user_line);
}
}
// Add top CPU process
if let Some(cpu_proc) = &summary.top_cpu_process {
description_lines.push(format!("Top CPU: {}", cpu_proc));
}
// Add top RAM process
if let Some(ram_proc) = &summary.top_ram_process {
description_lines.push(format!("Top RAM: {}", ram_proc));
}
system_dataset.add_row(
overall_status.clone(),