From 54483653f95aa91ee429977c599928103fb79872 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Sun, 23 Nov 2025 17:40:12 +0100 Subject: [PATCH] Fix mergerfs drive metric parsing for proper pool consolidation - Update extract_pool_name to handle data_/parity_ drive metrics correctly - Fix extract_drive_name to parse mergerfs drive roles properly - Prevent srv_media_data from being parsed as separate pool --- Cargo.lock | 6 +++--- agent/Cargo.toml | 2 +- dashboard/Cargo.toml | 2 +- dashboard/src/ui/widgets/system.rs | 27 +++++++++++++++++++++++++-- shared/Cargo.toml | 2 +- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9f7112..c2f5ebd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cm-dashboard" -version = "0.1.121" +version = "0.1.122" dependencies = [ "anyhow", "chrono", @@ -301,7 +301,7 @@ dependencies = [ [[package]] name = "cm-dashboard-agent" -version = "0.1.121" +version = "0.1.122" dependencies = [ "anyhow", "async-trait", @@ -324,7 +324,7 @@ dependencies = [ [[package]] name = "cm-dashboard-shared" -version = "0.1.121" +version = "0.1.122" dependencies = [ "chrono", "serde", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index f731776..8b9f017 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-agent" -version = "0.1.121" +version = "0.1.122" edition = "2021" [dependencies] diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index e10bc3f..5a21c90 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard" -version = "0.1.121" +version = "0.1.122" edition = "2021" [dependencies] diff --git a/dashboard/src/ui/widgets/system.rs b/dashboard/src/ui/widgets/system.rs index 38dd3d1..e3858a2 100644 --- a/dashboard/src/ui/widgets/system.rs +++ b/dashboard/src/ui/widgets/system.rs @@ -369,8 +369,22 @@ impl SystemWidget { else if let Some(suffix_pos) = metric_name.rfind("_temperature") .or_else(|| metric_name.rfind("_wear_percent")) .or_else(|| metric_name.rfind("_health")) { - // Find the second-to-last underscore to get pool name + // For mergerfs pools, metrics look like: disk_srv_media_data_0_temperature or disk_srv_media_parity_0_temperature + // We need to extract just "srv_media" as the pool name let before_suffix = &metric_name[..suffix_pos]; + + // Check if this looks like a mergerfs drive metric (contains data_ or parity_) + if before_suffix.contains("_data_") { + if let Some(data_pos) = before_suffix.find("_data_") { + return Some(metric_name[5..data_pos].to_string()); // Extract pool name before "_data_" + } + } else if before_suffix.contains("_parity_") { + if let Some(parity_pos) = before_suffix.find("_parity_") { + return Some(metric_name[5..parity_pos].to_string()); // Extract pool name before "_parity_" + } + } + + // Fallback for physical drive metrics: find the second-to-last underscore if let Some(drive_start) = before_suffix.rfind('_') { if drive_start > 5 { return Some(metric_name[5..drive_start].to_string()); // Skip "disk_" @@ -415,13 +429,22 @@ impl SystemWidget { /// Extract drive name from disk metric name fn extract_drive_name(&self, metric_name: &str) -> Option { // Pattern: disk_{pool_name}_{drive_name}_{metric_type} + // For mergerfs: disk_{pool_name}_{data|parity}_{index}_{metric_type} // Since pool_name can contain underscores, work backwards from known metric suffixes if metric_name.starts_with("disk_") { if let Some(suffix_pos) = metric_name.rfind("_temperature") .or_else(|| metric_name.rfind("_wear_percent")) .or_else(|| metric_name.rfind("_health")) { - // Find the second-to-last underscore to get the drive name let before_suffix = &metric_name[..suffix_pos]; + + // For mergerfs drive metrics: extract the role_index part (e.g., "data_0", "parity_1") + if before_suffix.contains("_data_") || before_suffix.contains("_parity_") { + if let Some(role_start) = before_suffix.rfind("_data_").or_else(|| before_suffix.rfind("_parity_")) { + return Some(before_suffix[role_start + 1..].to_string()); // e.g., "data_0" or "parity_1" + } + } + + // Fallback for physical drive metrics: get the last component if let Some(drive_start) = before_suffix.rfind('_') { return Some(before_suffix[drive_start + 1..].to_string()); } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 660837b..d90ab7b 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cm-dashboard-shared" -version = "0.1.121" +version = "0.1.122" edition = "2021" [dependencies]