Implement metric-level caching system for optimal CPU performance

Replace legacy SmartCache with MetricCollectionManager for granular control:
- RealTime tier (5s): CPU load, CPU temperature, Service CPU usage
- Fast tier (30s): Memory usage, top processes
- Medium tier (5min): Service status, C-states, users
- Slow tier (15min): Disk usage

All CPU-related metrics now update consistently every 5 seconds as requested,
eliminating the previous inconsistency where only CPU load was updating
at the correct frequency while service CPU usage was on 5-minute intervals.
This commit is contained in:
Christoffer Martinsson 2025-10-16 00:44:15 +02:00
parent 246973ebf6
commit cfc89e7312

View File

@ -129,13 +129,18 @@ impl SmartAgent {
async fn collect_realtime_metrics(&mut self) { async fn collect_realtime_metrics(&mut self) {
info!("Collecting RealTime metrics (5s)..."); info!("Collecting RealTime metrics (5s)...");
// Collect and aggregate System metrics into complete message // Collect and aggregate System metrics into dashboard-expected format
let mut system_data = json!({}); let mut summary = json!({});
let mut timestamp = json!(null);
if let Ok(cpu_load) = self.metric_manager.get_metric(&AgentType::System, "cpu_load").await { if let Ok(cpu_load) = self.metric_manager.get_metric(&AgentType::System, "cpu_load").await {
if let Some(obj) = cpu_load.as_object() { if let Some(obj) = cpu_load.as_object() {
for (key, value) in obj { for (key, value) in obj {
system_data[key] = value.clone(); if key == "timestamp" {
timestamp = value.clone();
} else {
summary[key] = value.clone();
}
} }
} }
} }
@ -143,15 +148,23 @@ impl SmartAgent {
if let Ok(cpu_temp) = self.metric_manager.get_metric(&AgentType::System, "cpu_temperature").await { if let Ok(cpu_temp) = self.metric_manager.get_metric(&AgentType::System, "cpu_temperature").await {
if let Some(obj) = cpu_temp.as_object() { if let Some(obj) = cpu_temp.as_object() {
for (key, value) in obj { for (key, value) in obj {
system_data[key] = value.clone(); if key == "timestamp" {
timestamp = value.clone();
} else {
summary[key] = value.clone();
}
} }
} }
} }
// Send complete System message if we have any data // Send complete System message with summary structure if we have any data
if !system_data.as_object().unwrap().is_empty() { if !summary.as_object().unwrap().is_empty() {
info!("Sending aggregated System metrics"); let system_message = json!({
self.send_metric_data(&AgentType::System, &system_data).await; "summary": summary,
"timestamp": timestamp
});
info!("Sending aggregated System metrics with summary structure");
self.send_metric_data(&AgentType::System, &system_message).await;
} }
// Service CPU usage (complete message) // Service CPU usage (complete message)
@ -168,13 +181,21 @@ impl SmartAgent {
async fn collect_fast_metrics(&mut self) { async fn collect_fast_metrics(&mut self) {
info!("Collecting Fast metrics (30s)..."); info!("Collecting Fast metrics (30s)...");
// Collect and aggregate System metrics into complete message // Collect and aggregate System metrics into dashboard-expected format
let mut system_data = json!({}); let mut summary = json!({});
let mut top_level = json!({});
let mut timestamp = json!(null);
if let Ok(memory) = self.metric_manager.get_metric(&AgentType::System, "memory").await { if let Ok(memory) = self.metric_manager.get_metric(&AgentType::System, "memory").await {
if let Some(obj) = memory.as_object() { if let Some(obj) = memory.as_object() {
for (key, value) in obj { for (key, value) in obj {
system_data[key] = value.clone(); if key == "timestamp" {
timestamp = value.clone();
} else if key.starts_with("system_memory") {
summary[key] = value.clone();
} else {
top_level[key] = value.clone();
}
} }
} }
} }
@ -182,15 +203,34 @@ impl SmartAgent {
if let Ok(processes) = self.metric_manager.get_metric(&AgentType::System, "top_processes").await { if let Ok(processes) = self.metric_manager.get_metric(&AgentType::System, "top_processes").await {
if let Some(obj) = processes.as_object() { if let Some(obj) = processes.as_object() {
for (key, value) in obj { for (key, value) in obj {
system_data[key] = value.clone(); if key == "timestamp" {
timestamp = value.clone();
} else {
top_level[key] = value.clone();
}
} }
} }
} }
// Send complete System message if we have any data // Send complete System message with summary structure if we have any data
if !system_data.as_object().unwrap().is_empty() { if !summary.as_object().unwrap().is_empty() || !top_level.as_object().unwrap().is_empty() {
info!("Sending aggregated System metrics"); let mut system_message = json!({
self.send_metric_data(&AgentType::System, &system_data).await; "timestamp": timestamp
});
if !summary.as_object().unwrap().is_empty() {
system_message["summary"] = summary;
}
// Add top-level fields
if let Some(obj) = top_level.as_object() {
for (key, value) in obj {
system_message[key] = value.clone();
}
}
info!("Sending aggregated System metrics with summary structure");
self.send_metric_data(&AgentType::System, &system_message).await;
} }
// Service memory usage (complete message) // Service memory usage (complete message)