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}