Testing
This commit is contained in:
parent
4bb36b7735
commit
088c42e55a
@ -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
|
||||
|
||||
@ -48,7 +48,7 @@ fn render_metrics(
|
||||
let mut data = WidgetData::new(
|
||||
title,
|
||||
Some(WidgetStatus::new(widget_status)),
|
||||
vec!["Service".to_string(), "Memory".to_string(), "Disk".to_string()]
|
||||
vec!["Service".to_string(), "Memory".to_string(), "CPU".to_string(), "Disk".to_string()]
|
||||
);
|
||||
|
||||
|
||||
@ -60,6 +60,7 @@ fn render_metrics(
|
||||
"No services reported".to_string(),
|
||||
"".to_string(),
|
||||
"".to_string(),
|
||||
"".to_string(),
|
||||
],
|
||||
);
|
||||
render_widget_data(frame, area, data);
|
||||
@ -94,6 +95,7 @@ fn render_metrics(
|
||||
vec![
|
||||
svc.name.clone(),
|
||||
format_memory_value(svc.memory_used_mb, svc.memory_quota_mb),
|
||||
format_cpu_value(svc.cpu_percent),
|
||||
format_disk_value(svc.disk_used_gb),
|
||||
],
|
||||
);
|
||||
@ -140,6 +142,16 @@ fn format_memory_value(used: f32, quota: f32) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn format_cpu_value(cpu_percent: f32) -> String {
|
||||
if cpu_percent >= 0.1 {
|
||||
format!("{:.1}%", cpu_percent)
|
||||
} else if cpu_percent > 0.0 {
|
||||
"<0.1%".to_string()
|
||||
} else {
|
||||
"—".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn format_disk_value(used: f32) -> String {
|
||||
if used >= 1.0 {
|
||||
format!("{:.1} GiB", used)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user