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 ownSpan
using theInfo
struct, 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.