Logging and Tracing
warp provides filters for logging requests and integrating with the tracing ecosystem for rich, structured diagnostics.
Simple Access Logging (warp::log)
For basic access logging, warp provides the warp::log() filter. It wraps another filter and logs a summary of each request and its response to the standard log facade.
use warp::Filter;
// To view logs, you might need to initialize a logger, like `pretty_env_logger`.
// Run with `RUST_LOG=my_app=info` to see the logs.
// pretty_env_logger::init();
let log = warp::log("my_app");
let routes = warp::any()
.map(|| "Hello, World!")
.with(log);
A typical log line looks like this:
INFO my_app > "GET / HTTP/1.1" 200 "-" "curl/7.64.1" 2.13µs
This format includes the request method, path, HTTP version, response status code, referer, user-agent, and latency.
Advanced Diagnostics with warp::trace
For more advanced and structured diagnostics, warp integrates with the tracing crate. This allows you to create spans for requests, which group together all related events and logs, providing a clear context for what happened during a request's lifecycle.
Setting up tracing
First, you need to set up a tracing subscriber. tracing-subscriber is a common choice.
use tracing_subscriber::fmt::format::FmtSpan;
// In your main function:
tracing_subscriber::fmt()
.with_env_filter("info,warp=debug")
// Log events when spans close, which includes latency.
.with_span_events(FmtSpan::CLOSE)
.init();
Using the Trace Filters
-
warp::trace::request(): This is the main filter to wrap your entire API. It creates atracing::info_span!for each incoming request, automatically including fields like method, path, and remote address.use warp::Filter; let routes = some_filter // ... .with(warp::trace::request()); -
warp::trace::named("..."): This filter creates a sub-span within the main request span. It's useful for instrumenting specific parts of your application to see how much time is spent in different sections.use warp::Filter; let users_api = warp::path("users") .map(|| "users") .with(warp::trace::named("api::users")); let products_api = warp::path("products") .map(|| "products") .with(warp::trace::named("api::products")); let routes = users_api.or(products_api) .with(warp::trace::request()); -
warp::trace::trace(|info| ...): For full control, this filter allows you to construct your ownSpanusing theInfostruct, which contains details about the request.
By using warp::trace, you can produce detailed, structured logs that are invaluable for debugging and monitoring your application.