Line data Source code
1 : use axum::{body::Body, response::Response};
2 : use http::header::CONTENT_TYPE;
3 : use http::StatusCode;
4 : use metrics::proto::MetricFamily;
5 : use metrics::{Encoder, TextEncoder};
6 :
7 : use crate::{http::JsonResponse, metrics::collect};
8 :
9 : /// Expose Prometheus metrics.
10 0 : pub(in crate::http) async fn get_metrics() -> Response {
11 0 : // When we call TextEncoder::encode() below, it will immediately return an
12 0 : // error if a metric family has no metrics, so we need to preemptively
13 0 : // filter out metric families with no metrics.
14 0 : let metrics = collect()
15 0 : .into_iter()
16 0 : .filter(|m| !m.get_metric().is_empty())
17 0 : .collect::<Vec<MetricFamily>>();
18 0 :
19 0 : let encoder = TextEncoder::new();
20 0 : let mut buffer = vec![];
21 :
22 0 : if let Err(e) = encoder.encode(&metrics, &mut buffer) {
23 0 : return JsonResponse::error(StatusCode::INTERNAL_SERVER_ERROR, e);
24 0 : }
25 0 :
26 0 : Response::builder()
27 0 : .status(StatusCode::OK)
28 0 : .header(CONTENT_TYPE, encoder.format_type())
29 0 : .body(Body::from(buffer))
30 0 : .unwrap()
31 0 : }
|