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