-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
use bytes::Bytes; | ||
use http_body_util::Full; | ||
use hyper::service::service_fn; | ||
use hyper::{body, Request, Response, Version}; | ||
use hyper_util::rt::TokioExecutor; | ||
|
||
use opentelemetry_sdk::metrics::SdkMeterProvider; | ||
use prometheus::{Encoder, TextEncoder}; | ||
use tokio::net::TcpListener; | ||
use tracing::{error, info, warn}; | ||
|
||
pub async fn setup_metrics_provider(addr: &str) -> anyhow::Result<SdkMeterProvider> { | ||
let registry = prometheus::Registry::new(); | ||
|
||
// configure OpenTelemetry to use this registry | ||
let exporter = opentelemetry_prometheus::exporter() | ||
.with_registry(registry.clone()) | ||
.build()?; | ||
|
||
// set up a meter to create instruments | ||
let provider = SdkMeterProvider::builder().with_reader(exporter).build(); | ||
let listener = TcpListener::bind(addr).await?; | ||
info!("Started metrics server on {}", addr); | ||
|
||
tokio::spawn(async move { | ||
loop { | ||
let (stream, _) = match listener.accept().await { | ||
Ok(ret) => ret, | ||
Err(err) => { | ||
warn!("Error while accepting connection on metrics port {:?}", err); | ||
continue; | ||
} | ||
}; | ||
|
||
let stream = hyper_util::rt::TokioIo::new(stream); | ||
let conn = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new()); | ||
let fut = conn | ||
.serve_connection( | ||
stream, | ||
service_fn(|req: Request<body::Incoming>| { | ||
// Create handler local registry for ownership | ||
let registry = registry.clone(); | ||
async move { | ||
let encoder = TextEncoder::new(); | ||
let metric_families = registry.gather(); | ||
let mut result = Vec::new(); | ||
if let Err(err) = encoder.encode(&metric_families, &mut result) { | ||
error!("Failed to encode prometheus metrics: {:?}", err); | ||
return Err("failed to create metrics export") | ||
} | ||
|
||
if req.version() == Version::HTTP_11 { | ||
Ok(Response::new(Full::<Bytes>::from(result))) | ||
} else { | ||
// Note: it's usually better to return a Response | ||
// with an appropriate StatusCode instead of an Err. | ||
Err("not HTTP/1.1, abort connection") | ||
} | ||
} | ||
}), | ||
) | ||
.await; | ||
|
||
if let Err(err) = fut { | ||
warn!("Failed to handle metrics connection: {:?}", err) | ||
} | ||
} | ||
}); | ||
|
||
return Ok(provider); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters