tracing_core/subscriber.rs
1//! Collectors collect and record trace data.
2use crate::{span, Dispatch, Event, LevelFilter, Metadata};
3
4use alloc::{boxed::Box, sync::Arc};
5use core::any::{Any, TypeId};
6
7/// Trait representing the functions required to collect trace data.
8///
9/// Crates that provide implementations of methods for collecting or recording
10/// trace data should implement the `Subscriber` interface. This trait is
11/// intended to represent fundamental primitives for collecting trace events and
12/// spans — other libraries may offer utility functions and types to make
13/// subscriber implementations more modular or improve the ergonomics of writing
14/// subscribers.
15///
16/// A subscriber is responsible for the following:
17/// - Registering new spans as they are created, and providing them with span
18/// IDs. Implicitly, this means the subscriber may determine the strategy for
19/// determining span equality.
20/// - Recording the attachment of field values and follows-from annotations to
21/// spans.
22/// - Filtering spans and events, and determining when those filters must be
23/// invalidated.
24/// - Observing spans as they are entered, exited, and closed, and events as
25/// they occur.
26///
27/// When a span is entered or exited, the subscriber is provided only with the
28/// [ID] with which it tagged that span when it was created. This means
29/// that it is up to the subscriber to determine whether and how span _data_ —
30/// the fields and metadata describing the span — should be stored. The
31/// [`new_span`] function is called when a new span is created, and at that
32/// point, the subscriber _may_ choose to store the associated data if it will
33/// be referenced again. However, if the data has already been recorded and will
34/// not be needed by the implementations of `enter` and `exit`, the subscriber
35/// may freely discard that data without allocating space to store it.
36///
37/// ## Overriding default impls
38///
39/// Some trait methods on `Subscriber` have default implementations, either in
40/// order to reduce the surface area of implementing `Subscriber`, or for
41/// backward-compatibility reasons. However, many subscribers will likely want
42/// to override these default implementations.
43///
44/// The following methods are likely of interest:
45///
46/// - [`register_callsite`] is called once for each callsite from which a span
47/// event may originate, and returns an [`Interest`] value describing whether or
48/// not the subscriber wishes to see events or spans from that callsite. By
49/// default, it calls [`enabled`], and returns `Interest::always()` if
50/// `enabled` returns true, or `Interest::never()` if enabled returns false.
51/// However, if the subscriber's interest can change dynamically at runtime,
52/// it may want to override this function to return `Interest::sometimes()`.
53/// Additionally, subscribers which wish to perform a behaviour once for each
54/// callsite, such as allocating storage for data related to that callsite,
55/// can perform it in `register_callsite`.
56///
57/// See also the [documentation on the callsite registry][cs-reg] for details
58/// on [`register_callsite`].
59///
60/// - [`event_enabled`] is called once before every call to the [`event`]
61/// method. This can be used to implement filtering on events once their field
62/// values are known, but before any processing is done in the `event` method.
63/// - [`clone_span`] is called every time a span ID is cloned, and [`try_close`]
64/// is called when a span ID is dropped. By default, these functions do
65/// nothing. However, they can be used to implement reference counting for
66/// spans, allowing subscribers to free storage for span data and to determine
67/// when a span has _closed_ permanently (rather than being exited).
68/// Subscribers which store per-span data or which need to track span closures
69/// should override these functions together.
70///
71/// [ID]: super::span::Id
72/// [`new_span`]: Subscriber::new_span
73/// [`register_callsite`]: Subscriber::register_callsite
74/// [`enabled`]: Subscriber::enabled
75/// [`clone_span`]: Subscriber::clone_span
76/// [`try_close`]: Subscriber::try_close
77/// [cs-reg]: crate::callsite#registering-callsites
78/// [`event`]: Subscriber::event
79/// [`event_enabled`]: Subscriber::event_enabled
80pub trait Subscriber: 'static {
81 /// Invoked when this subscriber becomes a [`Dispatch`].
82 ///
83 /// ## Avoiding Memory Leaks
84 ///
85 /// `Subscriber`s should not store their own [`Dispatch`]. Because the
86 /// `Dispatch` owns the `Subscriber`, storing the `Dispatch` within the
87 /// `Subscriber` will create a reference count cycle, preventing the `Dispatch`
88 /// from ever being dropped.
89 ///
90 /// Instead, when it is necessary to store a cyclical reference to the
91 /// `Dispatch` within a `Subscriber`, use [`Dispatch::downgrade`] to convert a
92 /// `Dispatch` into a [`WeakDispatch`]. This type is analogous to
93 /// [`std::sync::Weak`], and does not create a reference count cycle. A
94 /// [`WeakDispatch`] can be stored within a `Subscriber` without causing a
95 /// memory leak, and can be [upgraded] into a `Dispatch` temporarily when
96 /// the `Dispatch` must be accessed by the `Subscriber`.
97 ///
98 /// [`WeakDispatch`]: crate::dispatcher::WeakDispatch
99 /// [upgraded]: crate::dispatcher::WeakDispatch::upgrade
100 fn on_register_dispatch(&self, subscriber: &Dispatch) {
101 let _ = subscriber;
102 }
103
104 /// Registers a new [callsite] with this subscriber, returning whether or not
105 /// the subscriber is interested in being notified about the callsite.
106 ///
107 /// By default, this function assumes that the subscriber's [filter]
108 /// represents an unchanging view of its interest in the callsite. However,
109 /// if this is not the case, subscribers may override this function to
110 /// indicate different interests, or to implement behaviour that should run
111 /// once for every callsite.
112 ///
113 /// This function is guaranteed to be called at least once per callsite on
114 /// every active subscriber. The subscriber may store the keys to fields it
115 /// cares about in order to reduce the cost of accessing fields by name,
116 /// preallocate storage for that callsite, or perform any other actions it
117 /// wishes to perform once for each callsite.
118 ///
119 /// The subscriber should then return an [`Interest`], indicating
120 /// whether it is interested in being notified about that callsite in the
121 /// future. This may be `Always` indicating that the subscriber always
122 /// wishes to be notified about the callsite, and its filter need not be
123 /// re-evaluated; `Sometimes`, indicating that the subscriber may sometimes
124 /// care about the callsite but not always (such as when sampling), or
125 /// `Never`, indicating that the subscriber never wishes to be notified about
126 /// that callsite. If all active subscribers return `Never`, a callsite will
127 /// never be enabled unless a new subscriber expresses interest in it.
128 ///
129 /// `Subscriber`s which require their filters to be run every time an event
130 /// occurs or a span is entered/exited should return `Interest::sometimes`.
131 /// If a subscriber returns `Interest::sometimes`, then its [`enabled`] method
132 /// will be called every time an event or span is created from that callsite.
133 ///
134 /// For example, suppose a sampling subscriber is implemented by
135 /// incrementing a counter every time `enabled` is called and only returning
136 /// `true` when the counter is divisible by a specified sampling rate. If
137 /// that subscriber returns `Interest::always` from `register_callsite`, then
138 /// the filter will not be re-evaluated once it has been applied to a given
139 /// set of metadata. Thus, the counter will not be incremented, and the span
140 /// or event that corresponds to the metadata will never be `enabled`.
141 ///
142 /// `Subscriber`s that need to change their filters occasionally should call
143 /// [`rebuild_interest_cache`] to re-evaluate `register_callsite` for all
144 /// callsites.
145 ///
146 /// Similarly, if a `Subscriber` has a filtering strategy that can be
147 /// changed dynamically at runtime, it would need to re-evaluate that filter
148 /// if the cached results have changed.
149 ///
150 /// A subscriber which manages fanout to multiple other subscribers
151 /// should proxy this decision to all of its child subscribers,
152 /// returning `Interest::never` only if _all_ such children return
153 /// `Interest::never`. If the set of subscribers to which spans are
154 /// broadcast may change dynamically, the subscriber should also never
155 /// return `Interest::Never`, as a new subscriber may be added that _is_
156 /// interested.
157 ///
158 /// See the [documentation on the callsite registry][cs-reg] for more
159 /// details on how and when the `register_callsite` method is called.
160 ///
161 /// # Notes
162 /// This function may be called again when a new subscriber is created or
163 /// when the registry is invalidated.
164 ///
165 /// If a subscriber returns `Interest::never` for a particular callsite, it
166 /// _may_ still see spans and events originating from that callsite, if
167 /// another subscriber expressed interest in it.
168 ///
169 /// [callsite]: crate::callsite
170 /// [filter]: Self::enabled
171 /// [metadata]: super::metadata::Metadata
172 /// [`enabled`]: Subscriber::enabled()
173 /// [`rebuild_interest_cache`]: super::callsite::rebuild_interest_cache
174 /// [cs-reg]: crate::callsite#registering-callsites
175 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
176 if self.enabled(metadata) {
177 Interest::always()
178 } else {
179 Interest::never()
180 }
181 }
182
183 /// Returns true if a span or event with the specified [metadata] would be
184 /// recorded.
185 ///
186 /// By default, it is assumed that this filter needs only be evaluated once
187 /// for each callsite, so it is called by [`register_callsite`] when each
188 /// callsite is registered. The result is used to determine if the subscriber
189 /// is always [interested] or never interested in that callsite. This is intended
190 /// primarily as an optimization, so that expensive filters (such as those
191 /// involving string search, et cetera) need not be re-evaluated.
192 ///
193 /// However, if the subscriber's interest in a particular span or event may
194 /// change, or depends on contexts only determined dynamically at runtime,
195 /// then the `register_callsite` method should be overridden to return
196 /// [`Interest::sometimes`]. In that case, this function will be called every
197 /// time that span or event occurs.
198 ///
199 /// [metadata]: super::metadata::Metadata
200 /// [interested]: Interest
201 /// [`Interest::sometimes`]: Interest::sometimes
202 /// [`register_callsite`]: Subscriber::register_callsite()
203 fn enabled(&self, metadata: &Metadata<'_>) -> bool;
204
205 /// Returns the highest [verbosity level][level] that this `Subscriber` will
206 /// enable, or `None`, if the subscriber does not implement level-based
207 /// filtering or chooses not to implement this method.
208 ///
209 /// If this method returns a [`Level`][level], it will be used as a hint to
210 /// determine the most verbose level that will be enabled. This will allow
211 /// spans and events which are more verbose than that level to be skipped
212 /// more efficiently. Subscribers which perform filtering are strongly
213 /// encouraged to provide an implementation of this method.
214 ///
215 /// If the maximum level the subscriber will enable can change over the
216 /// course of its lifetime, it is free to return a different value from
217 /// multiple invocations of this method. However, note that changes in the
218 /// maximum level will **only** be reflected after the callsite [`Interest`]
219 /// cache is rebuilt, by calling the [`callsite::rebuild_interest_cache`][rebuild]
220 /// function. Therefore, if the subscriber will change the value returned by
221 /// this method, it is responsible for ensuring that
222 /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
223 /// level changes.
224 ///
225 /// [level]: super::Level
226 /// [rebuild]: super::callsite::rebuild_interest_cache
227 fn max_level_hint(&self) -> Option<LevelFilter> {
228 None
229 }
230
231 /// Visit the construction of a new span, returning a new [span ID] for the
232 /// span being constructed.
233 ///
234 /// The provided [`Attributes`] contains any field values that were provided
235 /// when the span was created. The subscriber may pass a [visitor] to the
236 /// `Attributes`' [`record` method] to record these values.
237 ///
238 /// IDs are used to uniquely identify spans and events within the context of a
239 /// subscriber, so span equality will be based on the returned ID. Thus, if
240 /// the subscriber wishes for all spans with the same metadata to be
241 /// considered equal, it should return the same ID every time it is given a
242 /// particular set of metadata. Similarly, if it wishes for two separate
243 /// instances of a span with the same metadata to *not* be equal, it should
244 /// return a distinct ID every time this function is called, regardless of
245 /// the metadata.
246 ///
247 /// Note that the subscriber is free to assign span IDs based on whatever
248 /// scheme it sees fit. Any guarantees about uniqueness, ordering, or ID
249 /// reuse are left up to the subscriber implementation to determine.
250 ///
251 /// [span ID]: super::span::Id
252 /// [`Attributes`]: super::span::Attributes
253 /// [visitor]: super::field::Visit
254 /// [`record` method]: super::span::Attributes::record
255 fn new_span(&self, span: &span::Attributes<'_>) -> span::Id;
256
257 // === Notification methods ===============================================
258
259 /// Record a set of values on a span.
260 ///
261 /// This method will be invoked when value is recorded on a span.
262 /// Recording multiple values for the same field is possible,
263 /// but the actual behaviour is defined by the subscriber implementation.
264 ///
265 /// Keep in mind that a span might not provide a value
266 /// for each field it declares.
267 ///
268 /// The subscriber is expected to provide a [visitor] to the `Record`'s
269 /// [`record` method] in order to record the added values.
270 ///
271 /// # Example
272 /// "foo = 3" will be recorded when [`record`] is called on the
273 /// `Attributes` passed to `new_span`.
274 /// Since values are not provided for the `bar` and `baz` fields,
275 /// the span's `Metadata` will indicate that it _has_ those fields,
276 /// but values for them won't be recorded at this time.
277 ///
278 /// ```rust,ignore
279 /// # use tracing::span;
280 ///
281 /// let mut span = span!("my_span", foo = 3, bar, baz);
282 ///
283 /// // `Subscriber::record` will be called with a `Record`
284 /// // containing "bar = false"
285 /// span.record("bar", &false);
286 ///
287 /// // `Subscriber::record` will be called with a `Record`
288 /// // containing "baz = "a string""
289 /// span.record("baz", &"a string");
290 /// ```
291 ///
292 /// [visitor]: super::field::Visit
293 /// [`record`]: super::span::Attributes::record
294 /// [`record` method]: super::span::Record::record
295 fn record(&self, span: &span::Id, values: &span::Record<'_>);
296
297 /// Adds an indication that `span` follows from the span with the id
298 /// `follows`.
299 ///
300 /// This relationship differs somewhat from the parent-child relationship: a
301 /// span may have any number of prior spans, rather than a single one; and
302 /// spans are not considered to be executing _inside_ of the spans they
303 /// follow from. This means that a span may close even if subsequent spans
304 /// that follow from it are still open, and time spent inside of a
305 /// subsequent span should not be included in the time its precedents were
306 /// executing. This is used to model causal relationships such as when a
307 /// single future spawns several related background tasks, et cetera.
308 ///
309 /// If the subscriber has spans corresponding to the given IDs, it should
310 /// record this relationship in whatever way it deems necessary. Otherwise,
311 /// if one or both of the given span IDs do not correspond to spans that the
312 /// subscriber knows about, or if a cyclical relationship would be created
313 /// (i.e., some span _a_ which proceeds some other span _b_ may not also
314 /// follow from _b_), it may silently do nothing.
315 fn record_follows_from(&self, span: &span::Id, follows: &span::Id);
316
317 /// Determine if an [`Event`] should be recorded.
318 ///
319 /// By default, this returns `true` and `Subscriber`s can filter events in
320 /// [`event`][Self::event] without any penalty. However, when `event` is
321 /// more complicated, this can be used to determine if `event` should be
322 /// called at all, separating out the decision from the processing.
323 fn event_enabled(&self, event: &Event<'_>) -> bool {
324 let _ = event;
325 true
326 }
327
328 /// Records that an [`Event`] has occurred.
329 ///
330 /// This method will be invoked when an Event is constructed by
331 /// the `Event`'s [`dispatch` method]. For example, this happens internally
332 /// when an event macro from `tracing` is called.
333 ///
334 /// The key difference between this method and `record` is that `record` is
335 /// called when a value is recorded for a field defined by a span,
336 /// while `event` is called when a new event occurs.
337 ///
338 /// The provided `Event` struct contains any field values attached to the
339 /// event. The subscriber may pass a [visitor] to the `Event`'s
340 /// [`record` method] to record these values.
341 ///
342 /// [`Event`]: super::event::Event
343 /// [visitor]: super::field::Visit
344 /// [`record` method]: super::event::Event::record
345 /// [`dispatch` method]: super::event::Event::dispatch
346 fn event(&self, event: &Event<'_>);
347
348 /// Records that a span has been entered.
349 ///
350 /// When entering a span, this method is called to notify the subscriber
351 /// that the span has been entered. The subscriber is provided with the
352 /// [span ID] of the entered span, and should update any internal state
353 /// tracking the current span accordingly.
354 ///
355 /// [span ID]: super::span::Id
356 fn enter(&self, span: &span::Id);
357
358 /// Records that a span has been exited.
359 ///
360 /// When exiting a span, this method is called to notify the subscriber
361 /// that the span has been exited. The subscriber is provided with the
362 /// [span ID] of the exited span, and should update any internal state
363 /// tracking the current span accordingly.
364 ///
365 /// Exiting a span does not imply that the span will not be re-entered.
366 ///
367 /// [span ID]: super::span::Id
368 fn exit(&self, span: &span::Id);
369
370 /// Notifies the subscriber that a [span ID] has been cloned.
371 ///
372 /// This function is guaranteed to only be called with span IDs that were
373 /// returned by this subscriber's `new_span` function.
374 ///
375 /// Note that the default implementation of this function this is just the
376 /// identity function, passing through the identifier. However, it can be
377 /// used in conjunction with [`try_close`] to track the number of handles
378 /// capable of `enter`ing a span. When all the handles have been dropped
379 /// (i.e., `try_close` has been called one more time than `clone_span` for a
380 /// given ID), the subscriber may assume that the span will not be entered
381 /// again. It is then free to deallocate storage for data associated with
382 /// that span, write data from that span to IO, and so on.
383 ///
384 /// For more unsafe situations, however, if `id` is itself a pointer of some
385 /// kind this can be used as a hook to "clone" the pointer, depending on
386 /// what that means for the specified pointer.
387 ///
388 /// [span ID]: super::span::Id
389 /// [`try_close`]: Subscriber::try_close
390 fn clone_span(&self, id: &span::Id) -> span::Id {
391 id.clone()
392 }
393
394 /// **This method is deprecated.**
395 ///
396 /// Using `drop_span` may result in subscribers composed using
397 /// `tracing-subscriber` crate's `Layer` trait from observing close events.
398 /// Use [`try_close`] instead.
399 ///
400 /// The default implementation of this function does nothing.
401 ///
402 /// [`try_close`]: Subscriber::try_close
403 #[deprecated(since = "0.1.2", note = "use `Subscriber::try_close` instead")]
404 fn drop_span(&self, _id: span::Id) {}
405
406 /// Notifies the subscriber that a [span ID] has been dropped, and returns
407 /// `true` if there are now 0 IDs that refer to that span.
408 ///
409 /// Higher-level libraries providing functionality for composing multiple
410 /// subscriber implementations may use this return value to notify any
411 /// "layered" subscribers that this subscriber considers the span closed.
412 ///
413 /// The default implementation of this method calls the subscriber's
414 /// [`drop_span`] method and returns `false`. This means that, unless the
415 /// subscriber overrides the default implementation, close notifications
416 /// will never be sent to any layered subscribers. In general, if the
417 /// subscriber tracks reference counts, this method should be implemented,
418 /// rather than `drop_span`.
419 ///
420 /// This function is guaranteed to only be called with span IDs that were
421 /// returned by this subscriber's `new_span` function.
422 ///
423 /// It's guaranteed that if this function has been called once more than the
424 /// number of times `clone_span` was called with the same `id`, then no more
425 /// handles that can enter the span with that `id` exist. This means that it
426 /// can be used in conjunction with [`clone_span`] to track the number of
427 /// handles capable of `enter`ing a span. When all the handles have been
428 /// dropped (i.e., `try_close` has been called one more time than
429 /// `clone_span` for a given ID), the subscriber may assume that the span
430 /// will not be entered again, and should return `true`. It is then free to
431 /// deallocate storage for data associated with that span, write data from
432 /// that span to IO, and so on.
433 ///
434 /// **Note**: since this function is called when spans are dropped,
435 /// implementations should ensure that they are unwind-safe. Panicking from
436 /// inside of a `try_close` function may cause a double panic, if the span
437 /// was dropped due to a thread unwinding.
438 ///
439 /// [span ID]: super::span::Id
440 /// [`clone_span`]: Subscriber::clone_span
441 /// [`drop_span`]: Subscriber::drop_span
442 fn try_close(&self, id: span::Id) -> bool {
443 #[allow(deprecated)]
444 self.drop_span(id);
445 false
446 }
447
448 /// Returns a type representing this subscriber's view of the current span.
449 ///
450 /// If subscribers track a current span, they should override this function
451 /// to return [`Current::new`] if the thread from which this method is
452 /// called is inside a span, or [`Current::none`] if the thread is not
453 /// inside a span.
454 ///
455 /// By default, this returns a value indicating that the subscriber
456 /// does **not** track what span is current. If the subscriber does not
457 /// implement a current span, it should not override this method.
458 ///
459 /// [`Current::new`]: super::span::Current#tymethod.new
460 /// [`Current::none`]: super::span::Current#tymethod.none
461 fn current_span(&self) -> span::Current {
462 span::Current::unknown()
463 }
464
465 // === Downcasting methods ================================================
466
467 /// If `self` is the same type as the provided `TypeId`, returns an untyped
468 /// `*const` pointer to that type. Otherwise, returns `None`.
469 ///
470 /// If you wish to downcast a `Subscriber`, it is strongly advised to use
471 /// the safe API provided by [`downcast_ref`] instead.
472 ///
473 /// This API is required for `downcast_raw` to be a trait method; a method
474 /// signature like [`downcast_ref`] (with a generic type parameter) is not
475 /// object-safe, and thus cannot be a trait method for `Subscriber`. This
476 /// means that if we only exposed `downcast_ref`, `Subscriber`
477 /// implementations could not override the downcasting behavior
478 ///
479 /// This method may be overridden by "fan out" or "chained" subscriber
480 /// implementations which consist of multiple composed types. Such
481 /// subscribers might allow `downcast_raw` by returning references to those
482 /// component if they contain components with the given `TypeId`.
483 ///
484 /// # Safety
485 ///
486 /// The [`downcast_ref`] method expects that the pointer returned by
487 /// `downcast_raw` is non-null and points to a valid instance of the type
488 /// with the provided `TypeId`. Failure to ensure this will result in
489 /// undefined behaviour, so implementing `downcast_raw` is unsafe.
490 ///
491 /// [`downcast_ref`]: #method.downcast_ref
492 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
493 if id == TypeId::of::<Self>() {
494 Some(self as *const Self as *const ())
495 } else {
496 None
497 }
498 }
499}
500
501impl dyn Subscriber {
502 /// Returns `true` if this `Subscriber` is the same type as `T`.
503 pub fn is<T: Any>(&self) -> bool {
504 self.downcast_ref::<T>().is_some()
505 }
506
507 /// Returns some reference to this `Subscriber` value if it is of type `T`,
508 /// or `None` if it isn't.
509 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
510 unsafe {
511 let raw = self.downcast_raw(TypeId::of::<T>())?;
512 if raw.is_null() {
513 None
514 } else {
515 Some(&*(raw as *const _))
516 }
517 }
518 }
519}
520
521impl dyn Subscriber + Send {
522 /// Returns `true` if this [`Subscriber`] is the same type as `T`.
523 pub fn is<T: Any>(&self) -> bool {
524 self.downcast_ref::<T>().is_some()
525 }
526
527 /// Returns some reference to this [`Subscriber`] value if it is of type `T`,
528 /// or `None` if it isn't.
529 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
530 unsafe {
531 let raw = self.downcast_raw(TypeId::of::<T>())?;
532 if raw.is_null() {
533 None
534 } else {
535 Some(&*(raw as *const _))
536 }
537 }
538 }
539}
540
541impl dyn Subscriber + Sync {
542 /// Returns `true` if this [`Subscriber`] is the same type as `T`.
543 pub fn is<T: Any>(&self) -> bool {
544 self.downcast_ref::<T>().is_some()
545 }
546
547 /// Returns some reference to this `[`Subscriber`] value if it is of type `T`,
548 /// or `None` if it isn't.
549 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
550 unsafe {
551 let raw = self.downcast_raw(TypeId::of::<T>())?;
552 if raw.is_null() {
553 None
554 } else {
555 Some(&*(raw as *const _))
556 }
557 }
558 }
559}
560
561impl dyn Subscriber + Send + Sync {
562 /// Returns `true` if this [`Subscriber`] is the same type as `T`.
563 pub fn is<T: Any>(&self) -> bool {
564 self.downcast_ref::<T>().is_some()
565 }
566
567 /// Returns some reference to this [`Subscriber`] value if it is of type `T`,
568 /// or `None` if it isn't.
569 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
570 unsafe {
571 let raw = self.downcast_raw(TypeId::of::<T>())?;
572 if raw.is_null() {
573 None
574 } else {
575 Some(&*(raw as *const _))
576 }
577 }
578 }
579}
580
581/// Indicates a [`Subscriber`]'s interest in a particular callsite.
582///
583/// `Subscriber`s return an `Interest` from their [`register_callsite`] methods
584/// in order to determine whether that span should be enabled or disabled.
585///
586/// [`Subscriber`]: super::Subscriber
587/// [`register_callsite`]: super::Subscriber::register_callsite
588#[derive(Clone, Debug)]
589pub struct Interest(InterestKind);
590
591#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
592enum InterestKind {
593 Never = 0,
594 Sometimes = 1,
595 Always = 2,
596}
597
598impl Interest {
599 /// Returns an `Interest` indicating that the subscriber is never interested
600 /// in being notified about a callsite.
601 ///
602 /// If all active subscribers are `never()` interested in a callsite, it will
603 /// be completely disabled unless a new subscriber becomes active.
604 #[inline]
605 pub fn never() -> Self {
606 Interest(InterestKind::Never)
607 }
608
609 /// Returns an `Interest` indicating the subscriber is sometimes interested
610 /// in being notified about a callsite.
611 ///
612 /// If all active subscribers are `sometimes` or `never` interested in a
613 /// callsite, the currently active subscriber will be asked to filter that
614 /// callsite every time it creates a span. This will be the case until a new
615 /// subscriber expresses that it is `always` interested in the callsite.
616 #[inline]
617 pub fn sometimes() -> Self {
618 Interest(InterestKind::Sometimes)
619 }
620
621 /// Returns an `Interest` indicating the subscriber is always interested in
622 /// being notified about a callsite.
623 ///
624 /// If any subscriber expresses that it is `always()` interested in a given
625 /// callsite, then the callsite will always be enabled.
626 #[inline]
627 pub fn always() -> Self {
628 Interest(InterestKind::Always)
629 }
630
631 /// Returns `true` if the subscriber is never interested in being notified
632 /// about this callsite.
633 #[inline]
634 pub fn is_never(&self) -> bool {
635 matches!(self.0, InterestKind::Never)
636 }
637
638 /// Returns `true` if the subscriber is sometimes interested in being notified
639 /// about this callsite.
640 #[inline]
641 pub fn is_sometimes(&self) -> bool {
642 matches!(self.0, InterestKind::Sometimes)
643 }
644
645 /// Returns `true` if the subscriber is always interested in being notified
646 /// about this callsite.
647 #[inline]
648 pub fn is_always(&self) -> bool {
649 matches!(self.0, InterestKind::Always)
650 }
651
652 /// Returns the common interest between these two Interests.
653 ///
654 /// If both interests are the same, this propagates that interest.
655 /// Otherwise, if they differ, the result must always be
656 /// `Interest::sometimes` --- if the two subscribers differ in opinion, we
657 /// will have to ask the current subscriber what it thinks, no matter what.
658 pub(crate) fn and(self, rhs: Interest) -> Self {
659 if self.0 == rhs.0 {
660 self
661 } else {
662 Interest::sometimes()
663 }
664 }
665}
666
667/// A no-op [`Subscriber`].
668///
669/// [`NoSubscriber`] implements the [`Subscriber`] trait by never being enabled,
670/// never being interested in any callsite, and dropping all spans and events.
671#[derive(Copy, Clone, Debug, Default)]
672pub struct NoSubscriber(());
673
674impl Subscriber for NoSubscriber {
675 #[inline]
676 fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest {
677 Interest::never()
678 }
679
680 fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
681 span::Id::from_u64(0xDEAD)
682 }
683
684 fn event(&self, _event: &Event<'_>) {}
685
686 fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
687
688 fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
689
690 #[inline]
691 fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
692 false
693 }
694
695 fn enter(&self, _span: &span::Id) {}
696 fn exit(&self, _span: &span::Id) {}
697}
698
699impl NoSubscriber {
700 /// Returns a new `NoSubscriber`.
701 #[must_use]
702 pub const fn new() -> Self {
703 Self(())
704 }
705}
706
707impl<S> Subscriber for Box<S>
708where
709 S: Subscriber + ?Sized,
710{
711 #[inline]
712 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
713 self.as_ref().register_callsite(metadata)
714 }
715
716 #[inline]
717 fn enabled(&self, metadata: &Metadata<'_>) -> bool {
718 self.as_ref().enabled(metadata)
719 }
720
721 #[inline]
722 fn max_level_hint(&self) -> Option<LevelFilter> {
723 self.as_ref().max_level_hint()
724 }
725
726 #[inline]
727 fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
728 self.as_ref().new_span(span)
729 }
730
731 #[inline]
732 fn record(&self, span: &span::Id, values: &span::Record<'_>) {
733 self.as_ref().record(span, values)
734 }
735
736 #[inline]
737 fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
738 self.as_ref().record_follows_from(span, follows)
739 }
740
741 #[inline]
742 fn event_enabled(&self, event: &Event<'_>) -> bool {
743 self.as_ref().event_enabled(event)
744 }
745
746 #[inline]
747 fn event(&self, event: &Event<'_>) {
748 self.as_ref().event(event)
749 }
750
751 #[inline]
752 fn enter(&self, span: &span::Id) {
753 self.as_ref().enter(span)
754 }
755
756 #[inline]
757 fn exit(&self, span: &span::Id) {
758 self.as_ref().exit(span)
759 }
760
761 #[inline]
762 fn clone_span(&self, id: &span::Id) -> span::Id {
763 self.as_ref().clone_span(id)
764 }
765
766 #[inline]
767 fn try_close(&self, id: span::Id) -> bool {
768 self.as_ref().try_close(id)
769 }
770
771 #[inline]
772 #[allow(deprecated)]
773 fn drop_span(&self, id: span::Id) {
774 self.as_ref().try_close(id);
775 }
776
777 #[inline]
778 fn current_span(&self) -> span::Current {
779 self.as_ref().current_span()
780 }
781
782 #[inline]
783 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
784 if id == TypeId::of::<Self>() {
785 return Some(self as *const Self as *const _);
786 }
787
788 unsafe { self.as_ref().downcast_raw(id) }
789 }
790}
791
792impl<S> Subscriber for Arc<S>
793where
794 S: Subscriber + ?Sized,
795{
796 #[inline]
797 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
798 self.as_ref().register_callsite(metadata)
799 }
800
801 #[inline]
802 fn enabled(&self, metadata: &Metadata<'_>) -> bool {
803 self.as_ref().enabled(metadata)
804 }
805
806 #[inline]
807 fn max_level_hint(&self) -> Option<LevelFilter> {
808 self.as_ref().max_level_hint()
809 }
810
811 #[inline]
812 fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
813 self.as_ref().new_span(span)
814 }
815
816 #[inline]
817 fn record(&self, span: &span::Id, values: &span::Record<'_>) {
818 self.as_ref().record(span, values)
819 }
820
821 #[inline]
822 fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
823 self.as_ref().record_follows_from(span, follows)
824 }
825
826 #[inline]
827 fn event_enabled(&self, event: &Event<'_>) -> bool {
828 self.as_ref().event_enabled(event)
829 }
830
831 #[inline]
832 fn event(&self, event: &Event<'_>) {
833 self.as_ref().event(event)
834 }
835
836 #[inline]
837 fn enter(&self, span: &span::Id) {
838 self.as_ref().enter(span)
839 }
840
841 #[inline]
842 fn exit(&self, span: &span::Id) {
843 self.as_ref().exit(span)
844 }
845
846 #[inline]
847 fn clone_span(&self, id: &span::Id) -> span::Id {
848 self.as_ref().clone_span(id)
849 }
850
851 #[inline]
852 fn try_close(&self, id: span::Id) -> bool {
853 self.as_ref().try_close(id)
854 }
855
856 #[inline]
857 #[allow(deprecated)]
858 fn drop_span(&self, id: span::Id) {
859 self.as_ref().try_close(id);
860 }
861
862 #[inline]
863 fn current_span(&self) -> span::Current {
864 self.as_ref().current_span()
865 }
866
867 #[inline]
868 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
869 if id == TypeId::of::<Self>() {
870 return Some(self as *const Self as *const _);
871 }
872
873 unsafe { self.as_ref().downcast_raw(id) }
874 }
875}