1use tracing_core::{metadata::Metadata, span, Dispatch, Event, Interest, LevelFilter, Subscriber};
2
3use crate::{
4 filter,
5 layer::{Context, Layer},
6 registry::LookupSpan,
7};
8#[cfg(all(feature = "registry", feature = "std"))]
9use crate::{filter::FilterId, registry::Registry};
10use core::{
11 any::{Any, TypeId},
12 cmp, fmt,
13 marker::PhantomData,
14};
15
16#[derive(Clone)]
22pub struct Layered<L, I, S = I> {
23 layer: L,
25
26 inner: I,
32
33 inner_is_registry: bool,
40
41 has_layer_filter: bool,
54
55 inner_has_layer_filter: bool,
60 _s: PhantomData<fn(S)>,
61}
62
63impl<L, S> Layered<L, S>
66where
67 L: Layer<S>,
68 S: Subscriber,
69{
70 pub fn is<T: Any>(&self) -> bool {
72 self.downcast_ref::<T>().is_some()
73 }
74
75 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
89impl<L, S> Subscriber for Layered<L, S>
90where
91 L: Layer<S>,
92 S: Subscriber,
93{
94 fn on_register_dispatch(&self, subscriber: &Dispatch) {
95 self.inner.on_register_dispatch(subscriber);
96 self.layer.on_register_dispatch(subscriber);
97 }
98
99 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
100 self.pick_interest(self.layer.register_callsite(metadata), || {
101 self.inner.register_callsite(metadata)
102 })
103 }
104
105 fn enabled(&self, metadata: &Metadata<'_>) -> bool {
106 if self.layer.enabled(metadata, self.ctx()) {
107 self.inner.enabled(metadata)
109 } else {
110 #[cfg(feature = "registry")]
116 filter::FilterState::clear_enabled();
117
118 false
119 }
120 }
121
122 fn max_level_hint(&self) -> Option<LevelFilter> {
123 self.pick_level_hint(
124 self.layer.max_level_hint(),
125 self.inner.max_level_hint(),
126 super::subscriber_is_none(&self.inner),
127 )
128 }
129
130 fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
131 let id = self.inner.new_span(span);
132 self.layer.on_new_span(span, &id, self.ctx());
133 id
134 }
135
136 fn record(&self, span: &span::Id, values: &span::Record<'_>) {
137 self.inner.record(span, values);
138 self.layer.on_record(span, values, self.ctx());
139 }
140
141 fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
142 self.inner.record_follows_from(span, follows);
143 self.layer.on_follows_from(span, follows, self.ctx());
144 }
145
146 fn event_enabled(&self, event: &Event<'_>) -> bool {
147 if self.layer.event_enabled(event, self.ctx()) {
148 self.inner.event_enabled(event)
150 } else {
151 false
153 }
154 }
155
156 fn event(&self, event: &Event<'_>) {
157 self.inner.event(event);
158 self.layer.on_event(event, self.ctx());
159 }
160
161 fn enter(&self, span: &span::Id) {
162 self.inner.enter(span);
163 self.layer.on_enter(span, self.ctx());
164 }
165
166 fn exit(&self, span: &span::Id) {
167 self.inner.exit(span);
168 self.layer.on_exit(span, self.ctx());
169 }
170
171 fn clone_span(&self, old: &span::Id) -> span::Id {
172 let new = self.inner.clone_span(old);
173 if &new != old {
174 self.layer.on_id_change(old, &new, self.ctx())
175 };
176 new
177 }
178
179 #[inline]
180 fn drop_span(&self, id: span::Id) {
181 self.try_close(id);
182 }
183
184 fn try_close(&self, id: span::Id) -> bool {
185 #[cfg(all(feature = "registry", feature = "std"))]
186 let subscriber = &self.inner as &dyn Subscriber;
187 #[cfg(all(feature = "registry", feature = "std"))]
188 let mut guard = subscriber
189 .downcast_ref::<Registry>()
190 .map(|registry| registry.start_close(id.clone()));
191 if self.inner.try_close(id.clone()) {
192 #[cfg(all(feature = "registry", feature = "std"))]
195 {
196 if let Some(g) = guard.as_mut() {
197 g.set_closing()
198 };
199 }
200
201 self.layer.on_close(id, self.ctx());
202 true
203 } else {
204 false
205 }
206 }
207
208 #[inline]
209 fn current_span(&self) -> span::Current {
210 self.inner.current_span()
211 }
212
213 #[doc(hidden)]
214 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
215 if id == TypeId::of::<Self>() {
237 return Some(self as *const _ as *const ());
238 }
239
240 unsafe { self.layer.downcast_raw(id) }.or_else(|| unsafe { self.inner.downcast_raw(id) })
241 }
242}
243
244impl<S, A, B> Layer<S> for Layered<A, B, S>
245where
246 A: Layer<S>,
247 B: Layer<S>,
248 S: Subscriber,
249{
250 fn on_register_dispatch(&self, subscriber: &Dispatch) {
251 self.layer.on_register_dispatch(subscriber);
252 self.inner.on_register_dispatch(subscriber);
253 }
254
255 fn on_layer(&mut self, subscriber: &mut S) {
256 self.layer.on_layer(subscriber);
257 self.inner.on_layer(subscriber);
258 }
259
260 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
261 self.pick_interest(self.layer.register_callsite(metadata), || {
262 self.inner.register_callsite(metadata)
263 })
264 }
265
266 fn enabled(&self, metadata: &Metadata<'_>, ctx: Context<'_, S>) -> bool {
267 if self.layer.enabled(metadata, ctx.clone()) {
268 self.inner.enabled(metadata, ctx)
270 } else {
271 false
273 }
274 }
275
276 fn max_level_hint(&self) -> Option<LevelFilter> {
277 self.pick_level_hint(
278 self.layer.max_level_hint(),
279 self.inner.max_level_hint(),
280 super::layer_is_none(&self.inner),
281 )
282 }
283
284 #[inline]
285 fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
286 self.inner.on_new_span(attrs, id, ctx.clone());
287 self.layer.on_new_span(attrs, id, ctx);
288 }
289
290 #[inline]
291 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
292 self.inner.on_record(span, values, ctx.clone());
293 self.layer.on_record(span, values, ctx);
294 }
295
296 #[inline]
297 fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) {
298 self.inner.on_follows_from(span, follows, ctx.clone());
299 self.layer.on_follows_from(span, follows, ctx);
300 }
301
302 #[inline]
303 fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool {
304 if self.layer.event_enabled(event, ctx.clone()) {
305 self.inner.event_enabled(event, ctx)
307 } else {
308 false
310 }
311 }
312
313 #[inline]
314 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
315 self.inner.on_event(event, ctx.clone());
316 self.layer.on_event(event, ctx);
317 }
318
319 #[inline]
320 fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
321 self.inner.on_enter(id, ctx.clone());
322 self.layer.on_enter(id, ctx);
323 }
324
325 #[inline]
326 fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
327 self.inner.on_exit(id, ctx.clone());
328 self.layer.on_exit(id, ctx);
329 }
330
331 #[inline]
332 fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
333 self.inner.on_close(id.clone(), ctx.clone());
334 self.layer.on_close(id, ctx);
335 }
336
337 #[inline]
338 fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) {
339 self.inner.on_id_change(old, new, ctx.clone());
340 self.layer.on_id_change(old, new, ctx);
341 }
342
343 #[doc(hidden)]
344 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
345 match id {
346 id if id == TypeId::of::<Self>() => Some(self as *const _ as *const ()),
348
349 id if filter::is_plf_downcast_marker(id) => {
376 unsafe { self.layer.downcast_raw(id) }.and(unsafe { self.inner.downcast_raw(id) })
377 }
378
379 _ => unsafe { self.layer.downcast_raw(id) }
381 .or_else(|| unsafe { self.inner.downcast_raw(id) }),
382 }
383 }
384}
385
386impl<'a, L, S> LookupSpan<'a> for Layered<L, S>
387where
388 S: Subscriber + LookupSpan<'a>,
389{
390 type Data = S::Data;
391
392 fn span_data(&'a self, id: &span::Id) -> Option<Self::Data> {
393 self.inner.span_data(id)
394 }
395
396 #[cfg(all(feature = "registry", feature = "std"))]
397 fn register_filter(&mut self) -> FilterId {
398 self.inner.register_filter()
399 }
400}
401
402impl<L, S> Layered<L, S>
403where
404 S: Subscriber,
405{
406 fn ctx(&self) -> Context<'_, S> {
407 Context::new(&self.inner)
408 }
409}
410
411impl<A, B, S> Layered<A, B, S>
412where
413 A: Layer<S>,
414 S: Subscriber,
415{
416 pub(super) fn new(layer: A, inner: B, inner_has_layer_filter: bool) -> Self {
417 #[cfg(all(feature = "registry", feature = "std"))]
418 let inner_is_registry = TypeId::of::<S>() == TypeId::of::<crate::registry::Registry>();
419
420 #[cfg(not(all(feature = "registry", feature = "std")))]
421 let inner_is_registry = false;
422
423 let inner_has_layer_filter = inner_has_layer_filter || inner_is_registry;
424 let has_layer_filter = filter::layer_has_plf(&layer);
425 Self {
426 layer,
427 inner,
428 has_layer_filter,
429 inner_has_layer_filter,
430 inner_is_registry,
431 _s: PhantomData,
432 }
433 }
434
435 fn pick_interest(&self, outer: Interest, inner: impl FnOnce() -> Interest) -> Interest {
436 if self.has_layer_filter {
437 return inner();
438 }
439
440 if outer.is_never() {
443 #[cfg(feature = "registry")]
447 filter::FilterState::take_interest();
448
449 return outer;
450 }
451
452 let inner = inner();
457 if outer.is_sometimes() {
458 return outer;
461 }
462
463 if inner.is_never() && self.inner_has_layer_filter {
471 return Interest::sometimes();
472 }
473
474 inner
476 }
477
478 fn pick_level_hint(
479 &self,
480 outer_hint: Option<LevelFilter>,
481 inner_hint: Option<LevelFilter>,
482 inner_is_none: bool,
483 ) -> Option<LevelFilter> {
484 if self.inner_is_registry {
485 return outer_hint;
486 }
487
488 if self.has_layer_filter && self.inner_has_layer_filter {
489 return Some(cmp::max(outer_hint?, inner_hint?));
490 }
491
492 if self.has_layer_filter && inner_hint.is_none() {
493 return None;
494 }
495
496 if self.inner_has_layer_filter && outer_hint.is_none() {
497 return None;
498 }
499
500 if super::layer_is_none(&self.layer) {
516 return cmp::max(outer_hint, Some(inner_hint?));
517 }
518
519 if inner_is_none && inner_hint == Some(LevelFilter::OFF) {
522 return outer_hint;
523 }
524
525 cmp::max(outer_hint, inner_hint)
526 }
527}
528
529impl<A, B, S> fmt::Debug for Layered<A, B, S>
530where
531 A: fmt::Debug,
532 B: fmt::Debug,
533{
534 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
535 #[cfg(all(feature = "registry", feature = "std"))]
536 let alt = f.alternate();
537 let mut s = f.debug_struct("Layered");
538 #[cfg(all(feature = "registry", feature = "std"))]
543 {
544 if alt {
545 s.field("inner_is_registry", &self.inner_is_registry)
546 .field("has_layer_filter", &self.has_layer_filter)
547 .field("inner_has_layer_filter", &self.inner_has_layer_filter);
548 }
549 }
550
551 s.field("layer", &self.layer)
552 .field("inner", &self.inner)
553 .finish()
554 }
555}