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 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}