Skip to content

Commit

Permalink
tracing: add span_enabled! and event_enabled! macros (#1900)
Browse files Browse the repository at this point in the history
## Motivation

Closes #1892

## Solution

This branch adds new `span_enabled!` and `event_enabled!` macros.

I went withe sharing as much of the macro as possible. The new macros
were implemented by adding a `kind:` parameter to `enabled!`, and invoking
`enabled!` with the appropriate `kind:` argument. This means in the
docs, the macro only shows the `($($rest:tt)*)=> (...)` variant, but I
think linking to the `enabled!` docs should be fine. Also, I find the
macro pattern part of rustdoc to be very hard to understand, and I think
many people dont look at it.

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
  • Loading branch information
guswynn and hawkw committed Apr 1, 2022
1 parent bd7755f commit c9fd1d8
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 13 deletions.
118 changes: 111 additions & 7 deletions tracing/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,70 @@ macro_rules! event {
);
}

/// Tests whether an event with the specified level and target would be enabled.
///
/// This is similar to [`enabled!`], but queries the current subscriber specifically for
/// an event, whereas [`enabled!`] queries for an event _or_ span.
///
/// See the documentation for [`enabled!]` for more details on using this macro.
/// See also [`span_enabled!`].
///
/// # Examples
///
/// ```rust
/// # use tracing::{event_enabled, Level};
/// if event_enabled!(target: "my_crate", Level::DEBUG) {
/// // some expensive work...
/// }
/// // simpler
/// if event_enabled!(Level::DEBUG) {
/// // some expensive work...
/// }
/// // with fields
/// if event_enabled!(Level::DEBUG, foo_field) {
/// // some expensive work...
/// }
/// ```
///
#[macro_export]
macro_rules! event_enabled {
($($rest:tt)*)=> (
$crate::enabled!(kind: $crate::metadata::Kind::EVENT, $($rest)*)
)
}

/// Tests whether a span with the specified level and target would be enabled.
///
/// This is similar to [`enabled!`], but queries the current subscriber specifically for
/// an event, whereas [`enabled!`] queries for an event _or_ span.
///
/// See the documentation for [`enabled!]` for more details on using this macro.
/// See also [`span_enabled!`].
///
/// # Examples
///
/// ```rust
/// # use tracing::{span_enabled, Level};
/// if span_enabled!(target: "my_crate", Level::DEBUG) {
/// // some expensive work...
/// }
/// // simpler
/// if span_enabled!(Level::DEBUG) {
/// // some expensive work...
/// }
/// // with fields
/// if span_enabled!(Level::DEBUG, foo_field) {
/// // some expensive work...
/// }
/// ```
///
#[macro_export]
macro_rules! span_enabled {
($($rest:tt)*)=> (
$crate::enabled!(kind: $crate::metadata::Kind::SPAN, $($rest)*)
)
}

/// Checks whether a span or event is [enabled] based on the provided [metadata].
///
/// [enabled]: crate::Subscriber::enabled
Expand Down Expand Up @@ -884,9 +948,21 @@ macro_rules! event {
/// }
/// ```
///
/// # Alternatives
///
/// `enabled!` queries subscribers with [`Metadata`] where
/// [`is_event`] and [`is_span`] both return `false`. Alternatively,
/// use [`event_enabled!`] or [`span_enabled!`] to ensure one of these
/// returns true.
///
///
/// [`Metadata`]: crate::Metadata
/// [`is_event`]: crate::Metadata::is_event
/// [`is_span`]: crate::Metadata::is_span
///
#[macro_export]
macro_rules! enabled {
(target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
(kind: $kind:expr, target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> ({
if $crate::level_enabled!($lvl) {
use $crate::__macro_support::Callsite as _;
static CALLSITE: $crate::__macro_support::MacroCallsite = $crate::callsite2! {
Expand All @@ -896,7 +972,7 @@ macro_rules! enabled {
":",
line!()
),
kind: $crate::metadata::Kind::HINT,
kind: $kind.hint(),
target: $target,
level: $lvl,
fields: $($fields)*
Expand All @@ -913,29 +989,57 @@ macro_rules! enabled {
}
});
// Just target and level
(kind: $kind:expr, target: $target:expr, $lvl:expr ) => (
$crate::enabled!(kind: $kind, target: $target, $lvl, { })
);
(target: $target:expr, $lvl:expr ) => (
$crate::enabled!(target: $target, $lvl, { })
$crate::enabled!(kind: $crate::metadata::Kind::HINT, target: $target, $lvl, { })
);

// These two cases handle fields with no values
// These four cases handle fields with no values
(kind: $kind:expr, target: $target:expr, $lvl:expr, $($field:tt)*) => (
$crate::enabled!(
kind: $kind,
target: $target,
$lvl,
{ $($field)*}
)
);
(target: $target:expr, $lvl:expr, $($field:tt)*) => (
$crate::enabled!(
kind: $crate::metadata::Kind::HINT,
target: $target,
$lvl,
{ $($field)*}
)
);
($lvl:expr, $($field:tt)*) => (

// Level and field case
(kind: $kind:expr, $lvl:expr, $($field:tt)*) => (
$crate::enabled!(
kind: $kind,
target: module_path!(),
$lvl,
{ $($field)*}
)
);

// Simplest `enabled!` case
( $lvl:expr ) => (
$crate::enabled!(target: module_path!(), $lvl, { })
(kind: $kind:expr, $lvl:expr) => (
$crate::enabled!(kind: $kind, target: module_path!(), $lvl, { })
);
($lvl:expr) => (
$crate::enabled!(kind: $crate::metadata::Kind::HINT, target: module_path!(), $lvl, { })
);

// Fallthrough from above
($lvl:expr, $($field:tt)*) => (
$crate::enabled!(
kind: $crate::metadata::Kind::HINT,
target: module_path!(),
$lvl,
{ $($field)*}
)
);
}

Expand Down
38 changes: 34 additions & 4 deletions tracing/tests/enabled.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![cfg(feature = "std")]
use tracing::Level;
use tracing_mock::*;

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn level_and_target() {
let (subscriber, handle) = subscriber::mock()
let subscriber = subscriber::mock()
.with_filter(|meta| {
if meta.target() == "debug_module" {
meta.level() <= &Level::DEBUG
Expand All @@ -13,12 +14,41 @@ fn level_and_target() {
}
})
.done()
.run_with_handle();
.run();

tracing::subscriber::set_global_default(subscriber).unwrap();
let _guard = tracing::subscriber::set_default(subscriber);

assert!(tracing::enabled!(target: "debug_module", Level::DEBUG));
assert!(tracing::enabled!(Level::ERROR));
assert!(!tracing::enabled!(Level::DEBUG));
handle.assert_finished();
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn span_and_event() {
let subscriber = subscriber::mock()
.with_filter(|meta| {
if meta.target() == "debug_module" {
meta.level() <= &Level::DEBUG
} else if meta.is_span() {
meta.level() <= &Level::TRACE
} else if meta.is_event() {
meta.level() <= &Level::DEBUG
} else {
meta.level() <= &Level::INFO
}
})
.done()
.run();

let _guard = tracing::subscriber::set_default(subscriber);

// Ensure that the `_event` and `_span` alternatives work corretly
assert!(!tracing::event_enabled!(Level::TRACE));
assert!(tracing::event_enabled!(Level::DEBUG));
assert!(tracing::span_enabled!(Level::TRACE));

// target variants
assert!(tracing::span_enabled!(target: "debug_module", Level::DEBUG));
assert!(tracing::event_enabled!(target: "debug_module", Level::DEBUG));
}
32 changes: 30 additions & 2 deletions tracing/tests/macros.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![deny(warnings)]
use tracing::{
callsite, debug, debug_span, enabled, error, error_span, event, info, info_span, span, trace,
trace_span, warn, warn_span, Level,
callsite, debug, debug_span, enabled, error, error_span, event, event_enabled, info, info_span,
span, span_enabled, trace, trace_span, warn, warn_span, Level,
};

// Tests that macros work across various invocation syntax.
Expand Down Expand Up @@ -348,6 +348,34 @@ fn enabled() {
enabled!(target: "rando", Level::DEBUG, field);
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn span_enabled() {
span_enabled!(Level::DEBUG, foo, bar.baz, quux,);
span_enabled!(Level::DEBUG, message);
span_enabled!(Level::INFO, foo, bar.baz, quux, message,);
span_enabled!(Level::INFO, foo, bar., message,);
span_enabled!(Level::DEBUG, foo);

span_enabled!(Level::DEBUG);
span_enabled!(target: "rando", Level::DEBUG);
span_enabled!(target: "rando", Level::DEBUG, field);
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn event_enabled() {
event_enabled!(Level::DEBUG, foo, bar.baz, quux,);
event_enabled!(Level::DEBUG, message);
event_enabled!(Level::INFO, foo, bar.baz, quux, message,);
event_enabled!(Level::INFO, foo, bar., message,);
event_enabled!(Level::DEBUG, foo);

event_enabled!(Level::DEBUG);
event_enabled!(target: "rando", Level::DEBUG);
event_enabled!(target: "rando", Level::DEBUG, field);
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn locals_with_message() {
Expand Down

0 comments on commit c9fd1d8

Please sign in to comment.