🛈 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/
request_span.rs

1//! Middleware which instruments each request passing through a service with a new span.
2use super::GetSpan;
3use futures::future::Future;
4use std::marker::PhantomData;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use tracing::Instrument;
8
9#[derive(Debug)]
10pub struct Service<S, R, G = fn(&R) -> tracing::Span>
11where
12    S: tower_service::Service<R>,
13    G: GetSpan<R>,
14{
15    get_span: G,
16    inner: S,
17    _p: PhantomData<fn(R)>,
18}
19
20#[cfg(feature = "tower-layer")]
21#[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
22pub use self::layer::*;
23
24#[cfg(feature = "tower-layer")]
25#[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
26mod layer {
27    use super::*;
28
29    #[derive(Debug)]
30    pub struct Layer<R, G = fn(&R) -> tracing::Span>
31    where
32        G: GetSpan<R> + Clone,
33    {
34        get_span: G,
35        _p: PhantomData<fn(R)>,
36    }
37
38    pub fn layer<R, G>(get_span: G) -> Layer<R, G>
39    where
40        G: GetSpan<R> + Clone,
41    {
42        Layer {
43            get_span,
44            _p: PhantomData,
45        }
46    }
47
48    // === impl Subscriber ===
49    impl<S, R, G> tower_layer::Layer<S> for Layer<R, G>
50    where
51        S: tower_service::Service<R>,
52        G: GetSpan<R> + Clone,
53    {
54        type Service = Service<S, R, G>;
55
56        fn layer(&self, service: S) -> Self::Service {
57            Service::new(service, self.get_span.clone())
58        }
59    }
60
61    impl<R, G> Clone for Layer<R, G>
62    where
63        G: GetSpan<R> + Clone,
64    {
65        fn clone(&self) -> Self {
66            Self {
67                get_span: self.get_span.clone(),
68                _p: PhantomData,
69            }
70        }
71    }
72}
73
74#[cfg(feature = "tower-make")]
75#[cfg_attr(docsrs, doc(cfg(feature = "tower-make")))]
76pub use self::make::MakeService;
77
78#[cfg(feature = "tower-make")]
79#[cfg_attr(docsrs, doc(cfg(feature = "tower-make")))]
80pub mod make {
81    use super::*;
82    use pin_project_lite::pin_project;
83
84    #[derive(Debug)]
85    pub struct MakeService<S, R, G = fn(&R) -> tracing::Span> {
86        get_span: G,
87        inner: S,
88        _p: PhantomData<fn(R)>,
89    }
90
91    #[cfg(feature = "tower-layer")]
92    #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
93    #[derive(Debug)]
94    pub struct MakeLayer<R, T, G = fn(&R) -> tracing::Span>
95    where
96        G: GetSpan<R> + Clone,
97    {
98        get_span: G,
99        _p: PhantomData<fn(T, R)>,
100    }
101
102    pin_project! {
103        #[derive(Debug)]
104        pub struct MakeFuture<F, R, G = fn(&R) -> tracing::Span> {
105            get_span: Option<G>,
106            #[pin]
107            inner: F,
108            _p: PhantomData<fn(R)>,
109        }
110    }
111
112    #[cfg(feature = "tower-layer")]
113    #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
114    pub fn layer<R, T, G>(get_span: G) -> MakeLayer<R, T, G>
115    where
116        G: GetSpan<R> + Clone,
117    {
118        MakeLayer {
119            get_span,
120            _p: PhantomData,
121        }
122    }
123
124    // === impl MakeLayer ===
125
126    #[cfg(feature = "tower-layer")]
127    #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
128    impl<S, R, G, T> tower_layer::Layer<S> for MakeLayer<R, T, G>
129    where
130        S: tower_make::MakeService<T, R>,
131        G: GetSpan<R> + Clone,
132    {
133        type Service = MakeService<S, R, G>;
134
135        fn layer(&self, inner: S) -> Self::Service {
136            MakeService::new(inner, self.get_span.clone())
137        }
138    }
139
140    #[cfg(feature = "tower-layer")]
141    #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
142    impl<R, T, G> Clone for MakeLayer<R, T, G>
143    where
144        G: GetSpan<R> + Clone,
145    {
146        fn clone(&self) -> Self {
147            Self {
148                get_span: self.get_span.clone(),
149                _p: PhantomData,
150            }
151        }
152    }
153
154    // === impl MakeService ===
155
156    impl<S, R, G, T> tower_service::Service<T> for MakeService<S, R, G>
157    where
158        S: tower_make::MakeService<T, R>,
159        G: GetSpan<R> + Clone,
160    {
161        type Response = Service<S::Service, R, G>;
162        type Error = S::MakeError;
163        type Future = MakeFuture<S::Future, R, G>;
164
165        fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
166            self.inner.poll_ready(cx)
167        }
168
169        fn call(&mut self, target: T) -> Self::Future {
170            let inner = self.inner.make_service(target);
171            let get_span = Some(self.get_span.clone());
172            MakeFuture {
173                get_span,
174                inner,
175                _p: PhantomData,
176            }
177        }
178    }
179
180    impl<S, R, G> MakeService<S, R, G>
181    where
182        G: GetSpan<R> + Clone,
183    {
184        pub fn new<T>(inner: S, get_span: G) -> Self
185        where
186            S: tower_make::MakeService<T, R>,
187        {
188            Self {
189                get_span,
190                inner,
191                _p: PhantomData,
192            }
193        }
194    }
195
196    impl<S, R, G> Clone for MakeService<S, R, G>
197    where
198        G: GetSpan<R> + Clone,
199        S: Clone,
200    {
201        fn clone(&self) -> Self {
202            Self {
203                get_span: self.get_span.clone(),
204                inner: self.inner.clone(),
205                _p: PhantomData,
206            }
207        }
208    }
209
210    impl<F, R, G, S, E> Future for MakeFuture<F, R, G>
211    where
212        F: Future<Output = Result<S, E>>,
213        S: tower_service::Service<R>,
214        G: GetSpan<R> + Clone,
215    {
216        type Output = Result<Service<S, R, G>, E>;
217
218        fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
219            let this = self.project();
220            let inner = futures::ready!(this.inner.poll(cx));
221            let get_span = this.get_span.take().expect("polled after ready");
222            Poll::Ready(inner.map(|inner| Service {
223                inner,
224                get_span,
225                _p: PhantomData,
226            }))
227        }
228    }
229}
230
231// === impl Service ===
232
233impl<S, R, G> tower_service::Service<R> for Service<S, R, G>
234where
235    S: tower_service::Service<R>,
236    G: GetSpan<R> + Clone,
237{
238    type Response = S::Response;
239    type Error = S::Error;
240    type Future = tracing::instrument::Instrumented<S::Future>;
241
242    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
243        self.inner.poll_ready(cx)
244    }
245
246    fn call(&mut self, request: R) -> Self::Future {
247        let span = self.get_span.span_for(&request);
248        let _enter = span.enter();
249        self.inner.call(request).instrument(span.clone())
250    }
251}
252
253impl<S, R, G> Clone for Service<S, R, G>
254where
255    S: tower_service::Service<R> + Clone,
256    G: GetSpan<R> + Clone,
257{
258    fn clone(&self) -> Self {
259        Service {
260            get_span: self.get_span.clone(),
261            inner: self.inner.clone(),
262            _p: PhantomData,
263        }
264    }
265}
266
267impl<S, R, G> Service<S, R, G>
268where
269    S: tower_service::Service<R>,
270    G: GetSpan<R> + Clone,
271{
272    pub fn new(inner: S, get_span: G) -> Self {
273        Service {
274            get_span,
275            inner,
276            _p: PhantomData,
277        }
278    }
279}