use crate::metrics::Observer;
use prometheus::{
core::{Collector, Desc},
proto::MetricFamily,
Histogram, HistogramOpts, HistogramVec,
};
use std::{ops::Deref, time::Instant};
#[derive(Clone)]
pub struct Latency(HistogramVec);
impl Latency {
pub fn new(opts: HistogramOpts, label_names: &[&str]) -> prometheus::Result<Self> {
Ok(Self(HistogramVec::new(opts, label_names)?))
}
pub fn make_observer(&self, labels: &[&str]) -> LatencyObserver {
LatencyObserver {
hist: self.0.with_label_values(labels),
instant: Instant::now(),
}
}
pub fn record(&self, labels: &[&str], value: f64) {
self.0.with_label_values(labels).observe(value)
}
}
impl Deref for Latency {
type Target = HistogramVec;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Collector for Latency {
fn desc(&self) -> Vec<&Desc> {
self.0.desc()
}
fn collect(&self) -> Vec<MetricFamily> {
self.0.collect()
}
}
pub struct LatencyObserver {
hist: Histogram,
instant: Instant,
}
impl<Out: ?Sized> Observer<Out> for LatencyObserver {
fn on_first_poll(&mut self) {
self.instant = Instant::now();
}
fn on_finish(&mut self, _: Option<&Out>) {
self.hist.observe(self.instant.elapsed().as_secs_f64());
}
}