tokio_trace/level_filters.rs
1//! Trace verbosity level filtering.
2//!
3//! # Compile time filters
4//!
5//! Trace verbosity levels can be statically disabled at compile time via Cargo
6//! features, similar to the [`log` crate]. Trace instrumentation at disabled
7//! levels will be skipped and will not even be present in the resulting binary
8//! unless the verbosity level is specified dynamically. This level is
9//! configured separately for release and debug builds. The features are:
10//!
11//! * `max_level_off`
12//! * `max_level_error`
13//! * `max_level_warn`
14//! * `max_level_info`
15//! * `max_level_debug`
16//! * `max_level_trace`
17//! * `release_max_level_off`
18//! * `release_max_level_error`
19//! * `release_max_level_warn`
20//! * `release_max_level_info`
21//! * `release_max_level_debug`
22//! * `release_max_level_trace`
23//!
24//! These features control the value of the `STATIC_MAX_LEVEL` constant. The
25//! instrumentation macros macros check this value before recording an event or
26//! constructing a span. By default, no levels are disabled.
27//!
28//! For example, a crate can disable trace level instrumentation in debug builds
29//! and trace, debug, and info level instrumentation in release builds with the
30//! following configuration:
31//!
32//! ```toml
33//! [dependencies]
34//! tokio-trace = { version = "0.1", features = ["max_level_debug", "release_max_level_warn"] }
35//! ```
36//!
37//! [`log` crate]: https://docs.rs/log/0.4.6/log/#compile-time-filters
38use std::cmp::Ordering;
39use tokio_trace_core::Level;
40
41/// A filter comparable to trace verbosity `Level`.
42///
43/// If a `Level` is considered less than a `LevelFilter`, it should be
44/// considered disabled; if greater than or equal to the `LevelFilter`, that
45/// level is enabled.
46///
47/// Note that this is essentially identical to the `Level` type, but with the
48/// addition of an `OFF` level that completely disables all trace
49/// instrumentation.
50#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
51pub struct LevelFilter(Option<Level>);
52
53impl LevelFilter {
54 /// The "off" level.
55 ///
56 /// Designates that trace instrumentation should be completely disabled.
57 pub const OFF: LevelFilter = LevelFilter(None);
58 /// The "error" level.
59 ///
60 /// Designates very serious errors.
61 pub const ERROR: LevelFilter = LevelFilter(Some(Level::ERROR));
62 /// The "warn" level.
63 ///
64 /// Designates hazardous situations.
65 pub const WARN: LevelFilter = LevelFilter(Some(Level::WARN));
66 /// The "info" level.
67 ///
68 /// Designates useful information.
69 pub const INFO: LevelFilter = LevelFilter(Some(Level::INFO));
70 /// The "debug" level.
71 ///
72 /// Designates lower priority information.
73 pub const DEBUG: LevelFilter = LevelFilter(Some(Level::DEBUG));
74 /// The "trace" level.
75 ///
76 /// Designates very low priority, often extremely verbose, information.
77 pub const TRACE: LevelFilter = LevelFilter(Some(Level::TRACE));
78}
79
80impl PartialEq<LevelFilter> for Level {
81 fn eq(&self, other: &LevelFilter) -> bool {
82 match other.0 {
83 None => false,
84 Some(ref level) => self.eq(level),
85 }
86 }
87}
88
89impl PartialOrd<LevelFilter> for Level {
90 fn partial_cmp(&self, other: &LevelFilter) -> Option<Ordering> {
91 match other.0 {
92 None => Some(Ordering::Less),
93 Some(ref level) => self.partial_cmp(level),
94 }
95 }
96}
97
98/// The statically configured maximum trace level.
99///
100/// See the [module-level documentation] for information on how to configure
101/// this.
102///
103/// This value is checked by the `event!` and `span!` macros. Code that
104/// manually constructs events or spans via the `Event::record` function or
105/// `Span` constructors should compare the level against this value to
106/// determine if those spans or events are enabled.
107///
108/// [module-level documentation]: ../index.html#compile-time-filters
109pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL;
110
111cfg_if! {
112 if #[cfg(all(not(debug_assertions), feature = "release_max_level_off"))] {
113 const MAX_LEVEL: LevelFilter = LevelFilter::OFF;
114 } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_error"))] {
115 const MAX_LEVEL: LevelFilter = LevelFilter::ERROR;
116 } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_warn"))] {
117 const MAX_LEVEL: LevelFilter = LevelFilter::WARN;
118 } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_info"))] {
119 const MAX_LEVEL: LevelFilter = LevelFilter::INFO;
120 } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_debug"))] {
121 const MAX_LEVEL: LevelFilter = LevelFilter::DEBUG;
122 } else if #[cfg(all(not(debug_assertions), feature = "release_max_level_trace"))] {
123 const MAX_LEVEL: LevelFilter = LevelFilter::TRACE;
124 } else if #[cfg(feature = "max_level_off")] {
125 const MAX_LEVEL: LevelFilter = LevelFilter::OFF;
126 } else if #[cfg(feature = "max_level_error")] {
127 const MAX_LEVEL: LevelFilter = LevelFilter::ERROR;
128 } else if #[cfg(feature = "max_level_warn")] {
129 const MAX_LEVEL: LevelFilter = LevelFilter::WARN;
130 } else if #[cfg(feature = "max_level_info")] {
131 const MAX_LEVEL: LevelFilter = LevelFilter::INFO;
132 } else if #[cfg(feature = "max_level_debug")] {
133 const MAX_LEVEL: LevelFilter = LevelFilter::DEBUG;
134 } else {
135 const MAX_LEVEL: LevelFilter = LevelFilter::TRACE;
136 }
137}