use std::collections::HashMap;
use crate::private::Sealed;
pub type GaugeDefault = u64;
pub trait GaugeNumber: Sized + 'static + Sealed {
type Atomic: prometheus::core::Atomic;
}
impl GaugeNumber for i64 {
type Atomic = prometheus::core::AtomicI64;
}
impl GaugeNumber for f64 {
type Atomic = prometheus::core::AtomicF64;
}
impl GaugeNumber for u64 {
type Atomic = prometheus::core::AtomicU64;
}
#[derive(Debug)]
pub struct Gauge<N: GaugeNumber = GaugeDefault> {
inner: prometheus::core::GenericGaugeVec<N::Atomic>,
}
impl<N: GaugeNumber> Clone for Gauge<N> {
fn clone(&self) -> Self {
Self { inner: self.inner.clone() }
}
}
impl<N: GaugeNumber> Gauge<N> {
pub fn new(
registry: &prometheus::Registry,
name: &str,
help: &str,
labels: &[&str],
const_labels: HashMap<String, String>,
) -> Self {
let opts = prometheus::Opts::new(name, help).const_labels(const_labels);
let metric = prometheus::core::GenericGaugeVec::<N::Atomic>::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 inc(&self, labels: &[&str]) {
self.inner.with_label_values(labels).inc();
}
pub fn dec(&self, labels: &[&str]) {
self.inner.with_label_values(labels).dec();
}
pub fn add(&self, labels: &[&str], value: <N::Atomic as prometheus::core::Atomic>::T) {
self.inner.with_label_values(labels).add(value);
}
pub fn sub(&self, labels: &[&str], value: <N::Atomic as prometheus::core::Atomic>::T) {
self.inner.with_label_values(labels).sub(value);
}
pub fn set(&self, labels: &[&str], value: <N::Atomic as prometheus::core::Atomic>::T) {
self.inner.with_label_values(labels).set(value);
}
}