use async_trait::async_trait; use cm_dashboard_shared::{Metric, StatusTracker}; pub mod backup; pub mod cpu; pub mod disk; pub mod error; pub mod memory; pub mod nixos; pub mod smart; pub mod systemd; pub use error::CollectorError; /// Base trait for all collectors with extreme efficiency requirements #[async_trait] pub trait Collector: Send + Sync { /// Collect all metrics this collector provides async fn collect(&self, status_tracker: &mut StatusTracker) -> Result, CollectorError>; } /// CPU efficiency rules for all collectors pub mod efficiency { //! CRITICAL: All collectors must follow these efficiency rules to minimize system impact //! //! # FILE READING RULES //! - Read entire files in single syscall when possible //! - Use BufReader only for very large files (>4KB) //! - Never read files character by character //! - Cache file descriptors when safe (immutable paths) //! //! # PARSING RULES //! - Use split() instead of regex for simple patterns //! - Parse numbers with from_str() not complex parsing //! - Avoid string allocations in hot paths //! - Use str::trim() before parsing numbers //! //! # MEMORY ALLOCATION RULES //! - Reuse Vec buffers when possible //! - Pre-allocate collections with known sizes //! - Use str slices instead of String when possible //! - Avoid clone() in hot paths //! //! # SYSTEM CALL RULES //! - Minimize syscalls - prefer single reads over multiple //! - Use /proc filesystem efficiently //! - Avoid spawning processes when /proc data available //! - Cache static data (like CPU count) //! //! # ERROR HANDLING RULES //! - Use Result<> but minimize allocation in error paths //! - Log errors at debug level only to avoid I/O overhead //! - Graceful degradation - missing metrics better than failing //! - Never panic in collectors //! //! # CONCURRENCY RULES //! - Collectors must be thread-safe but avoid locks //! - Use atomic operations for simple counters //! - Avoid shared mutable state between collections //! - Each collection should be independent } /// Utility functions for efficient system data collection pub mod utils { use super::CollectorError; use std::fs; /// Read entire file content efficiently pub fn read_proc_file(path: &str) -> Result { fs::read_to_string(path).map_err(|e| CollectorError::SystemRead { path: path.to_string(), error: e.to_string(), }) } /// Parse float from string slice efficiently pub fn parse_f32(s: &str) -> Result { s.trim() .parse() .map_err(|e: std::num::ParseFloatError| CollectorError::Parse { value: s.to_string(), error: e.to_string(), }) } /// Parse integer from string slice efficiently pub fn parse_u64(s: &str) -> Result { s.trim() .parse() .map_err(|e: std::num::ParseIntError| CollectorError::Parse { value: s.to_string(), error: e.to_string(), }) } }