Skip to main content

prometheus_measures_exporter/
lib.rs

1use hyper::header::CONTENT_TYPE;
2use hyper::service::{make_service_fn, service_fn};
3use hyper::{Body, Request, Response, Server};
4use lazy_static::lazy_static;
5use prometheus::core::{Atomic, GenericGauge};
6use prometheus::{Encoder, Histogram, HistogramOpts, IntCounter, Opts, TextEncoder};
7use std::convert::Infallible;
8use std::net::SocketAddr;
9use std::sync::Mutex;
10
11pub mod measurer;
12pub mod measurers_by_label;
13
14lazy_static! {
15    pub(crate) static ref ENABLE_PROMETHEUS: Mutex<bool> = Mutex::new(false);
16}
17
18pub fn start_prometheus_exporter() {
19    *ENABLE_PROMETHEUS.lock().unwrap() = true;
20    tokio::spawn(async move {
21        tracing::info!("starting prometheus exporter");
22        let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
23        let service = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(metrics)) });
24        let server = Server::bind(&addr).serve(service);
25        if let Err(e) = server.await {
26            tracing::error!("hyper server error: {}", e);
27        }
28    });
29}
30
31async fn metrics(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
32    let metric_families = prometheus::gather();
33    let encoder = TextEncoder::new();
34    let mut buffer = Vec::new();
35    encoder.encode(&metric_families, &mut buffer).unwrap();
36    let output = String::from_utf8(buffer.clone()).unwrap();
37    let mut response = Response::new(output.into());
38    response
39        .headers_mut()
40        .append(CONTENT_TYPE, encoder.format_type().parse().unwrap());
41    Ok(response)
42}
43
44pub trait MeasureBuilder<OPTS> {
45    fn build(source: OPTS) -> Self;
46}
47
48impl MeasureBuilder<Opts> for IntCounter {
49    fn build(opts: Opts) -> Self {
50        IntCounter::with_opts(opts).unwrap()
51    }
52}
53
54impl<P> MeasureBuilder<Opts> for GenericGauge<P>
55where
56    P: Atomic,
57{
58    fn build(source: Opts) -> Self {
59        GenericGauge::<P>::with_opts(source).unwrap()
60    }
61}
62
63impl MeasureBuilder<HistogramOpts> for Histogram {
64    fn build(opts: HistogramOpts) -> Self {
65        Histogram::with_opts(opts).unwrap()
66    }
67}