use std::sync::OnceLock;
use prometheus::{HistogramVec, register_histogram_vec};
fn append_duration() -> &'static HistogramVec {
static V: OnceLock<HistogramVec> = OnceLock::new();
V.get_or_init(|| {
register_histogram_vec!(
"polychrome_eventlog_append_duration_seconds",
"Event-log append latency (one journal write), by outcome.",
&["outcome"]
)
.expect("register polychrome_eventlog_append_duration_seconds")
})
}
pub(crate) fn record_append(ok: bool, elapsed: std::time::Duration) {
append_duration()
.with_label_values(&[if ok { "ok" } else { "error" }])
.observe(elapsed.as_secs_f64());
}
pub(crate) fn force() {
for outcome in ["ok", "error"] {
append_duration().with_label_values(&[outcome]);
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::pedantic, clippy::nursery, missing_docs)]
use std::time::Duration;
use prometheus::{Encoder as _, TextEncoder};
use super::record_append;
#[test]
fn record_append_is_visible_in_a_registry_scrape() {
record_append(true, Duration::from_millis(5));
let mut buf = Vec::new();
TextEncoder::new()
.encode(&prometheus::default_registry().gather(), &mut buf)
.expect("encode");
let text = String::from_utf8(buf).expect("utf8");
assert!(
text.contains("polychrome_eventlog_append_duration_seconds_bucket"),
"missing histogram buckets in scrape:\n{text}"
);
}
}