From 024815018fbc63a37afc716796a454925aa7d25e Mon Sep 17 00:00:00 2001 From: Jim <8757851+3lpsy@users.noreply.github.com> Date: Sat, 1 Mar 2025 09:20:18 -0600 Subject: [PATCH] feat(log): Add `skip_logger` setting (#2377) --- .changes/skip-logger.md | 5 +++++ plugins/log/src/lib.rs | 45 +++++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 .changes/skip-logger.md diff --git a/.changes/skip-logger.md b/.changes/skip-logger.md new file mode 100644 index 00000000..d5066491 --- /dev/null +++ b/.changes/skip-logger.md @@ -0,0 +1,5 @@ +--- +'log': 'minor:feat' +'log-js': 'minor:feat' +--- +Add a `is_skip_logger` flag to the Log Plugin `Builder` struct, a `skip_logger()` method to the Builder, and logic to avoid acquiring (creating) a logger and attaching it to the global logger. Since acquire_logger is pub, a `LoggerNotInitialized` is added and returned if it's called when the `is_skip_looger` flag is set. Overall, this feature permits a user to avoid calling `attach_logger` which can only be called once in a program's lifetime and allows the user to control the logger returned from `logger()`. Additionally, it also will allow users to generate multiple Tauri Mock apps in test suites that run and parallel and have the `log` plugin attached (assuming they use `skip_logger()`). diff --git a/plugins/log/src/lib.rs b/plugins/log/src/lib.rs index 9f9a4adf..7cb4a526 100644 --- a/plugins/log/src/lib.rs +++ b/plugins/log/src/lib.rs @@ -58,6 +58,8 @@ pub enum Error { TimeFormat(#[from] time::error::Format), #[error(transparent)] InvalidFormatDescription(#[from] time::error::InvalidFormatDescription), + #[error("Internal logger disabled and cannot be acquired or attached")] + LoggerNotInitialized, } /// An enum representing the available verbosity levels of the logger. @@ -230,6 +232,7 @@ pub struct Builder { timezone_strategy: TimezoneStrategy, max_file_size: u128, targets: Vec, + is_skip_logger: bool, } impl Default for Builder { @@ -258,6 +261,7 @@ impl Default for Builder { timezone_strategy: DEFAULT_TIMEZONE_STRATEGY, max_file_size: DEFAULT_MAX_FILE_SIZE, targets: DEFAULT_LOG_TARGETS.into(), + is_skip_logger: false, } } } @@ -339,6 +343,22 @@ impl Builder { self } + /// 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. + /// ```rust + /// static LOGGER: SimpleLogger = SimpleLogger; + /// + /// log::set_logger(&SimpleLogger)?; + /// log::set_max_level(LevelFilter::Info); + /// tauri_plugin_log::Builder::new() + /// .skip_logger(); + /// ``` + pub fn skip_logger(mut self) -> Self { + self.is_skip_logger = true; + self + } + /// Adds a collection of targets to the logger. /// /// ```rust @@ -481,6 +501,9 @@ impl Builder { self, app_handle: &AppHandle, ) -> Result<(TauriPlugin, log::LevelFilter, Box), Error> { + if self.is_skip_logger { + return Err(Error::LoggerNotInitialized); + } let plugin = Self::plugin_builder(); let (max_level, log) = Self::acquire_logger( app_handle, @@ -497,17 +520,17 @@ impl Builder { pub fn build(self) -> TauriPlugin { Self::plugin_builder() .setup(move |app_handle, _api| { - let (max_level, log) = Self::acquire_logger( - app_handle, - self.dispatch, - self.rotation_strategy, - self.timezone_strategy, - self.max_file_size, - self.targets, - )?; - - attach_logger(max_level, log)?; - + if !self.is_skip_logger { + let (max_level, log) = Self::acquire_logger( + app_handle, + self.dispatch, + self.rotation_strategy, + self.timezone_strategy, + self.max_file_size, + self.targets, + )?; + attach_logger(max_level, log)?; + } Ok(()) }) .build()