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
173 lines
4.5 KiB
Rust
173 lines
4.5 KiB
Rust
use anyhow::Result;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::Path;
|
|
|
|
/// Main dashboard configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct DashboardConfig {
|
|
pub zmq: ZmqConfig,
|
|
pub ui: UiConfig,
|
|
pub hosts: HostsConfig,
|
|
pub metrics: MetricsConfig,
|
|
pub widgets: WidgetsConfig,
|
|
}
|
|
|
|
/// ZMQ consumer configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ZmqConfig {
|
|
pub subscriber_ports: Vec<u16>,
|
|
pub connection_timeout_ms: u64,
|
|
pub reconnect_interval_ms: u64,
|
|
}
|
|
|
|
/// UI configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct UiConfig {
|
|
pub refresh_rate_ms: u64,
|
|
pub theme: String,
|
|
pub preserve_layout: bool,
|
|
}
|
|
|
|
/// Hosts configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct HostsConfig {
|
|
pub auto_discovery: bool,
|
|
pub predefined_hosts: Vec<String>,
|
|
pub default_host: Option<String>,
|
|
}
|
|
|
|
/// Metrics configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MetricsConfig {
|
|
pub history_retention_hours: u64,
|
|
pub max_metrics_per_host: usize,
|
|
}
|
|
|
|
/// Widget configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct WidgetsConfig {
|
|
pub cpu: WidgetConfig,
|
|
pub memory: WidgetConfig,
|
|
pub storage: WidgetConfig,
|
|
pub services: WidgetConfig,
|
|
pub backup: WidgetConfig,
|
|
}
|
|
|
|
/// Individual widget configuration
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct WidgetConfig {
|
|
pub enabled: bool,
|
|
pub metrics: Vec<String>,
|
|
}
|
|
|
|
impl DashboardConfig {
|
|
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
|
|
let path = path.as_ref();
|
|
let content = std::fs::read_to_string(path)?;
|
|
let config: DashboardConfig = toml::from_str(&content)?;
|
|
Ok(config)
|
|
}
|
|
}
|
|
|
|
impl Default for DashboardConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
zmq: ZmqConfig::default(),
|
|
ui: UiConfig::default(),
|
|
hosts: HostsConfig::default(),
|
|
metrics: MetricsConfig::default(),
|
|
widgets: WidgetsConfig::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for ZmqConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
subscriber_ports: vec![6130],
|
|
connection_timeout_ms: 15000,
|
|
reconnect_interval_ms: 5000,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for UiConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
refresh_rate_ms: 100,
|
|
theme: "default".to_string(),
|
|
preserve_layout: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for HostsConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
auto_discovery: true,
|
|
predefined_hosts: vec![
|
|
"cmbox".to_string(),
|
|
"labbox".to_string(),
|
|
"simonbox".to_string(),
|
|
"steambox".to_string(),
|
|
"srv01".to_string(),
|
|
],
|
|
default_host: Some("cmbox".to_string()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for MetricsConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
history_retention_hours: 24,
|
|
max_metrics_per_host: 10000,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for WidgetsConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
cpu: WidgetConfig {
|
|
enabled: true,
|
|
metrics: vec![
|
|
"cpu_load_1min".to_string(),
|
|
"cpu_load_5min".to_string(),
|
|
"cpu_load_15min".to_string(),
|
|
"cpu_temperature_celsius".to_string(),
|
|
],
|
|
},
|
|
memory: WidgetConfig {
|
|
enabled: true,
|
|
metrics: vec![
|
|
"memory_usage_percent".to_string(),
|
|
"memory_total_gb".to_string(),
|
|
"memory_available_gb".to_string(),
|
|
],
|
|
},
|
|
storage: WidgetConfig {
|
|
enabled: true,
|
|
metrics: vec![
|
|
"disk_nvme0_temperature_celsius".to_string(),
|
|
"disk_nvme0_wear_percent".to_string(),
|
|
"disk_nvme0_usage_percent".to_string(),
|
|
],
|
|
},
|
|
services: WidgetConfig {
|
|
enabled: true,
|
|
metrics: vec![
|
|
"service_ssh_status".to_string(),
|
|
"service_ssh_memory_mb".to_string(),
|
|
],
|
|
},
|
|
backup: WidgetConfig {
|
|
enabled: true,
|
|
metrics: vec![
|
|
"backup_status".to_string(),
|
|
"backup_last_run_timestamp".to_string(),
|
|
],
|
|
},
|
|
}
|
|
}
|
|
} |