diff --git a/.changes/emit-traces.md b/.changes/emit-traces.md new file mode 100644 index 0000000000..569d2504fe --- /dev/null +++ b/.changes/emit-traces.md @@ -0,0 +1,5 @@ +--- +'log': 'minor:feat' +'log-js': 'minor:feat' +--- +Add a `tracing` feature to the `log` plugin that emits log messages to the `tracing` system. diff --git a/plugins/log/Cargo.toml b/plugins/log/Cargo.toml index a3b8b29037..d78d6e84e9 100644 --- a/plugins/log/Cargo.toml +++ b/plugins/log/Cargo.toml @@ -33,6 +33,8 @@ byte-unit = "5" log = { workspace = true, features = ["kv_unstable"] } time = { version = "0.3", features = ["formatting", "local-offset"] } fern = "0.7" +tracing = { workspace = true, optional = true } + [target."cfg(target_os = \"android\")".dependencies] android_logger = "0.15" @@ -47,3 +49,4 @@ objc2-foundation = { version = "0.3", default-features = false, features = [ [features] colored = ["fern/colored"] +tracing = ["dep:tracing"] diff --git a/plugins/log/src/lib.rs b/plugins/log/src/lib.rs index 9bf784c755..63e77d367a 100644 --- a/plugins/log/src/lib.rs +++ b/plugins/log/src/lib.rs @@ -197,6 +197,38 @@ impl Target { } } +// Target becomes default and location is added as a parameter +#[cfg(feature = "tracing")] +fn emit_trace( + level: log::Level, + message: &String, + location: Option<&str>, + file: Option<&str>, + line: Option, + kv: &HashMap<&str, &str>, +) { + macro_rules! emit_event { + ($level:expr) => { + tracing::event!( + target: WEBVIEW_TARGET, + $level, + message = %message, + location = location, + file, + line, + ?kv + ) + }; + } + match level { + log::Level::Error => emit_event!(tracing::Level::ERROR), + log::Level::Warn => emit_event!(tracing::Level::WARN), + log::Level::Info => emit_event!(tracing::Level::INFO), + log::Level::Debug => emit_event!(tracing::Level::DEBUG), + log::Level::Trace => emit_event!(tracing::Level::TRACE), + } +} + #[tauri::command] fn log( level: LogLevel, @@ -223,6 +255,8 @@ fn log( kv.insert(k.as_str(), v.as_str()); } builder.key_values(&kv); + #[cfg(feature = "tracing")] + emit_trace(level, &message, location, file, line, &kv); logger().log(&builder.args(format_args!("{message}")).build()); } @@ -346,7 +380,7 @@ impl Builder { /// Skip the creation and global registration of a logger /// - /// If you wish to use your own global logger, you must call `skip_logger` so that the plugin does not attempt to set a second global logger. In this configuration, no logger will be created and the plugin's `log` command will rely on the result of `log::logger()`. You will be responsible for configuring the logger yourself and any included targets will be ignored. This can also be used with `tracing-log` or if running tests in parallel that require the plugin to be registered. + /// If you wish to use your own global logger, you must call `skip_logger` so that the plugin does not attempt to set a second global logger. In this configuration, no logger will be created and the plugin's `log` command will rely on the result of `log::logger()`. You will be responsible for configuring the logger yourself and any included targets will be ignored. If ever initializing the plugin multiple times, such as if registering the plugin while testing, call this method to avoid panicking when registering multiple loggers. For interacting with `tracing`, you can leverage the `tracing-log` logger to forward logs to `tracing` or enable the `tracing` feature for this plugin to emit events directly to the tracing system. Both scenarios require calling this method. /// ```rust /// static LOGGER: SimpleLogger = SimpleLogger; ///