Add agent hash display to system panel
Implement agent version tracking to diagnose deployment issues: - Add get_agent_hash() method to extract Nix store hash from executable path - Collect system_agent_hash metric in NixOS collector - Display "Agent Hash" in system panel under NixOS section - Update metric filtering to include agent hash This helps identify which version of the agent is actually running when troubleshooting deployment or metric collection issues.
This commit is contained in:
parent
4193a97737
commit
c5ec529210
@ -46,6 +46,23 @@ impl NixOSCollector {
|
|||||||
Ok(clean_version)
|
Ok(clean_version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get agent hash from binary path
|
||||||
|
fn get_agent_hash(&self) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
|
// Get the path of the current executable
|
||||||
|
let exe_path = std::env::current_exe()?;
|
||||||
|
let exe_str = exe_path.to_string_lossy();
|
||||||
|
|
||||||
|
// Extract Nix store hash from path like /nix/store/fn804fh332mp8gz06qawminpj20xl25h-cm-dashboard-0.1.0/bin/cm-dashboard-agent
|
||||||
|
if let Some(store_path) = exe_str.strip_prefix("/nix/store/") {
|
||||||
|
if let Some(dash_pos) = store_path.find('-') {
|
||||||
|
return Ok(store_path[..dash_pos].to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to "unknown" if not in Nix store
|
||||||
|
Ok("unknown".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get currently active users
|
/// Get currently active users
|
||||||
fn get_active_users(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
fn get_active_users(&self) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
||||||
let output = Command::new("who").output()?;
|
let output = Command::new("who").output()?;
|
||||||
@ -131,6 +148,31 @@ impl Collector for NixOSCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect agent hash
|
||||||
|
match self.get_agent_hash() {
|
||||||
|
Ok(hash) => {
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "system_agent_hash".to_string(),
|
||||||
|
value: MetricValue::String(hash),
|
||||||
|
unit: None,
|
||||||
|
description: Some("Agent Nix store hash".to_string()),
|
||||||
|
status: Status::Ok,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
debug!("Failed to get agent hash: {}", e);
|
||||||
|
metrics.push(Metric {
|
||||||
|
name: "system_agent_hash".to_string(),
|
||||||
|
value: MetricValue::String("unknown".to_string()),
|
||||||
|
unit: None,
|
||||||
|
description: Some("Agent hash (failed to detect)".to_string()),
|
||||||
|
status: Status::Unknown,
|
||||||
|
timestamp,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
debug!("Collected {} NixOS metrics", metrics.len());
|
debug!("Collected {} NixOS metrics", metrics.len());
|
||||||
Ok(metrics)
|
Ok(metrics)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,7 +119,7 @@ impl TuiApp {
|
|||||||
// Add NixOS metrics - using exact matching for build display fix
|
// Add NixOS metrics - using exact matching for build display fix
|
||||||
let nixos_metrics: Vec<&Metric> = all_metrics
|
let nixos_metrics: Vec<&Metric> = all_metrics
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|m| m.name == "system_nixos_build" || m.name == "system_active_users")
|
.filter(|m| m.name == "system_nixos_build" || m.name == "system_active_users" || m.name == "system_agent_hash")
|
||||||
.copied()
|
.copied()
|
||||||
.collect();
|
.collect();
|
||||||
system_metrics.extend(nixos_metrics);
|
system_metrics.extend(nixos_metrics);
|
||||||
|
|||||||
@ -16,6 +16,7 @@ pub struct SystemWidget {
|
|||||||
// NixOS information
|
// NixOS information
|
||||||
nixos_build: Option<String>,
|
nixos_build: Option<String>,
|
||||||
active_users: Option<String>,
|
active_users: Option<String>,
|
||||||
|
agent_hash: Option<String>,
|
||||||
|
|
||||||
// CPU metrics
|
// CPU metrics
|
||||||
cpu_load_1min: Option<f32>,
|
cpu_load_1min: Option<f32>,
|
||||||
@ -64,6 +65,7 @@ impl SystemWidget {
|
|||||||
Self {
|
Self {
|
||||||
nixos_build: None,
|
nixos_build: None,
|
||||||
active_users: None,
|
active_users: None,
|
||||||
|
agent_hash: None,
|
||||||
cpu_load_1min: None,
|
cpu_load_1min: None,
|
||||||
cpu_load_5min: None,
|
cpu_load_5min: None,
|
||||||
cpu_load_15min: None,
|
cpu_load_15min: None,
|
||||||
@ -313,6 +315,11 @@ impl Widget for SystemWidget {
|
|||||||
self.active_users = Some(users.clone());
|
self.active_users = Some(users.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"system_agent_hash" => {
|
||||||
|
if let MetricValue::String(hash) = &metric.value {
|
||||||
|
self.agent_hash = Some(hash.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CPU metrics
|
// CPU metrics
|
||||||
"cpu_load_1min" => {
|
"cpu_load_1min" => {
|
||||||
@ -397,6 +404,11 @@ impl Widget for SystemWidget {
|
|||||||
Span::styled(format!("Active users: {}", users_text), Typography::secondary())
|
Span::styled(format!("Active users: {}", users_text), Typography::secondary())
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
let agent_hash_text = self.agent_hash.as_deref().unwrap_or("unknown");
|
||||||
|
lines.push(Line::from(vec![
|
||||||
|
Span::styled(format!("Agent Hash: {}", agent_hash_text), Typography::secondary())
|
||||||
|
]));
|
||||||
|
|
||||||
// CPU section
|
// CPU section
|
||||||
lines.push(Line::from(vec![
|
lines.push(Line::from(vec![
|
||||||
Span::styled("CPU:", Typography::widget_title())
|
Span::styled("CPU:", Typography::widget_title())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user