use serde::Serialize;
use std::time::Duration;
use sysinfo::{self, Networks, Pid, System};
use tracing::{debug, error};
const UPDATE_INTERVAL: Duration = Duration::from_secs(60);
const TO_MB: u64 = 1_000_000;
#[derive(Debug, Serialize)]
struct Metrics {
physical_cpu_threads: usize,
system_cpu_usage_percent: f32,
process: Option<ProcessMetrics>,
}
#[derive(Debug, Serialize)]
struct ProcessMetrics {
cpu_usage_percent: f32,
memory_used_mb: u64,
bytes_read: u64,
bytes_written: u64,
total_mb_read: u64,
total_mb_written: u64,
}
pub async fn init_metrics(pid: u32) {
let mut sys = System::new();
let mut networks = Networks::new_with_refreshed_list();
let pid = Pid::from_u32(pid);
loop {
refresh_metrics(&mut sys, &mut networks, pid);
let process = match sys.process(pid) {
Some(antnode) => {
let disk_usage = antnode.disk_usage();
let process = ProcessMetrics {
cpu_usage_percent: antnode.cpu_usage(),
memory_used_mb: antnode.memory() / TO_MB,
bytes_read: disk_usage.read_bytes,
bytes_written: disk_usage.written_bytes,
total_mb_read: disk_usage.total_read_bytes / TO_MB,
total_mb_written: disk_usage.total_written_bytes / TO_MB,
};
Some(process)
}
None => {
None
}
};
let cpu_stat = sys.global_cpu_info();
let metrics = Metrics {
physical_cpu_threads: sys.cpus().len(),
system_cpu_usage_percent: cpu_stat.cpu_usage(),
process,
};
match serde_json::to_string(&metrics) {
Ok(metrics) => debug!("{metrics}"),
Err(err) => error!("Metrics error, could not serialize to JSON {err}"),
}
tokio::time::sleep(UPDATE_INTERVAL).await;
}
}
fn refresh_metrics(sys: &mut System, networks: &mut Networks, pid: Pid) {
sys.refresh_process(pid);
sys.refresh_memory();
sys.refresh_cpu();
networks.refresh();
}