-
Notifications
You must be signed in to change notification settings - Fork 727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic level support #372
Comments
Another motivation: Sometimes you want the pattern
|
Here's a drop-in replacement macro_rules! event {
($level:expr, $($args:tt)*) => {{
use ::tracing::Level;
match $level {
Level::ERROR => ::tracing::event!(Level::ERROR, $($args)*),
Level::WARN => ::tracing::event!(Level::WARN, $($args)*),
Level::INFO => ::tracing::event!(Level::INFO, $($args)*),
Level::DEBUG => ::tracing::event!(Level::DEBUG, $($args)*),
Level::TRACE => ::tracing::event!(Level::TRACE, $($args)*),
}
}};
} It's probably not great when it comes to code size, but at least it works! |
#2048 would fix this, though using a dynamic level is advised against in the current shape, as
We could ignore My FFI callback hookup currently looks like this, not using #2048: /// Debug callback (after idiomatic binding bridging)
fn log(
flags: DebugFlags,
file: Option<&str>,
line: i32,
func: Option<&str>,
message: Option<&str>,
) -> Result<()> {
if flags.is_set(DebugFlags::TypeMemory) {
tracing::trace!(target: "fmod::memory", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::TypeFile) {
tracing::trace!(target: "fmod::file", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::TypeCodec) {
tracing::trace!(target: "fmod::codec", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::TypeTrace) {
tracing::trace!(target: "fmod::trace", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::LevelLog) {
tracing::info!(target: "fmod", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::LevelWarning) {
tracing::warn!(target: "fmod", parent: crate::span(), file, line, func, message)
} else if flags.is_set(DebugFlags::LevelError) {
tracing::error!(target: "fmod", parent: crate::span(), file, line, func, message)
} else {
tracing::error!(
parent: crate::span(),
debug_flags = ?flags,
file,
line,
func,
message,
);
return Err(Error::InternalRs);
};
Ok(())
}
/// FFI lib-side filtering
pub fn ideal_debug_flags() -> DebugFlags {
use tracing::{enabled, Level};
let mut debug_flags = DebugFlags::LevelNone;
if enabled!(target: "fmod", Level::ERROR, { file, line, func, message }) {
debug_flags = DebugFlags::LevelError;
}
if enabled!(target: "fmod", Level::WARN, { file, line, func, message }) {
debug_flags = DebugFlags::LevelWarning;
}
if enabled!(target: "fmod", Level::INFO, { file, line, func, message }) {
debug_flags = DebugFlags::LevelLog;
}
if enabled!(target: "fmod::trace", Level::TRACE, { file, line, func, message }) {
debug_flags |= DebugFlags::TypeTrace;
}
if enabled!(target: "fmod::memory", Level::TRACE, { file, line, func, message }) {
debug_flags |= DebugFlags::TypeMemory;
}
if enabled!(target: "fmod::file", Level::TRACE, { file, line, func, message }) {
debug_flags |= DebugFlags::TypeFile;
}
if enabled!(target: "fmod::codec", Level::TRACE, { file, line, func, message }) {
debug_flags |= DebugFlags::TypeCodec;
}
debug_flags
} |
I also need this, we maintain an http framework, and we have a middleware to instrument operations, InstrumentOperation, that opens tracing spans for requests and responses. I wanted to add a |
We also need this for gphoto2-rs where libgphoto2 invokes provided callback with logging scope, level and message and we want to translate those to |
Branching between multiple events with static levels as in #372 (comment) has worked well for me in practice, FWIW. It's a bit boilerplatey but it's only needed in one place. |
Yeah that's what we're going to go with for now, but 1) proper solution would be still nice and 2) that doesn't solve dynamic target case, only dynamic level. That comment shows branching over targets too, but in our case we only get target as a string and can't feasibly enumerate all possible targets so it will have to go into an event variable which is kind of ugly and doesn't allow filtering. |
If you don't need to control span membership (i.e. the contextual span is fine) and aren't piping in structured key/value pairs, using the Would I prefer if tracing-core natively had support for dynamic event metadata instead of tracing-log sidechanneling it in by conspiring with roughly everyone? Yeah, absolutely; I even wrote a patch to enable such. But doing so would be a fairly impactful breaking change (making |
Will using But now I'm curious, in that case how does tracing itself translate |
It should, if you're forwarding
The short answer is "macros to emulate a |
Feature Request
Motivation
Foreign libraries often (e.g. Vulkan, OpenGL, libpng) expose callbacks to report diagnostics. Piping these into
tracing
events provides pleasant user experience, but when severity is specified in an argument, generating an event of the corresponding level is difficult, as theevent
macro requires a constant argument. Additionally, it should be possible for API users to skip e.g. formatting work for structured arguments if it can be determined that an event at a certain level would not be logged.Proposal
Introduce a new form of the
event
macro that permits a dynamic level, and allow the relevance of a level to be queried dynamically.Alternatives
Continue requiring the user to write out several near-duplicate macro invocations in this case
The text was updated successfully, but these errors were encountered: