tracing
tracing copied to clipboard
Non-const event level
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.
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.
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 fieldsCow<'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 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)+),
}
};
}