• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Middleware which instruments a service with a span entered when that service
2 //! is called.
3 use crate::GetSpan;
4 use std::future::Future;
5 use std::marker::PhantomData;
6 use std::pin::Pin;
7 use std::task::{Context, Poll};
8 
9 #[derive(Debug)]
10 pub 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")))]
17 pub use self::layer::*;
18 
19 #[cfg(feature = "tower-util")]
20 #[cfg_attr(docsrs, doc(cfg(feature = "tower-util")))]
21 pub use self::make::MakeService;
22 
23 #[cfg(feature = "tower-layer")]
24 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
25 mod layer {
26     use super::*;
27 
28     #[derive(Debug)]
29     pub struct Layer<S, R, G = fn(&S) -> tracing::Span>
30     where
31         G: GetSpan<S>,
32         S: tower_service::Service<R>,
33     {
34         get_span: G,
35         _p: PhantomData<fn(S, R)>,
36     }
37 
layer<S, R, G>(get_span: G) -> Layer<S, R, G> where G: GetSpan<S>, S: tower_service::Service<R>,38     pub fn layer<S, R, G>(get_span: G) -> Layer<S, R, G>
39     where
40         G: GetSpan<S>,
41         S: tower_service::Service<R>,
42     {
43         Layer {
44             get_span,
45             _p: PhantomData,
46         }
47     }
48 
49     // === impl Layer ===
50 
51     impl<S, R, G> tower_layer::Layer<S> for Layer<S, R, G>
52     where
53         G: GetSpan<S>,
54         S: tower_service::Service<R>,
55     {
56         type Service = Service<S>;
57 
layer(&self, inner: S) -> Self::Service58         fn layer(&self, inner: S) -> Self::Service {
59             let span = self.get_span.span_for(&inner);
60             Service { inner, span }
61         }
62     }
63 
64     impl<S, R, G> Clone for Layer<S, R, G>
65     where
66         G: GetSpan<S> + Clone,
67         S: tower_service::Service<R>,
68     {
clone(&self) -> Self69         fn clone(&self) -> Self {
70             Self {
71                 get_span: self.get_span.clone(),
72                 _p: PhantomData,
73             }
74         }
75     }
76 }
77 
78 #[cfg(feature = "tower-layer")]
79 #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
80 pub mod make {
81     use super::*;
82     use pin_project_lite::pin_project;
83 
84     #[derive(Debug)]
85     pub struct MakeService<M, T, R, G = fn(&T) -> tracing::Span>
86     where
87         G: GetSpan<T>,
88     {
89         get_span: G,
90         inner: M,
91         _p: PhantomData<fn(T, R)>,
92     }
93 
94     pin_project! {
95         #[derive(Debug)]
96         pub struct MakeFuture<F> {
97             #[pin]
98             inner: F,
99             span: Option<tracing::Span>,
100         }
101     }
102 
103     #[derive(Debug)]
104     pub struct MakeLayer<T, R, G = fn(&T) -> tracing::Span>
105     where
106         G: GetSpan<T> + Clone,
107     {
108         get_span: G,
109         _p: PhantomData<fn(T, R)>,
110     }
111 
112     #[cfg(feature = "tower-layer")]
113     #[cfg_attr(docsrs, doc(cfg(feature = "tower-layer")))]
layer<T, R, G>(get_span: G) -> MakeLayer<T, R, G> where G: GetSpan<T> + Clone,114     pub fn layer<T, R, G>(get_span: G) -> MakeLayer<T, R, G>
115     where
116         G: GetSpan<T> + 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<M, T, R, G> tower_layer::Layer<M> for MakeLayer<T, R, G>
129     where
130         M: tower_make::MakeService<T, R>,
131         G: GetSpan<T> + Clone,
132     {
133         type Service = MakeService<M, T, R, G>;
134 
layer(&self, inner: M) -> Self::Service135         fn layer(&self, inner: M) -> 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<T, R, G> Clone for MakeLayer<T, R, G>
143     where
144         G: GetSpan<T> + 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<M, T, R, G> tower_service::Service<T> for MakeService<M, T, R, G>
157     where
158         M: tower_make::MakeService<T, R>,
159         G: GetSpan<T>,
160     {
161         type Response = Service<M::Service>;
162         type Error = M::MakeError;
163         type Future = MakeFuture<M::Future>;
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 span = self.get_span.span_for(&target);
171             let inner = self.inner.make_service(target);
172             MakeFuture {
173                 span: Some(span),
174                 inner,
175             }
176         }
177     }
178 
179     impl<F, T, E> Future for MakeFuture<F>
180     where
181         F: Future<Output = Result<T, E>>,
182     {
183         type Output = Result<Service<T>, E>;
184 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>185         fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
186             let this = self.project();
187             let inner = {
188                 let _guard = this.span.as_ref().map(tracing::Span::enter);
189                 futures::ready!(this.inner.poll(cx))
190             };
191 
192             let span = this.span.take().expect("polled after ready");
193             Poll::Ready(inner.map(|svc| Service::new(svc, span)))
194         }
195     }
196 
197     impl<M, T, R, G> MakeService<M, T, R, G>
198     where
199         G: GetSpan<T>,
200     {
new(inner: M, get_span: G) -> Self201         pub fn new(inner: M, get_span: G) -> Self {
202             MakeService {
203                 get_span,
204                 inner,
205                 _p: PhantomData,
206             }
207         }
208     }
209 
210     impl<M, T, R, G> Clone for MakeService<M, T, R, G>
211     where
212         M: Clone,
213         G: GetSpan<T> + Clone,
214     {
clone(&self) -> Self215         fn clone(&self) -> Self {
216             Self::new(self.inner.clone(), self.get_span.clone())
217         }
218     }
219 }
220 
221 // === impl Service ===
222 
223 impl<S> Service<S> {
new(inner: S, span: tracing::Span) -> Self224     pub fn new(inner: S, span: tracing::Span) -> Self {
225         Self { inner, span }
226     }
227 }
228 
229 impl<S, R> tower_service::Service<R> for Service<S>
230 where
231     S: tower_service::Service<R>,
232 {
233     type Response = S::Response;
234     type Error = S::Error;
235     type Future = S::Future;
236 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>237     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
238         let _enter = self.span.enter();
239         self.inner.poll_ready(cx)
240     }
241 
call(&mut self, request: R) -> Self::Future242     fn call(&mut self, request: R) -> Self::Future {
243         let _enter = self.span.enter();
244         self.inner.call(request)
245     }
246 }
247 
248 impl<S> Clone for Service<S>
249 where
250     S: Clone,
251 {
clone(&self) -> Self252     fn clone(&self) -> Self {
253         Service {
254             span: self.span.clone(),
255             inner: self.inner.clone(),
256         }
257     }
258 }
259