'How to compose warp log?
I am pretty new in Rust and trying to build a web application with https://docs.rs/warp/0.2.3/warp/index.html.
I have tried:
#[tokio::main]
async fn main() {
// GET /hello/warp => 200 OK with body "Hello, warp!"
let cors = warp::cors()
.allow_origin("http://localhost:8090")
.allow_methods(vec!["GET", "POST", "DELETE"]);
let log = warp::log("dashbaord-svc");
let hello = warp::path!("hello" / String)
.with(cors)
.with(log)
.map(|name| format!("Hello, {}!", name));
warp::serve(hello)
.run(([127, 0, 0, 1], 9999))
.await;
}
and the compiler complains:
error[E0277]: `warp::filters::log::internal::Logged` doesn't implement `std::fmt::Display`
--> src/main.rs:16:43
|
16 | .map(|name| format!("Hello, {}!", name));
| ^^^^ `warp::filters::log::internal::Logged` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `warp::filters::log::internal::Logged`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required by `std::fmt::Display::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
What am I doing wrong?
Solution 1:[1]
let hello = warp::path!("hello" / String)
.with(cors)
.with(log)
.map(|name| format!("Hello, {}!", name));
Filter passes to follow-up filter data. In your code, the map function will receive data from the last filter before it which is the log filter and pass the data as "name", which is of type 'warp::filters::log::internal::Logged'. This type is not able be format! or print! with {} as it does not implement Display traits.
Filter sequence is important. Change the map function right after the path filter to receive the path param as "name":
let hello = warp::path!("hello" / String)
.map(|name| format!("Hello, {}!", name))
.with(cors)
.with(log);
Solution 2:[2]
Probably late, but my solution was to use the "custom" logger like:
let is_alive = warp:: path!("heartbeat").map(|| {
let heartbeat_alive = json!({ "status": "alive" });
json(&heartbeat_alive).into_response()
});
let incoming_log = warp::log::custom(|info| {
eprintln!(
"{} {} {} {:?}",
info.method(),
info.path(),
info.status(),
info.elapsed(),
);
});
let cors = warp::cors()
.allow_any_origin()
.allow_methods(vec!["GET", "POST", "PATCH", "OPTIONS", "DELETE"]);
is_alive
.with(incoming_log)
.with(cors)
You can also find the example in the docs themselves
https://github.com/seanmonstar/warp/blob/master/src/filters/log.rs#L60
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Yannik Yeo |
Solution 2 | marc_s |