use crate::guards::DeferredAddWithLabels;
use prometheus::{register_int_counter_vec, register_int_gauge_vec, IntCounterVec, IntGaugeVec};
use std::marker::PhantomData;
pub type LabelValues<'a> = Vec<&'a str>;
pub trait Labels {
fn label_names() -> Vec<&'static str>;
fn possible_label_values() -> Vec<LabelValues<'static>>;
fn label_values(&self) -> LabelValues;
}
pub struct IntCounterWithLabels<L: Labels> {
metric: IntCounterVec,
_labels: PhantomData<L>,
}
impl<L: Labels> IntCounterWithLabels<L> {
pub fn register_new(name: &str, help: &str) -> IntCounterWithLabels<L> {
let metric = register_int_counter_vec!(name, help, &L::label_names()).unwrap();
for vals in L::possible_label_values() {
metric.with_label_values(&vals).inc_by(0);
}
Self {
metric,
_labels: PhantomData,
}
}
pub fn inc(&self, labels: &L) {
self.metric.with_label_values(&labels.label_values()).inc();
}
pub fn add(&self, v: u64, labels: &L) {
self.metric
.with_label_values(&labels.label_values())
.inc_by(v);
}
#[must_use]
pub fn deferred_inc<'a>(&'a self, labels: L) -> DeferredAddWithLabels<'a, L> {
DeferredAddWithLabels::new(self, 1, labels)
}
#[must_use]
pub fn deferred_add<'a>(&'a self, v: u64, labels: L) -> DeferredAddWithLabels<'a, L> {
DeferredAddWithLabels::new(self, v, labels)
}
}
pub struct IntGaugeWithLabels<L: Labels> {
metric: IntGaugeVec,
_labels: PhantomData<L>,
}
impl<L: Labels> IntGaugeWithLabels<L> {
pub fn register_new(name: &str, help: &str) -> IntGaugeWithLabels<L> {
let metric = register_int_gauge_vec!(name, help, &L::label_names()).unwrap();
Self {
metric,
_labels: PhantomData,
}
}
pub fn set(&self, labels: &L, value: i64) {
self.metric
.with_label_values(&labels.label_values())
.set(value);
}
}