rama_http/layer/trace/on_request.rs
1use super::DEFAULT_MESSAGE_LEVEL;
2use crate::Request;
3use rama_core::telemetry::tracing::{Level, Span};
4
5/// Trait used to tell [`Trace`] what to do when a request is received.
6///
7/// See the [module docs](../trace/index.html#on_request) for details on exactly when the
8/// `on_request` callback is called.
9///
10/// [`Trace`]: super::Trace
11pub trait OnRequest<B>: Send + Sync + 'static {
12 /// Do the thing.
13 ///
14 /// `span` is the `tracing` [`Span`], corresponding to this request, produced by the closure
15 /// passed to [`TraceLayer::make_span_with`]. It can be used to [record field values][record]
16 /// that weren't known when the span was created.
17 ///
18 /// [`Span`]: https://docs.rs/tracing/latest/tracing/span/index.html
19 /// [record]: https://docs.rs/tracing/latest/tracing/span/struct.Span.html#method.record
20 /// [`TraceLayer::make_span_with`]: crate::layer::trace::TraceLayer::make_span_with
21 fn on_request(&self, request: &Request<B>, span: &Span);
22}
23
24impl<B> OnRequest<B> for () {
25 #[inline]
26 fn on_request(&self, _: &Request<B>, _: &Span) {}
27}
28
29impl<B, F> OnRequest<B> for F
30where
31 F: Fn(&Request<B>, &Span) + Send + Sync + 'static,
32{
33 fn on_request(&self, request: &Request<B>, span: &Span) {
34 self(request, span)
35 }
36}
37
38/// The default [`OnRequest`] implementation used by [`Trace`].
39///
40/// [`Trace`]: super::Trace
41#[derive(Clone, Debug)]
42pub struct DefaultOnRequest {
43 level: Level,
44}
45
46impl Default for DefaultOnRequest {
47 fn default() -> Self {
48 Self {
49 level: DEFAULT_MESSAGE_LEVEL,
50 }
51 }
52}
53
54impl DefaultOnRequest {
55 /// Create a new `DefaultOnRequest`.
56 #[must_use]
57 pub fn new() -> Self {
58 Self::default()
59 }
60
61 rama_utils::macros::generate_set_and_with! {
62 /// Set the [`Level`] used for [tracing events].
63 ///
64 /// Please note that while this will set the level for the tracing events
65 /// themselves, it might cause them to lack expected information, like
66 /// request method or path. You can address this using
67 /// [`DefaultMakeSpan::level`].
68 ///
69 /// Defaults to [`Level::DEBUG`].
70 ///
71 /// [tracing events]: https://docs.rs/tracing/latest/tracing/#events
72 /// [`DefaultMakeSpan::level`]: crate::layer::trace::DefaultMakeSpan::level
73 pub fn level(mut self, level: Level) -> Self {
74 self.level = level;
75 self
76 }
77 }
78}
79
80impl<B> OnRequest<B> for DefaultOnRequest {
81 fn on_request(&self, _: &Request<B>, span: &Span) {
82 event_dynamic_lvl!(
83 parent: span,
84 self.level,
85 "started processing request",
86 );
87 }
88}