1 use tracing_core::{metadata::Metadata, span, Dispatch, Event, Interest, LevelFilter, Subscriber}; 2 3 use crate::{ 4 filter, 5 layer::{Context, Layer}, 6 registry::LookupSpan, 7 }; 8 #[cfg(all(feature = "registry", feature = "std"))] 9 use crate::{filter::FilterId, registry::Registry}; 10 use core::{ 11 any::{Any, TypeId}, 12 cmp, fmt, 13 marker::PhantomData, 14 }; 15 16 /// A [`Subscriber`] composed of a `Subscriber` wrapped by one or more 17 /// [`Layer`]s. 18 /// 19 /// [`Layer`]: crate::Layer 20 /// [`Subscriber`]: tracing_core::Subscriber 21 #[derive(Clone)] 22 pub struct Layered<L, I, S = I> { 23 /// The layer. 24 layer: L, 25 26 /// The inner value that `self.layer` was layered onto. 27 /// 28 /// If this is also a `Layer`, then this `Layered` will implement `Layer`. 29 /// If this is a `Subscriber`, then this `Layered` will implement 30 /// `Subscriber` instead. 31 inner: I, 32 33 // These booleans are used to determine how to combine `Interest`s and max 34 // level hints when per-layer filters are in use. 35 /// Is `self.inner` a `Registry`? 36 /// 37 /// If so, when combining `Interest`s, we want to "bubble up" its 38 /// `Interest`. 39 inner_is_registry: bool, 40 41 /// Does `self.layer` have per-layer filters? 42 /// 43 /// This will be true if: 44 /// - `self.inner` is a `Filtered`. 45 /// - `self.inner` is a tree of `Layered`s where _all_ arms of those 46 /// `Layered`s have per-layer filters. 47 /// 48 /// Otherwise, if it's a `Layered` with one per-layer filter in one branch, 49 /// but a non-per-layer-filtered layer in the other branch, this will be 50 /// _false_, because the `Layered` is already handling the combining of 51 /// per-layer filter `Interest`s and max level hints with its non-filtered 52 /// `Layer`. 53 has_layer_filter: bool, 54 55 /// Does `self.inner` have per-layer filters? 56 /// 57 /// This is determined according to the same rules as 58 /// `has_layer_filter` above. 59 inner_has_layer_filter: bool, 60 _s: PhantomData<fn(S)>, 61 } 62 63 // === impl Layered === 64 65 impl<L, S> Layered<L, S> 66 where 67 L: Layer<S>, 68 S: Subscriber, 69 { 70 /// Returns `true` if this [`Subscriber`] is the same type as `T`. is<T: Any>(&self) -> bool71 pub fn is<T: Any>(&self) -> bool { 72 self.downcast_ref::<T>().is_some() 73 } 74 75 /// Returns some reference to this [`Subscriber`] value if it is of type `T`, 76 /// or `None` if it isn't. downcast_ref<T: Any>(&self) -> Option<&T>77 pub fn downcast_ref<T: Any>(&self) -> Option<&T> { 78 unsafe { 79 let raw = self.downcast_raw(TypeId::of::<T>())?; 80 if raw.is_null() { 81 None 82 } else { 83 Some(&*(raw as *const T)) 84 } 85 } 86 } 87 } 88 89 impl<L, S> Subscriber for Layered<L, S> 90 where 91 L: Layer<S>, 92 S: Subscriber, 93 { register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest94 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { 95 self.pick_interest(self.layer.register_callsite(metadata), || { 96 self.inner.register_callsite(metadata) 97 }) 98 } 99 enabled(&self, metadata: &Metadata<'_>) -> bool100 fn enabled(&self, metadata: &Metadata<'_>) -> bool { 101 if self.layer.enabled(metadata, self.ctx()) { 102 // if the outer layer enables the callsite metadata, ask the subscriber. 103 self.inner.enabled(metadata) 104 } else { 105 // otherwise, the callsite is disabled by the layer 106 107 // If per-layer filters are in use, and we are short-circuiting 108 // (rather than calling into the inner type), clear the current 109 // per-layer filter `enabled` state. 110 #[cfg(feature = "registry")] 111 filter::FilterState::clear_enabled(); 112 113 false 114 } 115 } 116 max_level_hint(&self) -> Option<LevelFilter>117 fn max_level_hint(&self) -> Option<LevelFilter> { 118 self.pick_level_hint( 119 self.layer.max_level_hint(), 120 self.inner.max_level_hint(), 121 super::subscriber_is_none(&self.inner), 122 ) 123 } 124 new_span(&self, span: &span::Attributes<'_>) -> span::Id125 fn new_span(&self, span: &span::Attributes<'_>) -> span::Id { 126 let id = self.inner.new_span(span); 127 self.layer.on_new_span(span, &id, self.ctx()); 128 id 129 } 130 record(&self, span: &span::Id, values: &span::Record<'_>)131 fn record(&self, span: &span::Id, values: &span::Record<'_>) { 132 self.inner.record(span, values); 133 self.layer.on_record(span, values, self.ctx()); 134 } 135 record_follows_from(&self, span: &span::Id, follows: &span::Id)136 fn record_follows_from(&self, span: &span::Id, follows: &span::Id) { 137 self.inner.record_follows_from(span, follows); 138 self.layer.on_follows_from(span, follows, self.ctx()); 139 } 140 event_enabled(&self, event: &Event<'_>) -> bool141 fn event_enabled(&self, event: &Event<'_>) -> bool { 142 if self.layer.event_enabled(event, self.ctx()) { 143 // if the outer layer enables the event, ask the inner subscriber. 144 self.inner.event_enabled(event) 145 } else { 146 // otherwise, the event is disabled by this layer 147 false 148 } 149 } 150 event(&self, event: &Event<'_>)151 fn event(&self, event: &Event<'_>) { 152 self.inner.event(event); 153 self.layer.on_event(event, self.ctx()); 154 } 155 enter(&self, span: &span::Id)156 fn enter(&self, span: &span::Id) { 157 self.inner.enter(span); 158 self.layer.on_enter(span, self.ctx()); 159 } 160 exit(&self, span: &span::Id)161 fn exit(&self, span: &span::Id) { 162 self.inner.exit(span); 163 self.layer.on_exit(span, self.ctx()); 164 } 165 clone_span(&self, old: &span::Id) -> span::Id166 fn clone_span(&self, old: &span::Id) -> span::Id { 167 let new = self.inner.clone_span(old); 168 if &new != old { 169 self.layer.on_id_change(old, &new, self.ctx()) 170 }; 171 new 172 } 173 174 #[inline] drop_span(&self, id: span::Id)175 fn drop_span(&self, id: span::Id) { 176 self.try_close(id); 177 } 178 try_close(&self, id: span::Id) -> bool179 fn try_close(&self, id: span::Id) -> bool { 180 #[cfg(all(feature = "registry", feature = "std"))] 181 let subscriber = &self.inner as &dyn Subscriber; 182 #[cfg(all(feature = "registry", feature = "std"))] 183 let mut guard = subscriber 184 .downcast_ref::<Registry>() 185 .map(|registry| registry.start_close(id.clone())); 186 if self.inner.try_close(id.clone()) { 187 // If we have a registry's close guard, indicate that the span is 188 // closing. 189 #[cfg(all(feature = "registry", feature = "std"))] 190 { 191 if let Some(g) = guard.as_mut() { 192 g.set_closing() 193 }; 194 } 195 196 self.layer.on_close(id, self.ctx()); 197 true 198 } else { 199 false 200 } 201 } 202 203 #[inline] current_span(&self) -> span::Current204 fn current_span(&self) -> span::Current { 205 self.inner.current_span() 206 } 207 208 #[doc(hidden)] downcast_raw(&self, id: TypeId) -> Option<*const ()>209 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { 210 // Unlike the implementation of `Layer` for `Layered`, we don't have to 211 // handle the "magic PLF downcast marker" here. If a `Layered` 212 // implements `Subscriber`, we already know that the `inner` branch is 213 // going to contain something that doesn't have per-layer filters (the 214 // actual root `Subscriber`). Thus, a `Layered` that implements 215 // `Subscriber` will always be propagating the root subscriber's 216 // `Interest`/level hint, even if it includes a `Layer` that has 217 // per-layer filters, because it will only ever contain layers where 218 // _one_ child has per-layer filters. 219 // 220 // The complex per-layer filter detection logic is only relevant to 221 // *trees* of layers, which involve the `Layer` implementation for 222 // `Layered`, not *lists* of layers, where every `Layered` implements 223 // `Subscriber`. Of course, a linked list can be thought of as a 224 // degenerate tree...but luckily, we are able to make a type-level 225 // distinction between individual `Layered`s that are definitely 226 // list-shaped (their inner child implements `Subscriber`), and 227 // `Layered`s that might be tree-shaped (the inner child is also a 228 // `Layer`). 229 230 // If downcasting to `Self`, return a pointer to `self`. 231 if id == TypeId::of::<Self>() { 232 return Some(self as *const _ as *const ()); 233 } 234 235 self.layer 236 .downcast_raw(id) 237 .or_else(|| self.inner.downcast_raw(id)) 238 } 239 } 240 241 impl<S, A, B> Layer<S> for Layered<A, B, S> 242 where 243 A: Layer<S>, 244 B: Layer<S>, 245 S: Subscriber, 246 { on_register_dispatch(&self, subscriber: &Dispatch)247 fn on_register_dispatch(&self, subscriber: &Dispatch) { 248 self.layer.on_register_dispatch(subscriber); 249 self.inner.on_register_dispatch(subscriber); 250 } 251 on_layer(&mut self, subscriber: &mut S)252 fn on_layer(&mut self, subscriber: &mut S) { 253 self.layer.on_layer(subscriber); 254 self.inner.on_layer(subscriber); 255 } 256 register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest257 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest { 258 self.pick_interest(self.layer.register_callsite(metadata), || { 259 self.inner.register_callsite(metadata) 260 }) 261 } 262 enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool263 fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool { 264 if self.layer.enabled(metadata, ctx.clone()) { 265 // if the outer subscriber enables the callsite metadata, ask the inner layer. 266 self.inner.enabled(metadata, ctx) 267 } else { 268 // otherwise, the callsite is disabled by this layer 269 false 270 } 271 } 272 max_level_hint(&self) -> Option<LevelFilter>273 fn max_level_hint(&self) -> Option<LevelFilter> { 274 self.pick_level_hint( 275 self.layer.max_level_hint(), 276 self.inner.max_level_hint(), 277 super::layer_is_none(&self.inner), 278 ) 279 } 280 281 #[inline] on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>)282 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) { 283 self.inner.on_new_span(attrs, id, ctx.clone()); 284 self.layer.on_new_span(attrs, id, ctx); 285 } 286 287 #[inline] on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>)288 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) { 289 self.inner.on_record(span, values, ctx.clone()); 290 self.layer.on_record(span, values, ctx); 291 } 292 293 #[inline] on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>)294 fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) { 295 self.inner.on_follows_from(span, follows, ctx.clone()); 296 self.layer.on_follows_from(span, follows, ctx); 297 } 298 299 #[inline] event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool300 fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool { 301 if self.layer.event_enabled(event, ctx.clone()) { 302 // if the outer layer enables the event, ask the inner subscriber. 303 self.inner.event_enabled(event, ctx) 304 } else { 305 // otherwise, the event is disabled by this layer 306 false 307 } 308 } 309 310 #[inline] on_event(&self, event: &Event<'_>, ctx: Context<'_, S>)311 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) { 312 self.inner.on_event(event, ctx.clone()); 313 self.layer.on_event(event, ctx); 314 } 315 316 #[inline] on_enter(&self, id: &span::Id, ctx: Context<'_, S>)317 fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) { 318 self.inner.on_enter(id, ctx.clone()); 319 self.layer.on_enter(id, ctx); 320 } 321 322 #[inline] on_exit(&self, id: &span::Id, ctx: Context<'_, S>)323 fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) { 324 self.inner.on_exit(id, ctx.clone()); 325 self.layer.on_exit(id, ctx); 326 } 327 328 #[inline] on_close(&self, id: span::Id, ctx: Context<'_, S>)329 fn on_close(&self, id: span::Id, ctx: Context<'_, S>) { 330 self.inner.on_close(id.clone(), ctx.clone()); 331 self.layer.on_close(id, ctx); 332 } 333 334 #[inline] on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>)335 fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) { 336 self.inner.on_id_change(old, new, ctx.clone()); 337 self.layer.on_id_change(old, new, ctx); 338 } 339 340 #[doc(hidden)] downcast_raw(&self, id: TypeId) -> Option<*const ()>341 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> { 342 match id { 343 // If downcasting to `Self`, return a pointer to `self`. 344 id if id == TypeId::of::<Self>() => Some(self as *const _ as *const ()), 345 346 // Oh, we're looking for per-layer filters! 347 // 348 // This should only happen if we are inside of another `Layered`, 349 // and it's trying to determine how it should combine `Interest`s 350 // and max level hints. 351 // 352 // In that case, this `Layered` should be considered to be 353 // "per-layer filtered" if *both* the outer layer and the inner 354 // layer/subscriber have per-layer filters. Otherwise, this `Layered 355 // should *not* be considered per-layer filtered (even if one or the 356 // other has per layer filters). If only one `Layer` is per-layer 357 // filtered, *this* `Layered` will handle aggregating the `Interest` 358 // and level hints on behalf of its children, returning the 359 // aggregate (which is the value from the &non-per-layer-filtered* 360 // child). 361 // 362 // Yes, this rule *is* slightly counter-intuitive, but it's 363 // necessary due to a weird edge case that can occur when two 364 // `Layered`s where one side is per-layer filtered and the other 365 // isn't are `Layered` together to form a tree. If we didn't have 366 // this rule, we would actually end up *ignoring* `Interest`s from 367 // the non-per-layer-filtered layers, since both branches would 368 // claim to have PLF. 369 // 370 // If you don't understand this...that's fine, just don't mess with 371 // it. :) 372 id if filter::is_plf_downcast_marker(id) => { 373 self.layer.downcast_raw(id).and(self.inner.downcast_raw(id)) 374 } 375 376 // Otherwise, try to downcast both branches normally... 377 _ => self 378 .layer 379 .downcast_raw(id) 380 .or_else(|| self.inner.downcast_raw(id)), 381 } 382 } 383 } 384 385 impl<'a, L, S> LookupSpan<'a> for Layered<L, S> 386 where 387 S: Subscriber + LookupSpan<'a>, 388 { 389 type Data = S::Data; 390 span_data(&'a self, id: &span::Id) -> Option<Self::Data>391 fn span_data(&'a self, id: &span::Id) -> Option<Self::Data> { 392 self.inner.span_data(id) 393 } 394 395 #[cfg(all(feature = "registry", feature = "std"))] register_filter(&mut self) -> FilterId396 fn register_filter(&mut self) -> FilterId { 397 self.inner.register_filter() 398 } 399 } 400 401 impl<L, S> Layered<L, S> 402 where 403 S: Subscriber, 404 { ctx(&self) -> Context<'_, S>405 fn ctx(&self) -> Context<'_, S> { 406 Context::new(&self.inner) 407 } 408 } 409 410 impl<A, B, S> Layered<A, B, S> 411 where 412 A: Layer<S>, 413 S: Subscriber, 414 { new(layer: A, inner: B, inner_has_layer_filter: bool) -> Self415 pub(super) fn new(layer: A, inner: B, inner_has_layer_filter: bool) -> Self { 416 #[cfg(all(feature = "registry", feature = "std"))] 417 let inner_is_registry = TypeId::of::<S>() == TypeId::of::<crate::registry::Registry>(); 418 419 #[cfg(not(all(feature = "registry", feature = "std")))] 420 let inner_is_registry = false; 421 422 let inner_has_layer_filter = inner_has_layer_filter || inner_is_registry; 423 let has_layer_filter = filter::layer_has_plf(&layer); 424 Self { 425 layer, 426 inner, 427 has_layer_filter, 428 inner_has_layer_filter, 429 inner_is_registry, 430 _s: PhantomData, 431 } 432 } 433 pick_interest(&self, outer: Interest, inner: impl FnOnce() -> Interest) -> Interest434 fn pick_interest(&self, outer: Interest, inner: impl FnOnce() -> Interest) -> Interest { 435 if self.has_layer_filter { 436 return inner(); 437 } 438 439 // If the outer layer has disabled the callsite, return now so that 440 // the inner layer/subscriber doesn't get its hopes up. 441 if outer.is_never() { 442 // If per-layer filters are in use, and we are short-circuiting 443 // (rather than calling into the inner type), clear the current 444 // per-layer filter interest state. 445 #[cfg(feature = "registry")] 446 filter::FilterState::take_interest(); 447 448 return outer; 449 } 450 451 // The `inner` closure will call `inner.register_callsite()`. We do this 452 // before the `if` statement to ensure that the inner subscriber is 453 // informed that the callsite exists regardless of the outer layer's 454 // filtering decision. 455 let inner = inner(); 456 if outer.is_sometimes() { 457 // if this interest is "sometimes", return "sometimes" to ensure that 458 // filters are reevaluated. 459 return outer; 460 } 461 462 // If there is a per-layer filter in the `inner` stack, and it returns 463 // `never`, change the interest to `sometimes`, because the `outer` 464 // layer didn't return `never`. This means that _some_ layer still wants 465 // to see that callsite, even though the inner stack's per-layer filter 466 // didn't want it. Therefore, returning `sometimes` will ensure 467 // `enabled` is called so that the per-layer filter can skip that 468 // span/event, while the `outer` layer still gets to see it. 469 if inner.is_never() && self.inner_has_layer_filter { 470 return Interest::sometimes(); 471 } 472 473 // otherwise, allow the inner subscriber or subscriber to weigh in. 474 inner 475 } 476 pick_level_hint( &self, outer_hint: Option<LevelFilter>, inner_hint: Option<LevelFilter>, inner_is_none: bool, ) -> Option<LevelFilter>477 fn pick_level_hint( 478 &self, 479 outer_hint: Option<LevelFilter>, 480 inner_hint: Option<LevelFilter>, 481 inner_is_none: bool, 482 ) -> Option<LevelFilter> { 483 if self.inner_is_registry { 484 return outer_hint; 485 } 486 487 if self.has_layer_filter && self.inner_has_layer_filter { 488 return Some(cmp::max(outer_hint?, inner_hint?)); 489 } 490 491 if self.has_layer_filter && inner_hint.is_none() { 492 return None; 493 } 494 495 if self.inner_has_layer_filter && outer_hint.is_none() { 496 return None; 497 } 498 499 // If the layer is `Option::None`, then we 500 // want to short-circuit the layer underneath, if it 501 // returns `None`, to override the `None` layer returning 502 // `Some(OFF)`, which should ONLY apply when there are 503 // no other layers that return `None`. Note this 504 // `None` does not == `Some(TRACE)`, it means 505 // something more like: "whatever all the other 506 // layers agree on, default to `TRACE` if none 507 // have an opinion". We also choose do this AFTER 508 // we check for per-layer filters, which 509 // have their own logic. 510 // 511 // Also note that this does come at some perf cost, but 512 // this function is only called on initialization and 513 // subscriber reloading. 514 if super::layer_is_none(&self.layer) { 515 return cmp::max(outer_hint, Some(inner_hint?)); 516 } 517 518 // Similarly, if the layer on the inside is `None` and it returned an 519 // `Off` hint, we want to override that with the outer hint. 520 if inner_is_none && inner_hint == Some(LevelFilter::OFF) { 521 return outer_hint; 522 } 523 524 cmp::max(outer_hint, inner_hint) 525 } 526 } 527 528 impl<A, B, S> fmt::Debug for Layered<A, B, S> 529 where 530 A: fmt::Debug, 531 B: fmt::Debug, 532 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result533 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 534 #[cfg(all(feature = "registry", feature = "std"))] 535 let alt = f.alternate(); 536 let mut s = f.debug_struct("Layered"); 537 // These additional fields are more verbose and usually only necessary 538 // for internal debugging purposes, so only print them if alternate mode 539 // is enabled. 540 541 #[cfg(all(feature = "registry", feature = "std"))] 542 { 543 if alt { 544 s.field("inner_is_registry", &self.inner_is_registry) 545 .field("has_layer_filter", &self.has_layer_filter) 546 .field("inner_has_layer_filter", &self.inner_has_layer_filter); 547 } 548 } 549 550 s.field("layer", &self.layer) 551 .field("inner", &self.inner) 552 .finish() 553 } 554 } 555