use serde::Serialize;
use std::time::Duration;
use systemstat::{Platform, System};
use tokio::time;
#[derive(Serialize)]
pub struct SystemStats {
cpu_load: f32,
memory_used: u64,
memory_total: u64,
network_rx: u64,
network_tx: u64,
}
pub struct Monitor {
sys: System,
}
impl Monitor {
pub fn new() -> Self {
Self { sys: System::new() }
}
pub async fn collect_stats(&self) -> Result<SystemStats, Box<dyn std::error::Error>> {
let cpu = self.sys.cpu_load_aggregate()?;
time::sleep(Duration::from_secs(1)).await;
let cpu = cpu.done()?;
let memory = self.sys.memory()?;
let networks = self.sys.networks()?;
let mut network_rx = 0;
let mut network_tx = 0;
for (interface_name, _) in networks.iter() {
if let Ok(stats) = self.sys.network_stats(interface_name) {
network_rx += stats.rx_bytes.as_u64();
network_tx += stats.tx_bytes.as_u64();
}
}
Ok(SystemStats {
cpu_load: cpu.user * 100.0,
memory_used: memory.total.as_u64() - memory.free.as_u64(),
memory_total: memory.total.as_u64(),
network_rx,
network_tx,
})
}
}