🛈 Note: This is pre-release documentation for the upcoming tracing 0.2.0 ecosystem.

For the release documentation, please see docs.rs, instead.

tracing_tower/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc(
3    html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
4    html_favicon_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/favicon.ico",
5    issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
6)]
7#![warn(
8    missing_debug_implementations,
9    // missing_docs, // TODO: add documentation!
10    rust_2018_idioms,
11    unreachable_pub,
12    bad_style,
13    dead_code,
14    improper_ctypes,
15    non_shorthand_field_patterns,
16    no_mangle_generic_items,
17    overflowing_literals,
18    path_statements,
19    patterns_in_fns_without_body,
20    private_interfaces,
21    private_bounds,
22    unconditional_recursion,
23    unused,
24    unused_allocation,
25    unused_comparisons,
26    unused_parens,
27    while_true
28)]
29
30use std::fmt;
31use tower_service::Service;
32use tracing::Level;
33
34pub mod request_span;
35pub mod service_span;
36
37#[cfg(feature = "http")]
38#[cfg_attr(docsrs, doc(cfg(feature = "http")))]
39pub mod http;
40
41pub type InstrumentedService<S, R> = service_span::Service<request_span::Service<S, R>>;
42
43pub trait InstrumentableService<Request>
44where
45    Self: Service<Request> + Sized,
46{
47    fn instrument<G>(self, svc_span: G) -> InstrumentedService<Self, Request>
48    where
49        G: GetSpan<Self>,
50        Request: fmt::Debug,
51    {
52        let req_span: fn(&Request) -> tracing::Span =
53            |request| tracing::span!(Level::TRACE, "request", ?request);
54        let svc_span = svc_span.span_for(&self);
55        self.trace_requests(req_span).trace_service(svc_span)
56    }
57
58    fn trace_requests<G>(self, get_span: G) -> request_span::Service<Self, Request, G>
59    where
60        G: GetSpan<Request> + Clone,
61    {
62        request_span::Service::new(self, get_span)
63    }
64
65    fn trace_service<G>(self, get_span: G) -> service_span::Service<Self>
66    where
67        G: GetSpan<Self>,
68    {
69        let span = get_span.span_for(&self);
70        service_span::Service::new(self, span)
71    }
72}
73
74impl<S, R> InstrumentableService<R> for S where S: Service<R> + Sized {}
75
76pub trait GetSpan<T>: crate::sealed::Sealed<T> {
77    fn span_for(&self, target: &T) -> tracing::Span;
78}
79
80impl<T, F> crate::sealed::Sealed<T> for F where F: Fn(&T) -> tracing::Span {}
81
82impl<T, F> GetSpan<T> for F
83where
84    F: Fn(&T) -> tracing::Span,
85{
86    #[inline]
87    fn span_for(&self, target: &T) -> tracing::Span {
88        (self)(target)
89    }
90}
91
92impl<T> crate::sealed::Sealed<T> for tracing::Span {}
93
94impl<T> GetSpan<T> for tracing::Span {
95    #[inline]
96    fn span_for(&self, _: &T) -> tracing::Span {
97        self.clone()
98    }
99}
100
101mod sealed {
102    pub trait Sealed<T = ()> {}
103}