relay_server/middlewares/
metrics.rs

1use axum::RequestExt;
2use axum::extract::{MatchedPath, Request};
3use axum::middleware::Next;
4use axum::response::Response;
5use std::time::Instant;
6
7use crate::extractors::ReceivedAt;
8use crate::statsd::{RelayCounters, RelayTimers};
9
10/// A middleware that logs web request timings as statsd metrics.
11///
12/// Use this with [`axum::middleware::from_fn`].
13pub async fn metrics(mut request: Request, next: Next) -> Response {
14    let request_start = Instant::now();
15
16    let received_at = ReceivedAt::now();
17    request.extensions_mut().insert(received_at);
18
19    let matched_path = request.extract_parts::<MatchedPath>().await;
20    let route = matched_path.as_ref().map_or("unknown", |m| m.as_str());
21    let method = request.method().clone();
22
23    relay_statsd::metric!(
24        counter(RelayCounters::Requests) += 1,
25        route = route,
26        method = method.as_str(),
27    );
28
29    let response = next.run(request).await;
30
31    relay_statsd::metric!(
32        timer(RelayTimers::RequestsDuration) = request_start.elapsed(),
33        route = route,
34        method = method.as_str(),
35    );
36    relay_statsd::metric!(
37        counter(RelayCounters::ResponsesStatusCodes) += 1,
38        status_code = response.status().as_str(),
39        route = route,
40        method = method.as_str(),
41    );
42
43    response
44}