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