1 #![warn( 2 missing_debug_implementations, 3 // missing_docs, // TODO: add documentation! 4 rust_2018_idioms, 5 unreachable_pub, 6 bad_style, 7 const_err, 8 dead_code, 9 improper_ctypes, 10 legacy_directory_ownership, 11 non_shorthand_field_patterns, 12 no_mangle_generic_items, 13 overflowing_literals, 14 path_statements, 15 patterns_in_fns_without_body, 16 plugin_as_library, 17 private_in_public, 18 safe_extern_statics, 19 unconditional_recursion, 20 21 unused, 22 unused_allocation, 23 unused_comparisons, 24 unused_parens, 25 while_true 26 )] 27 28 use std::fmt; 29 use tower_service::Service; 30 use tracing::Level; 31 32 pub mod request_span; 33 pub mod service_span; 34 35 #[cfg(feature = "http")] 36 pub mod http; 37 38 pub type InstrumentedService<S, R> = service_span::Service<request_span::Service<S, R>>; 39 40 pub trait InstrumentableService<Request> 41 where 42 Self: Service<Request> + Sized, 43 { instrument<G>(self, svc_span: G) -> InstrumentedService<Self, Request> where G: GetSpan<Self>, Request: fmt::Debug,44 fn instrument<G>(self, svc_span: G) -> InstrumentedService<Self, Request> 45 where 46 G: GetSpan<Self>, 47 Request: fmt::Debug, 48 { 49 let req_span: fn(&Request) -> tracing::Span = 50 |request| tracing::span!(Level::TRACE, "request", ?request); 51 let svc_span = svc_span.span_for(&self); 52 self.trace_requests(req_span).trace_service(svc_span) 53 } 54 trace_requests<G>(self, get_span: G) -> request_span::Service<Self, Request, G> where G: GetSpan<Request> + Clone,55 fn trace_requests<G>(self, get_span: G) -> request_span::Service<Self, Request, G> 56 where 57 G: GetSpan<Request> + Clone, 58 { 59 request_span::Service::new(self, get_span) 60 } 61 trace_service<G>(self, get_span: G) -> service_span::Service<Self> where G: GetSpan<Self>,62 fn trace_service<G>(self, get_span: G) -> service_span::Service<Self> 63 where 64 G: GetSpan<Self>, 65 { 66 let span = get_span.span_for(&self); 67 service_span::Service::new(self, span) 68 } 69 } 70 71 #[cfg(feature = "tower-util")] 72 pub trait InstrumentMake<T, R> 73 where 74 Self: tower_util::MakeService<T, R> + Sized, 75 { with_traced_service<G>(self, get_span: G) -> service_span::MakeService<Self, T, R, G> where G: GetSpan<T>,76 fn with_traced_service<G>(self, get_span: G) -> service_span::MakeService<Self, T, R, G> 77 where 78 G: GetSpan<T>, 79 { 80 service_span::MakeService::new(self, get_span) 81 } 82 with_traced_requests<G>(self, get_span: G) -> request_span::MakeService<Self, R, G> where G: GetSpan<R> + Clone,83 fn with_traced_requests<G>(self, get_span: G) -> request_span::MakeService<Self, R, G> 84 where 85 G: GetSpan<R> + Clone, 86 { 87 request_span::MakeService::new(self, get_span) 88 } 89 } 90 91 impl<S, R> InstrumentableService<R> for S where S: Service<R> + Sized {} 92 93 #[cfg(feature = "tower-util")] 94 impl<M, T, R> InstrumentMake<T, R> for M where M: tower_util::MakeService<T, R> {} 95 96 pub trait GetSpan<T>: crate::sealed::Sealed<T> { span_for(&self, target: &T) -> tracing::Span97 fn span_for(&self, target: &T) -> tracing::Span; 98 } 99 100 impl<T, F> crate::sealed::Sealed<T> for F where F: Fn(&T) -> tracing::Span {} 101 102 impl<T, F> GetSpan<T> for F 103 where 104 F: Fn(&T) -> tracing::Span, 105 { 106 #[inline] span_for(&self, target: &T) -> tracing::Span107 fn span_for(&self, target: &T) -> tracing::Span { 108 (self)(target) 109 } 110 } 111 112 impl<T> crate::sealed::Sealed<T> for tracing::Span {} 113 114 impl<T> GetSpan<T> for tracing::Span { 115 #[inline] span_for(&self, _: &T) -> tracing::Span116 fn span_for(&self, _: &T) -> tracing::Span { 117 self.clone() 118 } 119 } 120 121 mod sealed { 122 pub trait Sealed<T = ()> {} 123 } 124