mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-27 15:37:02 +00:00
fix(obs): drop placeholder drive series (#4440)
Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
@@ -44,38 +44,38 @@ pub struct DriveDetailedStats {
|
|||||||
pub capacity_observation_state: &'static str,
|
pub capacity_observation_state: &'static str,
|
||||||
/// Age in seconds of the current capacity observation
|
/// Age in seconds of the current capacity observation
|
||||||
pub capacity_observation_age_seconds: u64,
|
pub capacity_observation_age_seconds: u64,
|
||||||
/// Used inodes
|
/// Used inodes when the platform provides a real inode sample
|
||||||
pub used_inodes: u64,
|
pub used_inodes: Option<u64>,
|
||||||
/// Free inodes
|
/// Free inodes when the platform provides a real inode sample
|
||||||
pub free_inodes: u64,
|
pub free_inodes: Option<u64>,
|
||||||
/// Total inodes
|
/// Total inodes when the platform provides a real inode sample
|
||||||
pub total_inodes: u64,
|
pub total_inodes: Option<u64>,
|
||||||
/// Total timeout errors
|
/// Total timeout errors when backed by a real error counter
|
||||||
pub timeout_errors_total: u64,
|
pub timeout_errors_total: Option<u64>,
|
||||||
/// Total I/O errors
|
/// Total I/O errors when backed by a real error counter
|
||||||
pub io_errors_total: u64,
|
pub io_errors_total: Option<u64>,
|
||||||
/// Total availability errors
|
/// Total availability errors when backed by a real error counter
|
||||||
pub availability_errors_total: u64,
|
pub availability_errors_total: Option<u64>,
|
||||||
/// Number of I/O operations waiting
|
/// Number of I/O operations waiting when backed by a real queue sample
|
||||||
pub waiting_io: u64,
|
pub waiting_io: Option<u64>,
|
||||||
/// API latency in microseconds
|
/// API latency in microseconds when backed by a real latency sample
|
||||||
pub api_latency_micros: u64,
|
pub api_latency_micros: Option<u64>,
|
||||||
/// Health status (1=healthy, 0=unhealthy)
|
/// Health status (1=healthy, 0=unhealthy)
|
||||||
pub health: u8,
|
pub health: u8,
|
||||||
/// Reads per second
|
/// Reads per second when backed by a real iostat sample
|
||||||
pub reads_per_sec: f64,
|
pub reads_per_sec: Option<f64>,
|
||||||
/// Kilobytes read per second
|
/// Kilobytes read per second when backed by a real iostat sample
|
||||||
pub reads_kb_per_sec: f64,
|
pub reads_kb_per_sec: Option<f64>,
|
||||||
/// Average read await time
|
/// Average read await time when backed by a real iostat sample
|
||||||
pub reads_await: f64,
|
pub reads_await: Option<f64>,
|
||||||
/// Writes per second
|
/// Writes per second when backed by a real iostat sample
|
||||||
pub writes_per_sec: f64,
|
pub writes_per_sec: Option<f64>,
|
||||||
/// Kilobytes written per second
|
/// Kilobytes written per second when backed by a real iostat sample
|
||||||
pub writes_kb_per_sec: f64,
|
pub writes_kb_per_sec: Option<f64>,
|
||||||
/// Average write await time
|
/// Average write await time when backed by a real iostat sample
|
||||||
pub writes_await: f64,
|
pub writes_await: Option<f64>,
|
||||||
/// Percentage utilization
|
/// Drive percent utilization when backed by a real iostat sample
|
||||||
pub perc_util: f64,
|
pub perc_util: Option<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aggregate drive count statistics.
|
/// Aggregate drive count statistics.
|
||||||
@@ -134,46 +134,52 @@ pub fn collect_drive_detailed_metrics(stats: &[DriveDetailedStats]) -> Vec<Prome
|
|||||||
.with_label_owned("state", state.to_string()),
|
.with_label_owned("state", state.to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
push_drive_metric(&mut metrics, &DRIVE_USED_INODES_MD, stat.used_inodes as f64, server_label, drive_label);
|
if let Some(value) = stat.used_inodes {
|
||||||
push_drive_metric(&mut metrics, &DRIVE_FREE_INODES_MD, stat.free_inodes as f64, server_label, drive_label);
|
push_drive_metric(&mut metrics, &DRIVE_USED_INODES_MD, value as f64, server_label, drive_label);
|
||||||
push_drive_metric(&mut metrics, &DRIVE_TOTAL_INODES_MD, stat.total_inodes as f64, server_label, drive_label);
|
}
|
||||||
push_drive_metric(
|
if let Some(value) = stat.free_inodes {
|
||||||
&mut metrics,
|
push_drive_metric(&mut metrics, &DRIVE_FREE_INODES_MD, value as f64, server_label, drive_label);
|
||||||
&DRIVE_TIMEOUT_ERRORS_MD,
|
}
|
||||||
stat.timeout_errors_total as f64,
|
if let Some(value) = stat.total_inodes {
|
||||||
server_label,
|
push_drive_metric(&mut metrics, &DRIVE_TOTAL_INODES_MD, value as f64, server_label, drive_label);
|
||||||
drive_label,
|
}
|
||||||
);
|
if let Some(value) = stat.timeout_errors_total {
|
||||||
push_drive_metric(&mut metrics, &DRIVE_IO_ERRORS_MD, stat.io_errors_total as f64, server_label, drive_label);
|
push_drive_metric(&mut metrics, &DRIVE_TIMEOUT_ERRORS_MD, value as f64, server_label, drive_label);
|
||||||
push_drive_metric(
|
}
|
||||||
&mut metrics,
|
if let Some(value) = stat.io_errors_total {
|
||||||
&DRIVE_AVAILABILITY_ERRORS_MD,
|
push_drive_metric(&mut metrics, &DRIVE_IO_ERRORS_MD, value as f64, server_label, drive_label);
|
||||||
stat.availability_errors_total as f64,
|
}
|
||||||
server_label,
|
if let Some(value) = stat.availability_errors_total {
|
||||||
drive_label,
|
push_drive_metric(&mut metrics, &DRIVE_AVAILABILITY_ERRORS_MD, value as f64, server_label, drive_label);
|
||||||
);
|
}
|
||||||
push_drive_metric(&mut metrics, &DRIVE_WAITING_IO_MD, stat.waiting_io as f64, server_label, drive_label);
|
if let Some(value) = stat.waiting_io {
|
||||||
push_drive_metric(
|
push_drive_metric(&mut metrics, &DRIVE_WAITING_IO_MD, value as f64, server_label, drive_label);
|
||||||
&mut metrics,
|
}
|
||||||
&DRIVE_API_LATENCY_MD,
|
if let Some(value) = stat.api_latency_micros {
|
||||||
stat.api_latency_micros as f64,
|
push_drive_metric(&mut metrics, &DRIVE_API_LATENCY_MD, value as f64, server_label, drive_label);
|
||||||
server_label,
|
}
|
||||||
drive_label,
|
|
||||||
);
|
|
||||||
push_drive_metric(&mut metrics, &DRIVE_HEALTH_MD, stat.health as f64, server_label, drive_label);
|
push_drive_metric(&mut metrics, &DRIVE_HEALTH_MD, stat.health as f64, server_label, drive_label);
|
||||||
push_drive_metric(&mut metrics, &DRIVE_READS_PER_SEC_MD, stat.reads_per_sec, server_label, drive_label);
|
if let Some(value) = stat.reads_per_sec {
|
||||||
push_drive_metric(&mut metrics, &DRIVE_READS_KB_PER_SEC_MD, stat.reads_kb_per_sec, server_label, drive_label);
|
push_drive_metric(&mut metrics, &DRIVE_READS_PER_SEC_MD, value, server_label, drive_label);
|
||||||
push_drive_metric(&mut metrics, &DRIVE_READS_AWAIT_MD, stat.reads_await, server_label, drive_label);
|
}
|
||||||
push_drive_metric(&mut metrics, &DRIVE_WRITES_PER_SEC_MD, stat.writes_per_sec, server_label, drive_label);
|
if let Some(value) = stat.reads_kb_per_sec {
|
||||||
push_drive_metric(
|
push_drive_metric(&mut metrics, &DRIVE_READS_KB_PER_SEC_MD, value, server_label, drive_label);
|
||||||
&mut metrics,
|
}
|
||||||
&DRIVE_WRITES_KB_PER_SEC_MD,
|
if let Some(value) = stat.reads_await {
|
||||||
stat.writes_kb_per_sec,
|
push_drive_metric(&mut metrics, &DRIVE_READS_AWAIT_MD, value, server_label, drive_label);
|
||||||
server_label,
|
}
|
||||||
drive_label,
|
if let Some(value) = stat.writes_per_sec {
|
||||||
);
|
push_drive_metric(&mut metrics, &DRIVE_WRITES_PER_SEC_MD, value, server_label, drive_label);
|
||||||
push_drive_metric(&mut metrics, &DRIVE_WRITES_AWAIT_MD, stat.writes_await, server_label, drive_label);
|
}
|
||||||
push_drive_metric(&mut metrics, &DRIVE_PERC_UTIL_MD, stat.perc_util, server_label, drive_label);
|
if let Some(value) = stat.writes_kb_per_sec {
|
||||||
|
push_drive_metric(&mut metrics, &DRIVE_WRITES_KB_PER_SEC_MD, value, server_label, drive_label);
|
||||||
|
}
|
||||||
|
if let Some(value) = stat.writes_await {
|
||||||
|
push_drive_metric(&mut metrics, &DRIVE_WRITES_AWAIT_MD, value, server_label, drive_label);
|
||||||
|
}
|
||||||
|
if let Some(value) = stat.perc_util {
|
||||||
|
push_drive_metric(&mut metrics, &DRIVE_PERC_UTIL_MD, value, server_label, drive_label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics
|
metrics
|
||||||
@@ -243,22 +249,22 @@ mod tests {
|
|||||||
free_bytes: 1024 * 1024 * 1024 * 50, // 50 GB
|
free_bytes: 1024 * 1024 * 1024 * 50, // 50 GB
|
||||||
capacity_observation_state: "live",
|
capacity_observation_state: "live",
|
||||||
capacity_observation_age_seconds: 0,
|
capacity_observation_age_seconds: 0,
|
||||||
used_inodes: 100000,
|
used_inodes: Some(100000),
|
||||||
free_inodes: 900000,
|
free_inodes: Some(900000),
|
||||||
total_inodes: 1000000,
|
total_inodes: Some(1000000),
|
||||||
timeout_errors_total: 5,
|
timeout_errors_total: Some(5),
|
||||||
io_errors_total: 10,
|
io_errors_total: Some(10),
|
||||||
availability_errors_total: 2,
|
availability_errors_total: Some(2),
|
||||||
waiting_io: 3,
|
waiting_io: Some(3),
|
||||||
api_latency_micros: 1500,
|
api_latency_micros: Some(1500),
|
||||||
health: 1,
|
health: 1,
|
||||||
reads_per_sec: 100.0,
|
reads_per_sec: Some(100.0),
|
||||||
reads_kb_per_sec: 1024.0,
|
reads_kb_per_sec: Some(1024.0),
|
||||||
reads_await: 5.5,
|
reads_await: Some(5.5),
|
||||||
writes_per_sec: 50.0,
|
writes_per_sec: Some(50.0),
|
||||||
writes_kb_per_sec: 512.0,
|
writes_kb_per_sec: Some(512.0),
|
||||||
writes_await: 10.2,
|
writes_await: Some(10.2),
|
||||||
perc_util: 75.5,
|
perc_util: Some(75.5),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let metrics = collect_drive_detailed_metrics(&stats);
|
let metrics = collect_drive_detailed_metrics(&stats);
|
||||||
@@ -273,6 +279,54 @@ mod tests {
|
|||||||
assert_eq!(total_bytes.map(|m| m.value), Some(1024.0 * 1024.0 * 1024.0 * 100.0));
|
assert_eq!(total_bytes.map(|m| m.value), Some(1024.0 * 1024.0 * 1024.0 * 100.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_collect_drive_detailed_metrics_skips_unimplemented_placeholders() {
|
||||||
|
let stats = vec![DriveDetailedStats {
|
||||||
|
server: "node1:9000".to_string(),
|
||||||
|
drive: "/data/disk1".to_string(),
|
||||||
|
total_bytes: 1024,
|
||||||
|
used_bytes: 512,
|
||||||
|
free_bytes: 512,
|
||||||
|
capacity_observation_state: "live",
|
||||||
|
capacity_observation_age_seconds: 0,
|
||||||
|
used_inodes: None,
|
||||||
|
free_inodes: None,
|
||||||
|
total_inodes: None,
|
||||||
|
timeout_errors_total: None,
|
||||||
|
io_errors_total: None,
|
||||||
|
availability_errors_total: None,
|
||||||
|
waiting_io: None,
|
||||||
|
api_latency_micros: None,
|
||||||
|
health: 1,
|
||||||
|
reads_per_sec: None,
|
||||||
|
reads_kb_per_sec: None,
|
||||||
|
reads_await: None,
|
||||||
|
writes_per_sec: None,
|
||||||
|
writes_kb_per_sec: None,
|
||||||
|
writes_await: None,
|
||||||
|
perc_util: None,
|
||||||
|
}];
|
||||||
|
|
||||||
|
let metrics = collect_drive_detailed_metrics(&stats);
|
||||||
|
|
||||||
|
assert_eq!(metrics.len(), 8);
|
||||||
|
assert!(
|
||||||
|
metrics
|
||||||
|
.iter()
|
||||||
|
.all(|metric| metric.name != DRIVE_PERC_UTIL_MD.get_full_metric_name())
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
metrics
|
||||||
|
.iter()
|
||||||
|
.all(|metric| metric.name != DRIVE_USED_INODES_MD.get_full_metric_name())
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
metrics
|
||||||
|
.iter()
|
||||||
|
.all(|metric| metric.name != DRIVE_IO_ERRORS_MD.get_full_metric_name())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_collect_drive_count_metrics() {
|
fn test_collect_drive_count_metrics() {
|
||||||
let stats = DriveCountStats {
|
let stats = DriveCountStats {
|
||||||
|
|||||||
@@ -609,26 +609,22 @@ pub async fn collect_disk_and_system_drive_stats() -> (Vec<DiskStats>, Vec<Drive
|
|||||||
free_bytes: disk.available_space,
|
free_bytes: disk.available_space,
|
||||||
capacity_observation_state,
|
capacity_observation_state,
|
||||||
capacity_observation_age_seconds,
|
capacity_observation_age_seconds,
|
||||||
used_inodes: 0,
|
used_inodes: None,
|
||||||
free_inodes: 0,
|
free_inodes: None,
|
||||||
total_inodes: 0,
|
total_inodes: None,
|
||||||
timeout_errors_total: 0,
|
timeout_errors_total: None,
|
||||||
io_errors_total: 0,
|
io_errors_total: None,
|
||||||
availability_errors_total: 0,
|
availability_errors_total: None,
|
||||||
waiting_io: 0,
|
waiting_io: None,
|
||||||
api_latency_micros: 0,
|
api_latency_micros: None,
|
||||||
health: if is_online { 1 } else { 0 },
|
health: if is_online { 1 } else { 0 },
|
||||||
reads_per_sec: 0.0,
|
reads_per_sec: None,
|
||||||
reads_kb_per_sec: 0.0,
|
reads_kb_per_sec: None,
|
||||||
reads_await: 0.0,
|
reads_await: None,
|
||||||
writes_per_sec: 0.0,
|
writes_per_sec: None,
|
||||||
writes_kb_per_sec: 0.0,
|
writes_kb_per_sec: None,
|
||||||
writes_await: 0.0,
|
writes_await: None,
|
||||||
perc_util: if disk.total_space > 0 {
|
perc_util: None,
|
||||||
(disk.used_space as f64 / disk.total_space as f64) * 100.0
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
Reference in New Issue
Block a user