mirror of
https://github.com/csehviktor/status-monitor.git
synced 2026-04-29 08:37:36 +02:00
98 lines
2.7 KiB
Rust
98 lines
2.7 KiB
Rust
use std::collections::HashMap;
|
|
use common::metrics::CPUBreakdown;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
struct CPUValues {
|
|
pub user: u64,
|
|
pub nice: u64,
|
|
pub system: u64,
|
|
pub idle: u64,
|
|
pub iowait: u64,
|
|
pub irq: u64,
|
|
pub softirq: u64,
|
|
pub steal: u64,
|
|
pub guest: u64,
|
|
pub guest_nice: u64,
|
|
}
|
|
|
|
impl CPUValues {
|
|
pub fn total(&self) -> u64 {
|
|
self.user + self.nice + self.system + self.idle + self.iowait +
|
|
self.irq + self.softirq + self.steal + self.guest + self.guest_nice
|
|
}
|
|
}
|
|
|
|
pub struct CPUStatReader {
|
|
previous_stats: HashMap<String, CPUValues>,
|
|
}
|
|
|
|
impl CPUStatReader {
|
|
pub fn new() -> Self {
|
|
Self { previous_stats: HashMap::new() }
|
|
}
|
|
|
|
pub fn read_global_cpu_stats(&mut self) -> anyhow::Result<CPUBreakdown> {
|
|
let content = std::fs::read_to_string("/proc/stat").unwrap();
|
|
|
|
let cpu_line = content
|
|
.lines()
|
|
.find(|line| line.starts_with("cpu "))
|
|
.unwrap();
|
|
|
|
self.parse_cpu_line(cpu_line)
|
|
}
|
|
|
|
fn parse_cpu_line(&mut self, line: &str) -> anyhow::Result<CPUBreakdown> {
|
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
|
|
|
let cpu_name = parts[0].to_string();
|
|
|
|
let parse = |num: usize| -> u64 {
|
|
parts[num].parse().ok().unwrap()
|
|
};
|
|
|
|
let values = CPUValues {
|
|
user: parse(1),
|
|
nice: parse(2),
|
|
system: parse(3),
|
|
idle: parse(4),
|
|
iowait: parse(5),
|
|
irq: parse(6),
|
|
softirq: parse(7),
|
|
steal: parse(8),
|
|
guest: parse(9),
|
|
guest_nice: parse(10),
|
|
};
|
|
|
|
let previous = self.previous_stats.get(&cpu_name).copied();
|
|
let percentages = self.calculate_percentages(&values, previous);
|
|
|
|
self.previous_stats.insert(cpu_name, values);
|
|
|
|
Ok(percentages)
|
|
}
|
|
|
|
fn calculate_percentages(&self, current: &CPUValues, previous: Option<CPUValues>) -> CPUBreakdown {
|
|
let Some(prev) = previous else {
|
|
return CPUBreakdown::default();
|
|
};
|
|
|
|
let total_delta = current.total().saturating_sub(prev.total()) as f32;
|
|
if total_delta <= 0.0 {
|
|
return CPUBreakdown::default();
|
|
}
|
|
|
|
let calculate_pct = |current: u64, prev: u64| {
|
|
(current.saturating_sub(prev) as f32 / total_delta) * 100.0
|
|
};
|
|
|
|
CPUBreakdown {
|
|
system: calculate_pct(current.system, prev.system),
|
|
user: calculate_pct(current.user, prev.user),
|
|
idle: calculate_pct(current.idle, prev.idle),
|
|
steal: calculate_pct(current.steal, prev.steal),
|
|
iowait: calculate_pct(current.iowait, prev.iowait),
|
|
}
|
|
}
|
|
}
|