πŸ›ˆ Note: This is pre-release documentation for the upcoming tracing 0.2.0 ecosystem.

For the release documentation, please see docs.rs, instead.

tracing_core/
collect.rs

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