I'm trying to add a request id to each tracing event. I can do it with tower_http::trace
like this:
#[derive(Clone)]
pub struct RequestSpan;
impl<B> tower_http::trace::MakeSpan<B> for RequestSpan {
fn make_span(&mut self, request: &http::Request<B>) -> tracing::Span {
tracing::error_span!(
"rq",
id = %ulid::Ulid::new().to_string(),
method = %request.method(),
uri = %request.uri(),
version = ?request.version(),
)
}
}
...
let middleware_stack = tower::ServiceBuilder::new()
.layer(TraceLayer::new_for_http().make_span_with(RequestSpan))
It works in the scope of the server, but I also need to pass the request id into an external task queue. Any suggestions?
Custom data can be stored on requests via
Extensions
. They are accessible via.extensions()
and.extensions_mut()
on ahttp::request::Request
(which works for hyper and tower-http) or via the same methods onaxum::response::RequestParts
(which works for axum).Extensions are primarily used to move data between services/middleware to the route handler and vice-versa. The collection acts like a map with values keyed-off of their type, so if you want to store a
Ulid
you probably want to wrap it in some more descriptive type likeRequestId(Ulid)
just to ensure it doesn't conflict with other uses.See also: