tracing icon indicating copy to clipboard operation
tracing copied to clipboard

Non-const event level

Open Victor-N-Suadicani opened this issue 10 months ago • 3 comments

Feature Request

Crates

tracing

Motivation

Currently, this code is impossible it seems:

let level = tracing::Level::DEBUG; // Imagine this is decided at runtime.
tracing::event!(level, "foobar"); // ERROR: attempt to use non-constant value in a constant

This is surprising to me because the equivalent in the log crate just works (TM):

let level = log::Level::Debug;
log::log!(level, "foobar"); // Works fine :)

This is useful to decide at runtime what log level to use for an error based on its variant, just as an example. Some variants are perhaps expected, while others are rarer. The expected ones you would like to log at debug and the rare ones at error. The log crate supports this easily, tracing seems not to for some reason.

Proposal

Make it so this compiles:

let level = tracing::Level::DEBUG;
tracing::event!(level, "foobar");

Alternatives

I personally don't know of any other (just as easy) way to achieve this but I'd love to know.

Victor-N-Suadicani avatar Sep 28 '23 10:09 Victor-N-Suadicani

Thanks for opening this issue and sorry for taking a second to respond. tracing requires metadata fields like be 'static In order to enable fast filtering of events/spans. log doesn't have this requirement because it prioritizes (prioritized?) FFI with non-Rust libraries, whose log metadata might not be 'static.

I suppose this is a decision that can be revisited in future versions of tracing (in that making fields Cow<'static> is something that's already in the cards), but I don't recall what the implications are for doing something similar to metadata.

davidbarsky avatar Oct 02 '23 13:10 davidbarsky

Thanks for opening this issue and sorry for taking a second to respond. tracing requires metadata fields like be 'static In order to enable fast filtering of events/spans. log doesn't have this requirement because it prioritizes (prioritized?) FFI with non-Rust libraries, whose log metadata might not be 'static.

I suppose this is a decision that can be revisited in future versions of tracing (in that making fields Cow<'static> is something that's already in the cards), but I don't recall what the implications are for doing something similar to metadata.

Do you know if it is possible to work around this, possibly even to create events dynamically at runtime?

My current use case involves a plugin system which generates a log event (my own custom struct with a module and file path), and I would like to output these as first class tracing events with the correct log levels, rather than a new debug!("{}: {}", event.module, event.message) which has the callsite of the facade, and not the producer.

If that is not possible, would it be possible to workaround a non-const event level, other than a match statement for each log level which repeats the event macro?

ten3roberts avatar Dec 17 '23 17:12 ten3roberts

@ten3roberts you could pass the macro token token fragments that you'd normally pass into event macros through a match arm along with a Level:

#[macro_export]
macro_rules! dyn_event {
    ($lvl:ident, $($arg:tt)+) => {
        match $lvl {
            ::tracing::Level::TRACE => ::tracing::trace!($($arg)+),
            ::tracing::Level::DEBUG => ::tracing::debug!($($arg)+),
            ::tracing::Level::INFO => ::tracing::info!($($arg)+),
            ::tracing::Level::WARN => ::tracing::warn!($($arg)+),
            ::tracing::Level::ERROR => ::tracing::error!($($arg)+),
        }
    };
}

mkatychev avatar Feb 14 '24 03:02 mkatychev