• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Middleware which instruments each request passing through a service with a new span.
2 use super::GetSpan;
3 use futures::future::Future;
4 use std::marker::PhantomData;
5 use std::pin::Pin;
6 use std::task::{Context, Poll};
7 use tracing::Instrument;
8 
9 #[derive(Debug)]
10 pub struct Service<S, R, G = fn(&R) -> tracing::Span>
11 where
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")))]
22 pub use self::layer::*;
23 
24 #[cfg(feature = "tower-layer")]
25 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
26 mod 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 
layer<R, G>(get_span: G) -> Layer<R, G> where G: GetSpan<R> + Clone,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 Layer ===
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 
layer(&self, service: S) -> Self::Service56         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     {
clone(&self) -> Self65         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")))]
76 pub use self::make::MakeService;
77 
78 #[cfg(feature = "tower-make")]
79 #[cfg_attr(docsrs, doc(cfg(feature = "tower-make")))]
80 pub 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")))]
layer<R, T, G>(get_span: G) -> MakeLayer<R, T, G> where G: GetSpan<R> + Clone,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 
layer(&self, inner: S) -> Self::Service135         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     {
clone(&self) -> Self146         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 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>165         fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
166             self.inner.poll_ready(cx)
167         }
168 
call(&mut self, target: T) -> Self::Future169         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     {
new<T>(inner: S, get_span: G) -> Self where S: tower_make::MakeService<T, R>,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     {
clone(&self) -> Self201         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 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>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 
233 impl<S, R, G> tower_service::Service<R> for Service<S, R, G>
234 where
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 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>242     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
243         self.inner.poll_ready(cx)
244     }
245 
call(&mut self, request: R) -> Self::Future246     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 
253 impl<S, R, G> Clone for Service<S, R, G>
254 where
255     S: tower_service::Service<R> + Clone,
256     G: GetSpan<R> + Clone,
257 {
clone(&self) -> Self258     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 
267 impl<S, R, G> Service<S, R, G>
268 where
269     S: tower_service::Service<R>,
270     G: GetSpan<R> + Clone,
271 {
new(inner: S, get_span: G) -> Self272     pub fn new(inner: S, get_span: G) -> Self {
273         Service {
274             get_span,
275             inner,
276             _p: PhantomData,
277         }
278     }
279 }
280