#![allow(improper_ctypes)] use pscand_core::helpers::{ResourceHelper, SystemHelper}; use pscand_core::scanner::{MetricValue, Scanner}; use pscand_core::Result; use std::collections::HashMap; use std::time::Duration; struct SystemScanner { _prev_cpu: Option>, } impl Default for SystemScanner { fn default() -> Self { Self { _prev_cpu: None } } } #[unsafe(no_mangle)] pub extern "C" fn pscand_scanner() -> Box { Box::new(SystemScanner::default()) } impl Scanner for SystemScanner { fn name(&self) -> &'static str { "system" } fn interval(&self) -> Duration { Duration::from_secs(1) } fn init(&mut self, _config: &toml::Value) -> Result<()> { Ok(()) } fn collect(&self) -> Result> { let mut metrics = HashMap::new(); if let Ok(uptime) = SystemHelper::uptime() { metrics.insert( "uptime_secs".to_string(), MetricValue::from_f64(uptime.as_secs_f64()), ); } if let Ok((load1, load5, load15)) = SystemHelper::load_average() { metrics.insert("load_1m".to_string(), MetricValue::from_f64(load1)); metrics.insert("load_5m".to_string(), MetricValue::from_f64(load5)); metrics.insert("load_15m".to_string(), MetricValue::from_f64(load15)); } if let Ok(cpu) = ResourceHelper::cpu_usage() { if let Some(total) = cpu.get("total_usage_percent") { metrics.insert("cpu_percent".to_string(), MetricValue::from_f64(*total)); } } if let Ok(mem) = ResourceHelper::memory_info() { if let Some(total) = mem.get("MemTotal") { metrics.insert( "mem_total_bytes".to_string(), MetricValue::Integer(*total as i64), ); } if let Some(available) = mem.get("MemAvailable") { metrics.insert( "mem_available_bytes".to_string(), MetricValue::Integer(*available as i64), ); } if let (Some(used), Some(total)) = (mem.get("MemAvailable"), mem.get("MemTotal")) { let used_mem = total.saturating_sub(*used); metrics.insert( "mem_used_bytes".to_string(), MetricValue::Integer(used_mem as i64), ); } } Ok(metrics) } fn cleanup(&mut self) -> Result<()> { Ok(()) } }