我试图为每个跟踪事件添加请求id。我可以对tower_http::trace
这样做:
#[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))
它在服务器范围内工作,但我还需要将请求id传递到外部任务队列。有什么建议吗?
自定义数据可以通过Extensions
在请求时存储。它们可以通过http::request::Request
上的.extensions()
和.extensions_mut()
(适用于hyper和tower-http)或通过axum::response::RequestParts
上的相同方法(适用于axum)访问。
扩展主要用于在服务/中间件之间移动数据到路由处理程序,反之亦然。这个集合的行为就像一个映射,它的值与它们的类型保持一致,所以如果你想存储Ulid
,你可能想把它包装成一些更描述性的类型,比如RequestId(Ulid)
,以确保它不与其他用途冲突。
参见:
- "扩展名"的作用是什么?在actix-web吗? 什么是Rust的HTTP扩展?(博客)
我按照rustlang论坛的解决方案制作了一个小箱子