trace_tools/
observe.rs

1// Copyright 2022 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use tracing::trace_span;
5use tracing_futures::{Instrument, Instrumented};
6
7/// The field name of the [`Span`](tracing::Span) location file.
8pub(crate) const FILE_FIELD_NAME: &str = "loc.file";
9
10/// The field name of the [`Span`](tracing::Span) location line.
11pub(crate) const LINE_FIELD_NAME: &str = "loc.line";
12
13/// The target of the wrapping [`Span`](tracing::Span).
14pub const SPAN_TARGET: &str = "trace_tools::observe";
15
16/// The name of the wrapping [`Span`](tracing::Span).
17pub const SPAN_NAME: &str = "observed";
18
19/// Instruments a future with a `tracing` span.
20///
21/// This span is given the `trace_tools::observe` target, so that it can be more easily filtered
22/// in any subscribers or subscriber layers. It also records the future's calling location
23/// in its fields.
24pub trait Observe: Sized {
25    #[track_caller]
26    /// Instruments `Self` with a `tracing` span, returning [`Instrumented<Self>`].
27    fn observe(self, name: &str) -> Instrumented<Self>;
28}
29
30impl<T: Instrument> Observe for T {
31    #[track_caller]
32    fn observe(self, name: &str) -> Instrumented<Self> {
33        let location = std::panic::Location::caller();
34
35        let span = trace_span!(
36            target: SPAN_TARGET,
37            SPAN_NAME,
38            observed.name = name,
39            loc.file = location.file(),
40            loc.line = location.line(),
41            loc.col = location.column(),
42        );
43
44        self.instrument(span)
45    }
46}