在使用tokio、axum、tracing的时候,想要打印入参的body参数,发现body的读取方法是异步的,这种情况下改怎么做呢
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
// axum logs rejections from built-in extractors with the `axum::rejection`
// target, at `TRACE` level. `axum::rejection=trace` enables showing those events
"example_tracing_aka_logging=debug,tower_http=debug,axum::rejection=trace".into()
}),
)
.with(tracing_subscriber::fmt::layer())
.init();
// build our application with a route
let app = Router::new()
.route("/", get(handler))
// `TraceLayer` is provided by tower-http so you have to add that as a dependency.
// It provides good defaults but is also very customizable.
//
// See https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html for more details.
//
// If you want to customize the behavior using closures here is how.
.layer(
TraceLayer::new_for_http()
.make_span_with(|request: &Request<_>| {
// Log the matched route's path (with placeholders not filled in).
// Use request.uri() or OriginalUri if you want the real path.
let matched_path = request
.extensions()
.get::<MatchedPath>()
.map(MatchedPath::as_str);
info_span!(
"http_request",
method = ?request.method(),
matched_path,
some_other_field = tracing::field::Empty,
)
})
.on_request(|_request: &Request<_>, _span: &Span| {
// You can use `_span.record("some_other_field", value)` in one of these
// closures to attach a value to the initially empty field in the info_span
// created above.
})
.on_response(|_response: &Response, _latency: Duration, _span: &Span| {
// ...
})
.on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {
// ...
})
.on_eos(
|_trailers: Option<&HeaderMap>, _stream_duration: Duration, _span: &Span| {
// ...
},
)
.on_failure(
|_error: ServerErrorsFailureClass, _latency: Duration, _span: &Span| {
// ...
},
),
);
// run it
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::debug!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
以上是axum的examples中的代码,在on_request中读取body: hyper::body::to_bytes(_request.body())
1
共 6 条评论, 1 页
评论区
写评论使用 crate futures 的 futures::executor::block_on
这个我试试,可是这样的话http日志就散落在两个地方,一部分在TraceLayer另一部分在自定义的middleware里
--
👇
ruby: TraceLayer的方法都是同步的,你应该用axum的middleware写个请求拦截器/中间件拦截请求,会有个异步的回调让你打印每个request的body
为何不用axum的middleware呢
https://github.com/tokio-rs/axum/blob/main/examples/consume-body-in-extractor-or-middleware/src/main.rs
https://github.com/tokio-rs/axum/blob/main/examples/print-request-response/src/main.rs
可以写一些代码例子不,我也搜到过一些类似的文章,不过都不太好用看起来,比如要自己实例化异步运行时
--
👇
JasonkayZK: 试试 block_on
TraceLayer的方法都是同步的,你应该用axum的middleware写个请求拦截器/中间件拦截请求,会有个异步的回调让你打印每个request的body
试试 block_on