use sysinfo::{Disks, System}; #[derive(Debug, Clone)] pub struct SystemMetrics { pub cpu_usage: f32, pub memory_usage: f32, pub swap_usage: f32, pub disk_usage: f32, } #[derive(Debug, Clone)] pub struct ThresholdViolation { pub metric_name: String, pub current_value: f32, pub threshold: f32, pub severity: Severity, } #[derive(Debug, Clone)] pub enum Severity { Warning, Critical, } pub struct ResourceThreshold { pub name: String, pub get_usage_fn: fn(&System, &Disks) -> f32, pub threshold: f32, pub critical_threshold: Option, // Nouveau: seuil critique pub value: f32, } impl ResourceThreshold { pub fn new(name: String, get_usage_fn: fn(&System, &Disks) -> f32, threshold: f32) -> Self { Self { name, get_usage_fn, threshold, critical_threshold: None, value: 0.0, } } pub fn with_critical_threshold(mut self, critical_threshold: f32) -> Self { self.critical_threshold = Some(critical_threshold); self } pub fn check(&mut self, sys: &System, disks: &Disks) -> Option { self.value = (self.get_usage_fn)(sys, disks); if let Some(critical) = self.critical_threshold { if self.value > critical { return Some(ThresholdViolation { metric_name: self.name.clone(), current_value: self.value, threshold: critical, severity: Severity::Critical, }); } } if self.value > self.threshold { Some(ThresholdViolation { metric_name: self.name.clone(), current_value: self.value, threshold: self.threshold, severity: Severity::Warning, }) } else { None } } } pub fn get_cpu_usage(sys: &System, _: &Disks) -> f32 { sys.global_cpu_usage() } pub fn get_memory_usage(sys: &System, _: &Disks) -> f32 { let total_memory = sys.total_memory() as f32; let used_memory = sys.used_memory() as f32; if total_memory == 0.0 { return 0.0; } used_memory / total_memory * 100.0 } pub fn get_swap_usage(sys: &System, _: &Disks) -> f32 { let total_swap = sys.total_swap() as f32; let used_swap = sys.used_swap() as f32; if total_swap == 0.0 { return 0.0; } used_swap / total_swap * 100.0 } pub fn get_disk_usage(_: &System, disks: &Disks) -> f32 { let mut total_used_space = 0.0; let mut total_space = 0.0; for disk in disks { if let Some(mount_point) = disk.mount_point().to_str() { if mount_point == "/" || mount_point == "/home" { total_used_space += disk.total_space() as f32 - disk.available_space() as f32; total_space += disk.total_space() as f32; } } } if total_space == 0.0 { return 0.0; // Avoid division by zero } (total_used_space / total_space) * 100.0 } pub fn get_default_resource_thresholds() -> Vec { vec![ ResourceThreshold::new( "CPU".to_string(), get_cpu_usage, 80.0, ).with_critical_threshold(95.0), ResourceThreshold::new( "Memory".to_string(), get_memory_usage, 80.0, ).with_critical_threshold(95.0), ResourceThreshold::new( "Swap".to_string(), get_swap_usage, 80.0, ).with_critical_threshold(95.0), ResourceThreshold::new( "Disk".to_string(), get_disk_usage, 80.0, ).with_critical_threshold(90.0), ] } pub struct SystemMonitor { pub system: System, pub disks: Disks, pub thresholds: Vec, } impl SystemMonitor { pub fn new() -> Self { let mut system = System::new_all(); let mut disks = Disks::new_with_refreshed_list(); system.refresh_all(); disks.refresh(true); Self { system, disks, thresholds: get_default_resource_thresholds(), } } pub fn new_with_thresholds(thresholds: Vec) -> Self { let mut system = System::new_all(); let mut disks = Disks::new_with_refreshed_list(); system.refresh_all(); disks.refresh(true); Self { system, disks, thresholds, } } pub fn refresh(&mut self) { self.system.refresh_all(); self.disks.refresh(true); } pub fn check_thresholds(&mut self) -> Vec { let mut violations = Vec::new(); for threshold in &mut self.thresholds { if let Some(violation) = threshold.check(&self.system, &self.disks) { violations.push(violation); } } violations } pub fn get_metrics(&self) -> SystemMetrics { SystemMetrics { cpu_usage: get_cpu_usage(&self.system, &self.disks), memory_usage: get_memory_usage(&self.system, &self.disks), swap_usage: get_swap_usage(&self.system, &self.disks), disk_usage: get_disk_usage(&self.system, &self.disks), } } } impl Default for SystemMonitor { fn default() -> Self { Self::new() } }