pub fn trace<F>(func: F) -> Trace<F> where
    F: Fn(Info<'_>) -> Span + Clone
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
Hide additional 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;
}