Implement real-time process monitoring and fix UI hardcoded data
This commit addresses several key issues identified during development: Major Changes: - Replace hardcoded top CPU/RAM process display with real system data - Add intelligent process monitoring to CpuCollector using ps command - Fix disk metrics permission issues in systemd collector - Optimize service collection to focus on status, memory, and disk only - Update dashboard widgets to display live process information Process Monitoring Implementation: - Added collect_top_cpu_process() and collect_top_ram_process() methods - Implemented ps-based monitoring with accurate CPU percentages - Added filtering to prevent self-monitoring artifacts (ps commands) - Enhanced error handling and validation for process data - Dashboard now shows realistic values like "claude (PID 2974) 11.0%" Service Collection Optimization: - Removed CPU monitoring from systemd collector for efficiency - Enhanced service directory permission error logging - Simplified services widget to show essential metrics only - Fixed service-to-directory mapping accuracy UI and Dashboard Improvements: - Reorganized dashboard layout with btop-inspired multi-panel design - Updated system panel to include real top CPU/RAM process display - Enhanced widget formatting and data presentation - Removed placeholder/hardcoded data throughout the interface Technical Details: - Updated agent/src/collectors/cpu.rs with process monitoring - Modified dashboard/src/ui/mod.rs for real-time process display - Enhanced systemd collector error handling and disk metrics - Updated CLAUDE.md documentation with implementation details
This commit is contained in:
142
dashboard/src/metrics/mod.rs
Normal file
142
dashboard/src/metrics/mod.rs
Normal file
@@ -0,0 +1,142 @@
|
||||
use cm_dashboard_shared::{Metric, Status};
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Duration, Instant};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub mod store;
|
||||
pub mod subscription;
|
||||
|
||||
pub use store::MetricStore;
|
||||
pub use subscription::SubscriptionManager;
|
||||
|
||||
/// Widget types that can subscribe to metrics
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
pub enum WidgetType {
|
||||
Cpu,
|
||||
Memory,
|
||||
Storage,
|
||||
Services,
|
||||
Backup,
|
||||
Hosts,
|
||||
Alerts,
|
||||
}
|
||||
|
||||
/// Metric subscription entry
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MetricSubscription {
|
||||
pub widget_type: WidgetType,
|
||||
pub metric_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Historical metric data point
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MetricDataPoint {
|
||||
pub metric: Metric,
|
||||
pub received_at: Instant,
|
||||
}
|
||||
|
||||
/// Metric filtering and selection utilities
|
||||
pub mod filter {
|
||||
use super::*;
|
||||
|
||||
/// Filter metrics by widget type subscription
|
||||
pub fn filter_metrics_for_widget<'a>(
|
||||
metrics: &'a [Metric],
|
||||
subscriptions: &[String],
|
||||
) -> Vec<&'a Metric> {
|
||||
metrics
|
||||
.iter()
|
||||
.filter(|metric| subscriptions.contains(&metric.name))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get metrics by pattern matching
|
||||
pub fn filter_metrics_by_pattern<'a>(
|
||||
metrics: &'a [Metric],
|
||||
pattern: &str,
|
||||
) -> Vec<&'a Metric> {
|
||||
if pattern.is_empty() {
|
||||
return metrics.iter().collect();
|
||||
}
|
||||
|
||||
metrics
|
||||
.iter()
|
||||
.filter(|metric| metric.name.contains(pattern))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Aggregate status from multiple metrics
|
||||
pub fn aggregate_widget_status(metrics: &[&Metric]) -> Status {
|
||||
if metrics.is_empty() {
|
||||
return Status::Unknown;
|
||||
}
|
||||
|
||||
let statuses: Vec<Status> = metrics.iter().map(|m| m.status).collect();
|
||||
Status::aggregate(&statuses)
|
||||
}
|
||||
}
|
||||
|
||||
/// Widget metric subscription definitions
|
||||
pub mod subscriptions {
|
||||
/// CPU widget metric subscriptions
|
||||
pub const CPU_WIDGET_METRICS: &[&str] = &[
|
||||
"cpu_load_1min",
|
||||
"cpu_load_5min",
|
||||
"cpu_load_15min",
|
||||
"cpu_temperature_celsius",
|
||||
"cpu_frequency_mhz",
|
||||
];
|
||||
|
||||
/// Memory widget metric subscriptions
|
||||
pub const MEMORY_WIDGET_METRICS: &[&str] = &[
|
||||
"memory_usage_percent",
|
||||
"memory_total_gb",
|
||||
"memory_used_gb",
|
||||
"memory_available_gb",
|
||||
"memory_swap_total_gb",
|
||||
"memory_swap_used_gb",
|
||||
"disk_tmp_size_mb",
|
||||
"disk_tmp_total_mb",
|
||||
"disk_tmp_usage_percent",
|
||||
];
|
||||
|
||||
/// Storage widget metric subscriptions
|
||||
pub const STORAGE_WIDGET_METRICS: &[&str] = &[
|
||||
"disk_nvme0_temperature_celsius",
|
||||
"disk_nvme0_wear_percent",
|
||||
"disk_nvme0_spare_percent",
|
||||
"disk_nvme0_hours",
|
||||
"disk_nvme0_capacity_gb",
|
||||
"disk_nvme0_usage_gb",
|
||||
"disk_nvme0_usage_percent",
|
||||
];
|
||||
|
||||
/// Services widget metric subscriptions
|
||||
/// Note: Individual service metrics are dynamically discovered
|
||||
/// Pattern: "service_{name}_status" and "service_{name}_memory_mb"
|
||||
pub const SERVICES_WIDGET_METRICS: &[&str] = &[
|
||||
// Individual service metrics will be matched by pattern in the widget
|
||||
// e.g., "service_sshd_status", "service_nginx_status", etc.
|
||||
];
|
||||
|
||||
/// Backup widget metric subscriptions
|
||||
pub const BACKUP_WIDGET_METRICS: &[&str] = &[
|
||||
"backup_status",
|
||||
"backup_last_run_timestamp",
|
||||
"backup_size_gb",
|
||||
"backup_duration_minutes",
|
||||
];
|
||||
|
||||
/// Get all metric subscriptions for a widget type
|
||||
pub fn get_widget_subscriptions(widget_type: super::WidgetType) -> &'static [&'static str] {
|
||||
match widget_type {
|
||||
super::WidgetType::Cpu => CPU_WIDGET_METRICS,
|
||||
super::WidgetType::Memory => MEMORY_WIDGET_METRICS,
|
||||
super::WidgetType::Storage => STORAGE_WIDGET_METRICS,
|
||||
super::WidgetType::Services => SERVICES_WIDGET_METRICS,
|
||||
super::WidgetType::Backup => BACKUP_WIDGET_METRICS,
|
||||
super::WidgetType::Hosts => &[], // Hosts widget doesn't subscribe to specific metrics
|
||||
super::WidgetType::Alerts => &[], // Alerts widget aggregates from all metrics
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user