prometheus_measures_exporter/
lib.rs1use 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}