This commit addresses several key issues identified during development: Major Changes: - Replace hardcoded top CPU/RAM process display with real system data - Add intelligent process monitoring to CpuCollector using ps command - Fix disk metrics permission issues in systemd collector - Optimize service collection to focus on status, memory, and disk only - Update dashboard widgets to display live process information Process Monitoring Implementation: - Added collect_top_cpu_process() and collect_top_ram_process() methods - Implemented ps-based monitoring with accurate CPU percentages - Added filtering to prevent self-monitoring artifacts (ps commands) - Enhanced error handling and validation for process data - Dashboard now shows realistic values like "claude (PID 2974) 11.0%" Service Collection Optimization: - Removed CPU monitoring from systemd collector for efficiency - Enhanced service directory permission error logging - Simplified services widget to show essential metrics only - Fixed service-to-directory mapping accuracy UI and Dashboard Improvements: - Reorganized dashboard layout with btop-inspired multi-panel design - Updated system panel to include real top CPU/RAM process display - Enhanced widget formatting and data presentation - Removed placeholder/hardcoded data throughout the interface Technical Details: - Updated agent/src/collectors/cpu.rs with process monitoring - Modified dashboard/src/ui/mod.rs for real-time process display - Enhanced systemd collector error handling and disk metrics - Updated CLAUDE.md documentation with implementation details
112 lines
3.7 KiB
Rust
112 lines
3.7 KiB
Rust
use async_trait::async_trait;
|
|
use cm_dashboard_shared::{Metric, SharedError};
|
|
use std::time::Duration;
|
|
|
|
pub mod cached_collector;
|
|
pub mod cpu;
|
|
pub mod memory;
|
|
pub mod disk;
|
|
pub mod systemd;
|
|
pub mod error;
|
|
|
|
pub use error::CollectorError;
|
|
|
|
/// Performance metrics for a collector
|
|
#[derive(Debug, Clone)]
|
|
pub struct PerformanceMetrics {
|
|
pub last_collection_time: Duration,
|
|
pub collection_efficiency_percent: f32,
|
|
}
|
|
|
|
/// Base trait for all collectors with extreme efficiency requirements
|
|
#[async_trait]
|
|
pub trait Collector: Send + Sync {
|
|
/// Name of this collector
|
|
fn name(&self) -> &str;
|
|
|
|
/// Collect all metrics this collector provides
|
|
async fn collect(&self) -> Result<Vec<Metric>, CollectorError>;
|
|
|
|
/// Get performance metrics for monitoring collector efficiency
|
|
fn get_performance_metrics(&self) -> Option<PerformanceMetrics> {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// CPU efficiency rules for all collectors
|
|
pub mod efficiency {
|
|
/// CRITICAL: All collectors must follow these efficiency rules to minimize system impact
|
|
|
|
/// 1. 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)
|
|
|
|
/// 2. 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
|
|
|
|
/// 3. 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
|
|
|
|
/// 4. 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)
|
|
|
|
/// 5. 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
|
|
|
|
/// 6. 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
|
|
|
|
pub const PERFORMANCE_TARGET_OVERHEAD_PERCENT: f32 = 0.1;
|
|
}
|
|
|
|
/// Utility functions for efficient system data collection
|
|
pub mod utils {
|
|
use std::fs;
|
|
use super::CollectorError;
|
|
|
|
/// Read entire file content efficiently
|
|
pub fn read_proc_file(path: &str) -> Result<String, CollectorError> {
|
|
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<f32, CollectorError> {
|
|
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<u64, CollectorError> {
|
|
s.trim().parse().map_err(|e: std::num::ParseIntError| CollectorError::Parse {
|
|
value: s.to_string(),
|
|
error: e.to_string(),
|
|
})
|
|
}
|
|
|
|
/// Split string and get nth element safely
|
|
pub fn split_nth<'a>(s: &'a str, delimiter: char, n: usize) -> Option<&'a str> {
|
|
s.split(delimiter).nth(n)
|
|
}
|
|
} |