如何在 warp 中记录请求/响应主体?

Xav*_*r P 1 logging rust rust-warp

我正在尝试在 warp 中记录请求/响应主体。

使用时warp::log::custom,该Info结构不包含任何有关它的信息。

当尝试实现我自己的日志包装器时,基于 的实现warp::log,该Route结构是私有的(除其他外)。

我可以使用反序列化后记录主体

warp::body::json().map(|it| {
    println!("Hello : {:?}", it);
    it
})
Run Code Online (Sandbox Code Playgroud)

但如果用户没有发送正确的正文,它将无法工作。此外,我正在寻找一种简单的方法来记录所有请求主体。

小智 8

我在自己寻找解决方案时偶然发现了这一点,所以也许它对将来的某人有用。

您可以使用warp::body::bytes()不一定是 json 格式来获取正文:

warp::body::bytes()
    .map(|b: Bytes| {
        println!("Request body: {}", std::str::from_utf8(b.bytes()).expect("error converting bytes to &str"));

        "Hello, World!"
    }
Run Code Online (Sandbox Code Playgroud)

为了使其更加通用,我设法创建了一个可以在过滤器中轻松使用的函数:

fn log_body() -> impl Filter<Extract = (), Error = Rejection> + Copy {
    warp::body::bytes()
        .map(|b: Bytes| {
            println!("Request body: {}", std::str::from_utf8(b.bytes()).expect("error converting bytes to &str"));
        })
        .untuple_one()
}
Run Code Online (Sandbox Code Playgroud)

然后可以这样使用:

    let api = warp::any()
        .and(log_body())
        .and_then(handle);
Run Code Online (Sandbox Code Playgroud)

对于完整的示例,您可以查看我准备的要点。