Testing
This commit is contained in:
@@ -17,6 +17,14 @@ pub struct ServiceCollector {
|
||||
pub interval: Duration,
|
||||
pub services: Vec<String>,
|
||||
pub timeout_ms: u64,
|
||||
pub cpu_tracking: std::sync::Arc<tokio::sync::Mutex<std::collections::HashMap<u32, CpuSample>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct CpuSample {
|
||||
utime: u64,
|
||||
stime: u64,
|
||||
timestamp: std::time::Instant,
|
||||
}
|
||||
|
||||
impl ServiceCollector {
|
||||
@@ -26,6 +34,7 @@ impl ServiceCollector {
|
||||
interval: Duration::from_millis(interval_ms),
|
||||
services,
|
||||
timeout_ms: 10000, // 10 second timeout for service checks
|
||||
cpu_tracking: std::sync::Arc::new(tokio::sync::Mutex::new(std::collections::HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,12 +160,61 @@ impl ServiceCollector {
|
||||
// Convert pages to MB (assuming 4KB pages)
|
||||
let memory_mb = (rss_pages * 4) as f32 / 1024.0;
|
||||
|
||||
// For CPU, we'd need to track over time - simplified to 0 for now
|
||||
// TODO: Implement proper CPU percentage calculation
|
||||
let cpu_percent = 0.0;
|
||||
// Calculate CPU percentage
|
||||
let cpu_percent = self.calculate_cpu_usage(pid, &stat_fields).await.unwrap_or(0.0);
|
||||
|
||||
Ok((memory_mb, cpu_percent))
|
||||
}
|
||||
|
||||
async fn calculate_cpu_usage(&self, pid: u32, stat_fields: &[&str]) -> Result<f32, CollectorError> {
|
||||
// Parse CPU time fields from /proc/pid/stat
|
||||
let utime: u64 = stat_fields[13].parse().map_err(|e| CollectorError::ParseError {
|
||||
message: format!("Failed to parse utime: {}", e),
|
||||
})?;
|
||||
let stime: u64 = stat_fields[14].parse().map_err(|e| CollectorError::ParseError {
|
||||
message: format!("Failed to parse stime: {}", e),
|
||||
})?;
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
let current_sample = CpuSample {
|
||||
utime,
|
||||
stime,
|
||||
timestamp: now,
|
||||
};
|
||||
|
||||
let mut cpu_tracking = self.cpu_tracking.lock().await;
|
||||
|
||||
let cpu_percent = if let Some(previous_sample) = cpu_tracking.get(&pid) {
|
||||
let time_delta = now.duration_since(previous_sample.timestamp).as_secs_f32();
|
||||
if time_delta > 0.1 { // At least 100ms between samples
|
||||
let utime_delta = current_sample.utime.saturating_sub(previous_sample.utime);
|
||||
let stime_delta = current_sample.stime.saturating_sub(previous_sample.stime);
|
||||
let total_delta = utime_delta + stime_delta;
|
||||
|
||||
// Convert from jiffies to CPU percentage
|
||||
// sysconf(_SC_CLK_TCK) is typically 100 on Linux
|
||||
let hz = 100.0; // Clock ticks per second
|
||||
let cpu_time_used = total_delta as f32 / hz;
|
||||
let cpu_percent = (cpu_time_used / time_delta) * 100.0;
|
||||
|
||||
// Cap at reasonable values
|
||||
cpu_percent.min(999.9)
|
||||
} else {
|
||||
0.0 // Too soon for accurate measurement
|
||||
}
|
||||
} else {
|
||||
0.0 // First measurement, no baseline
|
||||
};
|
||||
|
||||
// Store current sample for next calculation
|
||||
cpu_tracking.insert(pid, current_sample);
|
||||
|
||||
// Clean up old entries (processes that no longer exist)
|
||||
let cutoff = now - Duration::from_secs(300); // 5 minutes
|
||||
cpu_tracking.retain(|_, sample| sample.timestamp > cutoff);
|
||||
|
||||
Ok(cpu_percent)
|
||||
}
|
||||
|
||||
async fn get_service_disk_usage(&self, service: &str) -> Result<f32, CollectorError> {
|
||||
// Only check the most likely path to avoid multiple du calls
|
||||
|
||||
Reference in New Issue
Block a user