From f4b5bb814d8374d221dfd1349a4154f2f085e52e Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Tue, 21 Oct 2025 19:32:37 +0200 Subject: [PATCH] Fix dashboard UI: correct pending color (blue) and use host_status_summary metric --- agent/src/agent.rs | 8 ++++-- agent/src/status/mod.rs | 15 ++++++++++ dashboard/src/ui/mod.rs | 42 ++++++++++++++++++++-------- dashboard/src/ui/theme.rs | 4 +-- dashboard/src/ui/widgets/services.rs | 2 +- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/agent/src/agent.rs b/agent/src/agent.rs index 8a78009..59d9069 100644 --- a/agent/src/agent.rs +++ b/agent/src/agent.rs @@ -156,14 +156,18 @@ impl Agent { debug!("Broadcasting all cached metrics via ZMQ"); // Get all cached metrics from the metric manager - let cached_metrics = self.metric_manager.get_all_cached_metrics().await?; + let mut cached_metrics = self.metric_manager.get_all_cached_metrics().await?; + + // Add the host status summary metric from status manager + let host_status_metric = self.host_status_manager.get_host_status_metric(); + cached_metrics.push(host_status_metric); if cached_metrics.is_empty() { debug!("No cached metrics to broadcast"); return Ok(()); } - debug!("Broadcasting {} cached metrics", cached_metrics.len()); + debug!("Broadcasting {} cached metrics (including host status summary)", cached_metrics.len()); // Create and send message with all cached data let message = MetricMessage::new(self.hostname.clone(), cached_metrics); diff --git a/agent/src/status/mod.rs b/agent/src/status/mod.rs index 6aa5545..b5ed9fd 100644 --- a/agent/src/status/mod.rs +++ b/agent/src/status/mod.rs @@ -128,6 +128,21 @@ impl HostStatusManager { ); } + /// Get the current host status as a metric for broadcasting to dashboard + pub fn get_host_status_metric(&self) -> Metric { + Metric { + name: "host_status_summary".to_string(), + value: cm_dashboard_shared::MetricValue::String(format!( + "Host aggregated from {} services", + self.service_statuses.len() + )), + status: self.current_host_status, + timestamp: Utc::now().timestamp() as u64, + description: Some("Aggregated host status from all services".to_string()), + unit: None, + } + } + /// Calculate the overall host status based on all service statuses fn calculate_host_status(&self) -> Status { if self.service_statuses.is_empty() { diff --git a/dashboard/src/ui/mod.rs b/dashboard/src/ui/mod.rs index 8444fed..0e79e95 100644 --- a/dashboard/src/ui/mod.rs +++ b/dashboard/src/ui/mod.rs @@ -357,23 +357,41 @@ impl TuiApp { return Status::Unknown; } - // Check if any metric is critical - if metrics.iter().any(|m| m.status == Status::Critical) { - return Status::Critical; + // First check if we have the aggregated host status summary from the agent + if let Some(host_summary_metric) = metric_store.get_metric(hostname, "host_status_summary") { + return host_summary_metric.status; } - // Check if any metric is warning - if metrics.iter().any(|m| m.status == Status::Warning) { - return Status::Warning; + // Fallback to old aggregation logic with proper Pending handling + let mut has_critical = false; + let mut has_warning = false; + let mut has_pending = false; + let mut ok_count = 0; + let mut total_count = 0; + + for metric in &metrics { + total_count += 1; + match metric.status { + Status::Critical => has_critical = true, + Status::Warning => has_warning = true, + Status::Pending => has_pending = true, + Status::Ok => ok_count += 1, + Status::Unknown => {} // Ignore unknown for aggregation + } } - // Check if all metrics are ok - if metrics.iter().all(|m| m.status == Status::Ok) { - return Status::Ok; + // Priority order: Critical > Warning > Pending > Ok > Unknown + if has_critical { + Status::Critical + } else if has_warning { + Status::Warning + } else if has_pending { + Status::Pending + } else if ok_count > 0 { + Status::Ok + } else { + Status::Unknown } - - // Default to unknown if mixed statuses - Status::Unknown } fn render_system_panel(&mut self, frame: &mut Frame, area: Rect, metric_store: &MetricStore) { diff --git a/dashboard/src/ui/theme.rs b/dashboard/src/ui/theme.rs index 3658943..671c28f 100644 --- a/dashboard/src/ui/theme.rs +++ b/dashboard/src/ui/theme.rs @@ -143,7 +143,7 @@ impl Theme { pub fn status_color(status: Status) -> Color { match status { Status::Ok => Self::success(), - Status::Pending => Self::info(), // Blue for pending + Status::Pending => Self::highlight(), // Blue for pending Status::Warning => Self::warning(), Status::Critical => Self::error(), Status::Unknown => Self::muted_text(), @@ -258,7 +258,7 @@ impl StatusIcons { let icon = Self::get_icon(status); let status_color = match status { Status::Ok => Theme::success(), // Green - Status::Pending => Theme::info(), // Blue + Status::Pending => Theme::highlight(), // Blue Status::Warning => Theme::warning(), // Yellow Status::Critical => Theme::error(), // Red Status::Unknown => Theme::muted_text(), // Gray diff --git a/dashboard/src/ui/widgets/services.rs b/dashboard/src/ui/widgets/services.rs index a1c6c74..441ba91 100644 --- a/dashboard/src/ui/widgets/services.rs +++ b/dashboard/src/ui/widgets/services.rs @@ -156,7 +156,7 @@ impl ServicesWidget { let status_color = match info.widget_status { Status::Ok => Theme::success(), - Status::Pending => Theme::info(), + Status::Pending => Theme::highlight(), Status::Warning => Theme::warning(), Status::Critical => Theme::error(), Status::Unknown => Theme::muted_text(),