1use crate::error::{AdminError, Result};
4use actrix_proto::{ServiceStatus, SystemMetrics};
5use std::sync::Arc;
6
7pub async fn collect_system_metrics() -> Result<SystemMetrics> {
13 let (_, details) = pwrzv::get_power_reserve_level_with_details_direct()
14 .await
15 .map_err(|e| {
16 platform::recording::warn!("Failed to read system metrics: {}", e);
17 AdminError::Metrics(e.to_string())
18 })?;
19
20 let val = |key: &str| details.get(key).map(|d| d.value).unwrap_or(0.0);
21
22 Ok(SystemMetrics {
23 cpu_usage_percent: (val("cpu_usage") * 100.0) as f64,
24 memory_usage_percent: (val("memory_usage") * 100.0) as f64,
25 memory_used_bytes: 0, memory_total_bytes: 0,
27 network_rx_bytes: 0,
28 network_tx_bytes: 0,
29 disk_used_bytes: 0,
30 disk_total_bytes: 0,
31 load_average_1m: val("cpu_load") as f64,
32 load_average_5m: None,
33 load_average_15m: None,
34 })
35}
36
37pub type ServiceStatusProviderForReport = Arc<dyn Fn() -> Vec<ServiceStatus> + Send + Sync>;
39
40pub fn collect_service_status(
45 service_status_provider: Option<ServiceStatusProviderForReport>,
46) -> Vec<ServiceStatus> {
47 if let Some(provider) = service_status_provider {
48 provider()
49 } else {
50 Vec::new()
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[tokio::test]
60 #[ignore] async fn test_collect_metrics() {
62 if let Ok(metrics) = collect_system_metrics().await {
63 assert!(metrics.memory_total_bytes > 0);
64 assert!(metrics.cpu_usage_percent >= 0.0);
65 }
66 }
67}