prometheus-hyper 0.2.1

small Tokio/Hyper server to run Prometheus metrics
Documentation
//! Simple example that counts runtime
use prometheus::{IntCounter, Opts, Registry};
use prometheus_hyper::{RegistryFn, Server};
use std::{
    error::Error,
    net::SocketAddr,
    sync::{
        Arc,
        atomic::{AtomicBool, Ordering},
    },
    time::Duration,
};
use tracing::{debug, info};

pub struct Metrics {
    pub seconds_total: IntCounter,
}

impl Metrics {
    pub fn new() -> Result<(Self, RegistryFn), Box<dyn Error>> {
        let seconds_total = IntCounter::with_opts(Opts::new(
            "seconds_total",
            "count the runtime of this service in seconds",
        ))?;

        let seconds_total_clone = seconds_total.clone();

        let f = |registry: &Registry| {
            registry.register(Box::new(seconds_total_clone))?;
            Ok(())
        };

        Ok((Self { seconds_total }, Box::new(f)))
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    // Initialize logging.
    tracing_subscriber::fmt().with_max_level(tracing::Level::TRACE).init();
    info!("Starting clock...");

    let running = Arc::new(AtomicBool::new(true));

    let registry = Arc::new(Registry::new());
    let (metrics, f) = Metrics::new().expect("failed prometheus");
    f(&registry).expect("problem registering");
    tokio::spawn(Server::run(
        Arc::clone(&registry),
        SocketAddr::from(([0; 4], 8080)),
        shutdown_signal(Arc::clone(&running)),
    ));

    let mut sec_int = tokio::time::interval(Duration::from_secs(1));
    while running.load(Ordering::Relaxed) {
        sec_int.tick().await;
        metrics.seconds_total.inc();
        debug!("tick");
        sec_int.tick().await;
        metrics.seconds_total.inc();
        debug!("tock");
    }
    info!("stopped clock");
}

async fn shutdown_signal(running: Arc<AtomicBool>) {
    // Wait for the CTRL+C Signal
    tokio::signal::ctrl_c()
        .await
        .expect("Failed to install CTRL+C signal handler");
    running.store(false, Ordering::Relaxed);
}