1 use std::any::{type_name, TypeId}; 2 use std::fmt; 3 use std::marker::PhantomData; 4 use tracing::{span, Dispatch, Metadata, Subscriber}; 5 use tracing_subscriber::fmt::format::{DefaultFields, FormatFields}; 6 use tracing_subscriber::{ 7 fmt::FormattedFields, 8 layer::{self, Layer}, 9 registry::LookupSpan, 10 }; 11 12 /// A subscriber [`Layer`] that enables capturing [`SpanTrace`]s. 13 /// 14 /// Optionally, this type may be constructed with a [field formatter] to use 15 /// when formatting the fields of each span in a trace. When no formatter is 16 /// provided, the [default format] is used instead. 17 /// 18 /// [`Layer`]: tracing_subscriber::layer::Layer 19 /// [`SpanTrace`]: super::SpanTrace 20 /// [field formatter]: tracing_subscriber::fmt::FormatFields 21 /// [default format]: tracing_subscriber::fmt::format::DefaultFields 22 pub struct ErrorLayer<S, F = DefaultFields> { 23 format: F, 24 25 get_context: WithContext, 26 _subscriber: PhantomData<fn(S)>, 27 } 28 29 // this function "remembers" the types of the subscriber and the formatter, 30 // so that we can downcast to something aware of them without knowing those 31 // types at the callsite. 32 pub(crate) struct WithContext( 33 fn(&Dispatch, &span::Id, f: &mut dyn FnMut(&'static Metadata<'static>, &str) -> bool), 34 ); 35 36 impl<S, F> Layer<S> for ErrorLayer<S, F> 37 where 38 S: Subscriber + for<'span> LookupSpan<'span>, 39 F: for<'writer> FormatFields<'writer> + 'static, 40 { 41 /// Notifies this layer that a new span was constructed with the given 42 /// `Attributes` and `Id`. on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>)43 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) { 44 let span = ctx.span(id).expect("span must already exist!"); 45 if span.extensions().get::<FormattedFields<F>>().is_some() { 46 return; 47 } 48 let mut fields = FormattedFields::<F>::new(String::new()); 49 if self.format.format_fields(fields.as_writer(), attrs).is_ok() { 50 span.extensions_mut().insert(fields); 51 } 52 } 53 downcast_raw(&self, id: TypeId) -> Option<*const ()>54 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { 55 match id { 56 id if id == TypeId::of::<Self>() => Some(self as *const _ as *const ()), 57 id if id == TypeId::of::<WithContext>() => { 58 Some(&self.get_context as *const _ as *const ()) 59 } 60 _ => None, 61 } 62 } 63 } 64 65 impl<S, F> ErrorLayer<S, F> 66 where 67 F: for<'writer> FormatFields<'writer> + 'static, 68 S: Subscriber + for<'span> LookupSpan<'span>, 69 { 70 /// Returns a new `ErrorLayer` with the provided [field formatter]. 71 /// 72 /// [field formatter]: tracing_subscriber::fmt::FormatFields new(format: F) -> Self73 pub fn new(format: F) -> Self { 74 Self { 75 format, 76 get_context: WithContext(Self::get_context), 77 _subscriber: PhantomData, 78 } 79 } 80 get_context( dispatch: &Dispatch, id: &span::Id, f: &mut dyn FnMut(&'static Metadata<'static>, &str) -> bool, )81 fn get_context( 82 dispatch: &Dispatch, 83 id: &span::Id, 84 f: &mut dyn FnMut(&'static Metadata<'static>, &str) -> bool, 85 ) { 86 let subscriber = dispatch 87 .downcast_ref::<S>() 88 .expect("subscriber should downcast to expected type; this is a bug!"); 89 let span = subscriber 90 .span(id) 91 .expect("registry should have a span for the current ID"); 92 for span in span.scope() { 93 let cont = if let Some(fields) = span.extensions().get::<FormattedFields<F>>() { 94 f(span.metadata(), fields.fields.as_str()) 95 } else { 96 f(span.metadata(), "") 97 }; 98 if !cont { 99 break; 100 } 101 } 102 } 103 } 104 105 impl WithContext { with_context<'a>( &self, dispatch: &'a Dispatch, id: &span::Id, mut f: impl FnMut(&'static Metadata<'static>, &str) -> bool, )106 pub(crate) fn with_context<'a>( 107 &self, 108 dispatch: &'a Dispatch, 109 id: &span::Id, 110 mut f: impl FnMut(&'static Metadata<'static>, &str) -> bool, 111 ) { 112 (self.0)(dispatch, id, &mut f) 113 } 114 } 115 116 impl<S> Default for ErrorLayer<S> 117 where 118 S: Subscriber + for<'span> LookupSpan<'span>, 119 { default() -> Self120 fn default() -> Self { 121 Self::new(DefaultFields::default()) 122 } 123 } 124 125 impl<S, F: fmt::Debug> fmt::Debug for ErrorLayer<S, F> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 127 f.debug_struct("ErrorLayer") 128 .field("format", &self.format) 129 .field("subscriber", &format_args!("{}", type_name::<S>())) 130 .finish() 131 } 132 } 133