Expand description
Create a wrapping filter that instruments every request with a custom
tracing
Span
provided by a function.
Example
use warp::Filter;
let route = warp::any()
.map(warp::reply)
.with(warp::trace(|info| {
// Create a span using tracing macros
tracing::info_span!(
"request",
method = %info.method(),
path = %info.path(),
)
}));
Examples found in repository?
src/filters/trace.rs (lines 44-66)
≺ ≻
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
pub fn request() -> Trace<impl Fn(Info) -> Span + Clone> {
use tracing::field::{display, Empty};
trace(|info: Info| {
let span = tracing::info_span!(
"request",
remote.addr = Empty,
method = %info.method(),
path = %info.path(),
version = ?info.route.version(),
referer = Empty,
);
// Record optional fields.
if let Some(remote_addr) = info.remote_addr() {
span.record("remote.addr", &display(remote_addr));
}
if let Some(referer) = info.referer() {
span.record("referer", &display(referer));
}
tracing::debug!(parent: &span, "received request");
span
})
}
/// Create a wrapping filter that instruments every request with a custom
/// `tracing` [`Span`] provided by a function.
///
///
/// # Example
///
/// ```
/// use warp::Filter;
///
/// let route = warp::any()
/// .map(warp::reply)
/// .with(warp::trace(|info| {
/// // Create a span using tracing macros
/// tracing::info_span!(
/// "request",
/// method = %info.method(),
/// path = %info.path(),
/// )
/// }));
/// ```
///
/// [`Span`]: https://docs.rs/tracing/latest/tracing/#spans
pub fn trace<F>(func: F) -> Trace<F>
where
F: Fn(Info) -> Span + Clone,
{
Trace { func }
}
/// Create a wrapping filter that instruments every request with a `tracing`
/// [`Span`] at the [`DEBUG`] level representing a named context.
///
/// This can be used to instrument multiple routes with their own sub-spans in a
/// per-request trace.
///
/// # Example
///
/// ```
/// use warp::Filter;
///
/// let hello = warp::path("hello")
/// .map(warp::reply)
/// .with(warp::trace::named("hello"));
///
/// let goodbye = warp::path("goodbye")
/// .map(warp::reply)
/// .with(warp::trace::named("goodbye"));
///
/// let routes = hello.or(goodbye);
/// ```
///
/// [`Span`]: https://docs.rs/tracing/latest/tracing/#spans
/// [`DEBUG`]: https://docs.rs/tracing/0.1.16/tracing/struct.Level.html#associatedconstant.DEBUG
pub fn named(name: &'static str) -> Trace<impl Fn(Info<'_>) -> Span + Copy> {
trace(move |_| tracing::debug_span!("context", "{}", name,))
}
More examples
examples/tracing.rs (lines 47-50)
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
async fn main() {
// Filter traces based on the RUST_LOG env var, or, if it's not set,
// default to show the output of the example.
let filter = std::env::var("RUST_LOG").unwrap_or_else(|_| "tracing=info,warp=debug".to_owned());
// Configure the default `tracing` subscriber.
// The `fmt` subscriber from the `tracing-subscriber` crate logs `tracing`
// events to stdout. Other subscribers are available for integrating with
// distributed tracing systems such as OpenTelemetry.
tracing_subscriber::fmt()
// Use the filter we built above to determine which traces to record.
.with_env_filter(filter)
// Record an event when each span closes. This can be used to time our
// routes' durations!
.with_span_events(FmtSpan::CLOSE)
.init();
let hello = warp::path("hello")
.and(warp::get())
// When the `hello` route is called, emit a `tracing` event.
.map(|| {
tracing::info!("saying hello...");
"Hello, World!"
})
// Wrap the route in a `tracing` span to add the route's name as context
// to any events that occur inside it.
.with(warp::trace::named("hello"));
let goodbye = warp::path("goodbye")
.and(warp::get())
.map(|| {
tracing::info!("saying goodbye...");
"So long and thanks for all the fish!"
})
// We can also provide our own custom `tracing` spans to wrap a route.
.with(warp::trace(|info| {
// Construct our own custom span for this route.
tracing::info_span!("goodbye", req.path = ?info.path())
}));
let routes = hello
.or(goodbye)
// Wrap all the routes with a filter that creates a `tracing` span for
// each request we receive, including data about the request.
.with(warp::trace::request());
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
}