diff --git a/tracing-core/src/metadata.rs b/tracing-core/src/metadata.rs index 7bf7428a62..f8eff6dea8 100644 --- a/tracing-core/src/metadata.rs +++ b/tracing-core/src/metadata.rs @@ -14,7 +14,9 @@ use crate::stdlib::{ /// or event occurred. The `tracing` macros default to using the module /// path where the span or event originated as the target, but it may be /// overridden. -/// - A [verbosity level]. +/// - A [verbosity level]. This determines how verbose a given span or event +/// is, and allows enabling or disabling more verbose diagnostics +/// situationally. See the documentation for the [`Level`] type for details. /// - The names of the [fields] defined by the span or event. /// - Whether the metadata corresponds to a span or event. /// @@ -89,20 +91,150 @@ pub struct Metadata<'a> { /// Indicates whether the callsite is a span or event. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Kind(KindInner); - /// Describes the level of verbosity of a span or event. +/// +/// # Comparing Levels +/// +/// `Level` implements the [`PartialOrd`] and [`Ord`] traits, allowing two +/// `Level`s to be compared to determine which is considered more or less +/// verbose. Levels which are more verbose are considered "greater than" levels +/// which are less verbose, with [`Level::ERROR`] considered the lowest, and +/// [`Level::TRACE`] considered the highest. +/// +/// For example: +/// ``` +/// use tracing_core::Level; +/// +/// assert!(Level::TRACE > Level::DEBUG); +/// assert!(Level::ERROR < Level::WARN); +/// assert!(Level::INFO <= Level::DEBUG); +/// assert_eq!(Level::TRACE, Level::TRACE); +/// ``` +/// +/// # Filtering +/// +/// `Level`s are typically used to implement filtering that determines which +/// spans and events are enabled. Depending on the use case, more or less +/// verbose diagnostics may be desired. For example, when running in +/// development, [`DEBUG`]-level traces may be enabled by default. When running in +/// production, only [`INFO`]-level and lower traces might be enabled. Libraries +/// may include very verbose diagnostics at the [`DEBUG`] and/or [`TRACE`] levels. +/// Applications using those libraries typically chose to ignore those traces. However, when +/// debugging an issue involving said libraries, it may be useful to temporarily +/// enable the more verbose traces. +/// +/// The [`LevelFilter`] type is provided to enable filtering traces by +/// verbosity. `Level`s can be compared against [`LevelFilter`]s, and +/// [`LevelFilter`] has a variant for each `Level`, which compares analogously +/// to that level. In addition, [`LevelFilter`] adds a [`LevelFilter::OFF`] +/// variant, which is considered "less verbose" than every other `Level. This is +/// intended to allow filters to completely disable tracing in a particular context. +/// +/// For example: +/// ``` +/// use tracing_core::{Level, LevelFilter}; +/// +/// assert!(LevelFilter::OFF < Level::TRACE); +/// assert!(LevelFilter::TRACE > Level::DEBUG); +/// assert!(LevelFilter::ERROR < Level::WARN); +/// assert!(LevelFilter::INFO <= Level::DEBUG); +/// assert!(LevelFilter::INFO >= Level::INFO); +/// ``` +/// +/// ## Examples +/// +/// Below is a simple example of how a [`Subscriber`] could implement filtering through +/// a [`LevelFilter`]. When a span or event is recorded, the [`Subscriber::enabled`] method +/// compares the span or event's `Level` against the configured [`LevelFilter`]. +/// The optional [`Subscriber::max_level_hint`] method can also be implemented to allow spans +/// and events above a maximum verbosity level to be skipped more efficiently, +/// often improving performance in short-lived programs. +/// +/// ``` +/// use tracing_core::{span, Event, Level, LevelFilter, Subscriber, Metadata}; +/// # use tracing_core::span::{Id, Record, Current}; +/// +/// #[derive(Debug)] +/// pub struct MySubscriber { +/// /// The most verbose level that this subscriber will enable. +/// max_level: LevelFilter, +/// +/// // ... +/// } +/// +/// impl MySubscriber { +/// /// Returns a new `MySubscriber` which will record spans and events up to +/// /// `max_level`. +/// pub fn with_max_level(max_level: LevelFilter) -> Self { +/// Self { +/// max_level, +/// // ... +/// } +/// } +/// } +/// impl Subscriber for MySubscriber { +/// fn enabled(&self, meta: &Metadata<'_>) -> bool { +/// // A span or event is enabled if it is at or below the configured +/// // maximum level. +/// meta.level() <= &self.max_level +/// } +/// +/// // This optional method returns the most verbose level that this +/// // subscriber will enable. Although implementing this method is not +/// // *required*, it permits additional optimizations when it is provided, +/// // allowing spans and events above the max level to be skipped +/// // more efficiently. +/// fn max_level_hint(&self) -> Option { +/// Some(self.max_level) +/// } +/// +/// // Implement the rest of the subscriber... +/// fn new_span(&self, span: &span::Attributes<'_>) -> span::Id { +/// // ... +/// # drop(span); Id::from_u64(1) +/// } + +/// fn event(&self, event: &Event<'_>) { +/// // ... +/// # drop(event); +/// } +/// +/// // ... +/// # fn enter(&self, _: &Id) {} +/// # fn exit(&self, _: &Id) {} +/// # fn record(&self, _: &Id, _: &Record<'_>) {} +/// # fn record_follows_from(&self, _: &Id, _: &Id) {} +/// } +/// ``` +/// +/// It is worth noting that the `tracing-subscriber` crate provides [additional +/// APIs][envfilter] for performing more sophisticated filtering, such as +/// enabling different levels based on which module or crate a span or event is +/// recorded in. +/// +/// [`DEBUG`]: Level::DEBUG +/// [`INFO`]: Level::INFO +/// [`TRACE`]: Level::TRACE +/// [`Subscriber::enabled`]: crate::subscriber::Subscriber::enabled +/// [`Subscriber::max_level_hint`]: crate::subscriber::Subscriber::max_level_hint +/// [subscriber]: crate::subscriber::Subscriber +/// [envfilter]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Level(LevelInner); -/// A filter comparable to a verbosity `Level`. +/// A filter comparable to a verbosity [`Level`]. /// -/// If a `Level` is considered less than a `LevelFilter`, it should be +/// If a [`Level`] is considered less than a `LevelFilter`, it should be /// considered disabled; if greater than or equal to the `LevelFilter`, that /// level is enabled. /// /// Note that this is essentially identical to the `Level` type, but with the -/// addition of an `OFF` level that completely disables all trace +/// addition of an [`OFF`] level that completely disables all trace /// instrumentation. +/// +/// See the documentation for the [`Level`] type for more details. +/// +/// [`OFF`]: LevelFilter::OFF #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq)] pub struct LevelFilter(Option);