use std::collections::HashMap;
#[derive(Debug)]
pub struct Histogram {
inner: prometheus::HistogramVec,
}
impl Clone for Histogram {
fn clone(&self) -> Self {
Self { inner: self.inner.clone() }
}
}
impl Histogram {
pub fn new(
registry: &prometheus::Registry,
name: &str,
help: &str,
labels: &[&str],
const_labels: HashMap<String, String>,
buckets: Option<Vec<f64>>,
) -> Self {
let buckets = buckets.unwrap_or(prometheus::DEFAULT_BUCKETS.to_vec());
let opts =
prometheus::HistogramOpts::new(name, help).const_labels(const_labels).buckets(buckets);
let metric = prometheus::HistogramVec::new(opts, labels).unwrap();
let boxed = Box::new(metric.clone());
if let Err(e) = registry.register(boxed.clone()) {
let id = format!("{}, Labels: {}", name, labels.join(", "),);
if matches!(e, prometheus::Error::AlreadyReg) {
registry
.unregister(boxed.clone())
.unwrap_or_else(|_| panic!("Failed to unregister metric {id}"));
registry
.register(boxed)
.unwrap_or_else(|_| panic!("Failed to overwrite metric {id}"));
} else {
panic!("Failed to register metric {id}");
}
}
Self { inner: metric }
}
pub fn observe(&self, labels: &[&str], value: f64) {
self.inner.with_label_values(labels).observe(value);
}
}