use std::sync::Arc;
#[cfg(feature = "system-metrics")]
use prometheus::{Gauge, IntGauge, Registry};
#[cfg(feature = "system-metrics")]
use sysinfo::{Pid, System};
#[cfg(feature = "system-metrics")]
#[derive(Clone, Debug)]
pub struct SystemMetrics {
registry: Arc<Registry>,
system: Arc<std::sync::Mutex<System>>,
process_cpu_usage_percent: Gauge,
process_memory_bytes: IntGauge,
process_memory_percent: Gauge,
}
#[cfg(feature = "system-metrics")]
impl SystemMetrics {
pub fn new() -> crate::Result<Self> {
let registry = Arc::new(Registry::new());
let process_cpu_usage_percent = Gauge::new(
"process_cpu_usage_percent",
"CPU usage percentage of the CDK process (0-100)",
)?;
registry.register(Box::new(process_cpu_usage_percent.clone()))?;
let process_memory_bytes = IntGauge::new(
"process_memory_bytes",
"Memory usage of the CDK process in bytes",
)?;
registry.register(Box::new(process_memory_bytes.clone()))?;
let process_memory_percent = Gauge::new(
"process_memory_percent",
"Memory usage percentage of the CDK process (0-100)",
)?;
registry.register(Box::new(process_memory_percent.clone()))?;
let system = Arc::new(std::sync::Mutex::new(System::new()));
let result = Self {
registry,
system,
process_cpu_usage_percent,
process_memory_bytes,
process_memory_percent,
};
Ok(result)
}
#[must_use]
pub fn registry(&self) -> Arc<Registry> {
Arc::<Registry>::clone(&self.registry)
}
pub fn update_metrics(&self) -> crate::Result<()> {
let mut system = self.system.lock().map_err(|e| {
crate::error::PrometheusError::SystemMetrics(format!("Failed to lock system: {e}"))
})?;
system.refresh_all();
let total_memory = i64::try_from(system.total_memory()).unwrap_or(i64::MAX);
if let Some(process) = system.process(Pid::from(std::process::id() as usize)) {
let process_cpu = process.cpu_usage();
self.process_cpu_usage_percent.set(f64::from(process_cpu));
let process_memory = i64::try_from(process.memory()).unwrap_or(i64::MAX);
self.process_memory_bytes.set(process_memory);
if total_memory > 0 {
#[allow(clippy::cast_precision_loss)]
let process_memory_percent = (process_memory as f64 / total_memory as f64) * 100.0;
self.process_memory_percent.set(process_memory_percent);
}
}
drop(system);
Ok(())
}
}