2019-05-05 17:42:46 -07:00
|
|
|
//! Exports metrics over HTTP.
|
|
|
|
//!
|
2019-07-17 06:06:45 -07:00
|
|
|
//! This exporter can utilize observers that are able to be converted to a textual representation
|
|
|
|
//! via [`Drain<String>`]. It will respond to any requests, regardless of the method or path.
|
2019-05-05 17:42:46 -07:00
|
|
|
//!
|
2020-01-14 20:11:42 -08:00
|
|
|
//! Awaiting on `async_run` will drive an HTTP server listening on the configured address.
|
2019-07-05 18:14:08 -07:00
|
|
|
#![deny(missing_docs)]
|
2019-05-05 17:42:46 -07:00
|
|
|
|
2019-07-17 06:06:45 -07:00
|
|
|
use hyper::{
|
2020-01-14 20:11:42 -08:00
|
|
|
service::{make_service_fn, service_fn},
|
|
|
|
{Body, Error, Response, Server},
|
2019-07-17 06:06:45 -07:00
|
|
|
};
|
|
|
|
use metrics_core::{Builder, Drain, Observe, Observer};
|
|
|
|
use std::{net::SocketAddr, sync::Arc};
|
2019-05-05 17:42:46 -07:00
|
|
|
|
|
|
|
/// Exports metrics over HTTP.
|
2019-07-15 06:35:34 -07:00
|
|
|
pub struct HttpExporter<C, B> {
|
2019-05-05 17:42:46 -07:00
|
|
|
controller: C,
|
2019-07-15 06:35:34 -07:00
|
|
|
builder: B,
|
2019-05-05 17:42:46 -07:00
|
|
|
address: SocketAddr,
|
|
|
|
}
|
|
|
|
|
2019-07-15 06:35:34 -07:00
|
|
|
impl<C, B> HttpExporter<C, B>
|
2019-05-05 17:42:46 -07:00
|
|
|
where
|
2019-07-17 06:06:45 -07:00
|
|
|
C: Observe + Send + Sync + 'static,
|
2019-07-15 06:35:34 -07:00
|
|
|
B: Builder + Send + Sync + 'static,
|
2019-07-17 06:06:45 -07:00
|
|
|
B::Output: Drain<String> + Observer,
|
2019-05-05 17:42:46 -07:00
|
|
|
{
|
|
|
|
/// Creates a new [`HttpExporter`] that listens on the given `address`.
|
|
|
|
///
|
2019-07-17 06:06:45 -07:00
|
|
|
/// Observers expose their output by being converted into strings.
|
2019-07-15 06:35:34 -07:00
|
|
|
pub fn new(controller: C, builder: B, address: SocketAddr) -> Self {
|
2019-05-05 17:42:46 -07:00
|
|
|
HttpExporter {
|
|
|
|
controller,
|
2019-07-15 06:35:34 -07:00
|
|
|
builder,
|
2019-05-05 17:42:46 -07:00
|
|
|
address,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-14 20:11:42 -08:00
|
|
|
/// Starts an HTTP server on the `address` the exporter was originally configured with,
|
2019-07-17 06:06:45 -07:00
|
|
|
/// responding to any request with the output of the configured observer.
|
2020-01-14 20:11:42 -08:00
|
|
|
pub async fn async_run(self) -> hyper::error::Result<()> {
|
|
|
|
let builder = Arc::new(self.builder);
|
|
|
|
let controller = Arc::new(self.controller);
|
2019-07-15 06:35:34 -07:00
|
|
|
|
2020-01-14 20:11:42 -08:00
|
|
|
let make_svc = make_service_fn(move |_| {
|
|
|
|
let builder = builder.clone();
|
|
|
|
let controller = controller.clone();
|
2019-05-05 17:42:46 -07:00
|
|
|
|
2020-01-14 20:11:42 -08:00
|
|
|
async move {
|
|
|
|
Ok::<_, Error>(service_fn(move |_| {
|
|
|
|
let builder = builder.clone();
|
|
|
|
let controller = controller.clone();
|
2019-05-05 17:42:46 -07:00
|
|
|
|
2020-01-14 20:11:42 -08:00
|
|
|
async move {
|
|
|
|
let mut observer = builder.build();
|
|
|
|
controller.observe(&mut observer);
|
|
|
|
let output = observer.drain();
|
|
|
|
Ok::<_, Error>(Response::new(Body::from(output)))
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
});
|
2019-05-05 17:42:46 -07:00
|
|
|
|
2020-01-14 20:11:42 -08:00
|
|
|
Server::bind(&self.address).serve(make_svc).await
|
|
|
|
}
|
2019-05-05 17:42:46 -07:00
|
|
|
}
|