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

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