rust 55 lines · 8 steps

Logging request and response sizes in Axum

An Axum middleware buffers each request and response body to measure and log their byte sizes without breaking the handler chain.

Explained by highlit
1use axum::{
2 body::{Body, Bytes},
3 extract::Request,
4 http::StatusCode,
5 middleware::{from_fn, Next},
6 response::{IntoResponse, Response},
7 routing::{get, post},
8 Router,
9};
10use http_body_util::BodyExt;
11use tracing::info;
12 
13pub fn upload_routes() -> Router {
14 Router::new()
15 .route("/upload", post(handle_upload))
16 .route("/blobs/:id", get(fetch_blob))
17 .layer(from_fn(log_body_sizes))
18}
19 
20async fn log_body_sizes(request: Request, next: Next) -> Result<Response, StatusCode> {
21 let method = request.method().clone();
22 let path = request.uri().path().to_owned();
23 
24 let (parts, body) = request.into_parts();
25 let req_bytes = buffer(body).await?;
26 let req_len = req_bytes.len();
27 let request = Request::from_parts(parts, Body::from(req_bytes));
28 
29 let response = next.run(request).await;
30 
31 let (parts, body) = response.into_parts();
32 let res_bytes = buffer(body).await?;
33 let res_len = res_bytes.len();
34 
35 info!(
36 %method,
37 %path,
38 status = parts.status.as_u16(),
39 request_bytes = req_len,
40 response_bytes = res_len,
41 "handled request"
42 );
43 
44 Ok((parts, Body::from(res_bytes)).into_response())
45}
46 
47async fn buffer<B>(body: B) -> Result<Bytes, StatusCode>
48where
49 B: axum::body::HttpBody<Data = Bytes>,
50{
51 body.collect()
52 .await
53 .map(|c| c.to_bytes())
54 .map_err(|_| StatusCode::BAD_REQUEST)
55}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Buffering a streaming body consumes it, so you must rebuild the request or response from the collected bytes to pass it along.
  2. 2Splitting a request or response into parts and body lets middleware inspect metadata and payload independently.
  3. 3A generic helper bounded on HttpBody can collect any body type into Bytes, mapping errors into a clean status code.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Logging request and response sizes in Axum — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code