Files
telemt/src/metrics/render/me_hardswap.rs
T
2026-09-25 19:49:36 +03:00

150 lines
5.3 KiB
Rust

use std::fmt::Write;
use crate::transport::middle_proxy::MeApiHardswapSnapshot;
/// Renders fixed-cardinality hardswap and writer-replacement gauges.
pub(super) fn render(out: &mut String, snapshot: Option<&MeApiHardswapSnapshot>, enabled: bool) {
let snapshot = enabled.then_some(snapshot).flatten();
let pending = snapshot.is_some_and(|value| value.pending);
let pending_age_secs = snapshot
.and_then(|value| value.pending_age_secs)
.unwrap_or(0);
let pending_writers_current = snapshot
.map(|value| value.pending_writers_current)
.unwrap_or(0);
let pending_writer_deficit = snapshot
.map(|value| value.pending_writer_deficit)
.unwrap_or(0);
let pending_missing_dc_groups = snapshot
.map(|value| value.pending_missing_dc_groups)
.unwrap_or(0);
let pending_map_current = snapshot
.and_then(|value| value.pending_map_current)
.is_some_and(|value| value);
let orphan_warm_writers_current = snapshot
.map(|value| value.orphan_warm_writers_current)
.unwrap_or(0);
let replacement_preparing_current = snapshot
.map(|value| value.replacement_preparing_current)
.unwrap_or(0);
let replacement_retiring_current = snapshot
.map(|value| value.replacement_retiring_current)
.unwrap_or(0);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending Whether an ME hardswap generation is pending"
);
let _ = writeln!(out, "# TYPE telemt_me_hardswap_pending gauge");
let _ = writeln!(out, "telemt_me_hardswap_pending {}", usize::from(pending));
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending_age_seconds Age of the pending ME hardswap generation"
);
let _ = writeln!(out, "# TYPE telemt_me_hardswap_pending_age_seconds gauge");
let _ = writeln!(
out,
"telemt_me_hardswap_pending_age_seconds {pending_age_secs}"
);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending_writers_current Authoritative warm writers in the pending generation"
);
let _ = writeln!(
out,
"# TYPE telemt_me_hardswap_pending_writers_current gauge"
);
let _ = writeln!(
out,
"telemt_me_hardswap_pending_writers_current {pending_writers_current}"
);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending_writer_deficit Writers missing from the pending generation floor"
);
let _ = writeln!(
out,
"# TYPE telemt_me_hardswap_pending_writer_deficit gauge"
);
let _ = writeln!(
out,
"telemt_me_hardswap_pending_writer_deficit {pending_writer_deficit}"
);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending_missing_dc_groups Desired DC-family groups below the pending-generation floor"
);
let _ = writeln!(
out,
"# TYPE telemt_me_hardswap_pending_missing_dc_groups gauge"
);
let _ = writeln!(
out,
"telemt_me_hardswap_pending_missing_dc_groups {pending_missing_dc_groups}"
);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_pending_map_current Whether the pending generation targets the current endpoint map"
);
let _ = writeln!(out, "# TYPE telemt_me_hardswap_pending_map_current gauge");
let _ = writeln!(
out,
"telemt_me_hardswap_pending_map_current {}",
usize::from(pending_map_current)
);
let _ = writeln!(
out,
"# HELP telemt_me_hardswap_orphan_warm_writers_current Warm writers not owned by the pending hardswap generation"
);
let _ = writeln!(
out,
"# TYPE telemt_me_hardswap_orphan_warm_writers_current gauge"
);
let _ = writeln!(
out,
"telemt_me_hardswap_orphan_warm_writers_current {orphan_warm_writers_current}"
);
let _ = writeln!(
out,
"# HELP telemt_me_writer_replacement_current ME writer replacements by transaction phase"
);
let _ = writeln!(out, "# TYPE telemt_me_writer_replacement_current gauge");
let _ = writeln!(
out,
"telemt_me_writer_replacement_current{{state=\"preparing\"}} {replacement_preparing_current}"
);
let _ = writeln!(
out,
"telemt_me_writer_replacement_current{{state=\"retiring\"}} {replacement_retiring_current}"
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn renders_bounded_hardswap_and_replacement_state() {
let snapshot = MeApiHardswapSnapshot {
pending: true,
pending_age_secs: Some(42),
pending_writers_current: 3,
pending_writer_deficit: 4,
pending_missing_dc_groups: 2,
pending_map_current: Some(true),
orphan_warm_writers_current: 1,
replacement_preparing_current: 5,
replacement_retiring_current: 6,
};
let mut out = String::new();
render(&mut out, Some(&snapshot), true);
assert!(out.contains("telemt_me_hardswap_pending 1"));
assert!(out.contains("telemt_me_hardswap_pending_age_seconds 42"));
assert!(out.contains("telemt_me_hardswap_pending_writer_deficit 4"));
assert!(out.contains("telemt_me_writer_replacement_current{state=\"preparing\"} 5"));
assert!(out.contains("telemt_me_writer_replacement_current{state=\"retiring\"} 6"));
}
}