diff --git a/CHANGELOG.md b/CHANGELOG.md index 77be840..de269ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file. * `Record::payload` is now `std::fmt::Arguments` instead of `Cow<'static, str>`. * `RecordOwned::as_record` has been removed; use `RecordOwned::with` instead. (This is a limitation of Rust as described [here](https://github.com/rust-lang/rust/issues/92698#issuecomment-3311144848).) * `logforth_core::Error::with_source` now set the optional source field instead of append a sources list. +* `logforth_core::kv` has been totally redesigned to decouple from `value-bag`. See [PR-229](https://github.com/fast/logforth/pull/229) for details. +* `logforth_core::filter::env_filter` is now factored out into `logforth-filter-rustlog` crate. `EnvFilter` is renamed to `RustLogFilter`. So do other related types and feature flags. ## [0.29.1] 2025-11-03 diff --git a/Cargo.toml b/Cargo.toml index fd8e3c3..2ef7aac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = [ "appenders/*", "bridges/*", "diagnostics/*", + "filters/*", "layouts/*", "xtask", ] @@ -47,6 +48,7 @@ logforth-bridge-log = { version = "0.3.0", path = "bridges/log" } logforth-core = { version = "0.3.1", path = "core" } logforth-diagnostic-fastrace = { version = "0.3.0", path = "diagnostics/fastrace" } logforth-diagnostic-task-local = { version = "0.3.0", path = "diagnostics/task-local" } +logforth-filter-rustlog = { version = "0.1.0", path = "filters/rustlog" } logforth-layout-google-cloud-logging = { version = "0.3.0", path = "layouts/google-cloud-logging" } logforth-layout-json = { version = "0.3.0", path = "layouts/json" } logforth-layout-logfmt = { version = "0.3.0", path = "layouts/logfmt" } diff --git a/bridges/log/src/lib.rs b/bridges/log/src/lib.rs index e521db9..960a306 100644 --- a/bridges/log/src/lib.rs +++ b/bridges/log/src/lib.rs @@ -27,12 +27,12 @@ use logforth_core::record::FilterCriteria; /// Adapter to use a `logforth` logger instance as a `log` crate logger. #[derive(Debug)] -pub struct LogAdapter { +pub struct LogBridge { logger: Arc, } -impl LogAdapter { - /// Create a new `LogAdapter` instance. +impl LogBridge { + /// Create a new `LogBridge` instance. pub fn new(logger: impl Into>) -> Self { Self { logger: logger.into(), @@ -40,7 +40,7 @@ impl LogAdapter { } } -impl Deref for LogAdapter { +impl Deref for LogBridge { type Target = Logger; fn deref(&self) -> &Self::Target { @@ -48,7 +48,7 @@ impl Deref for LogAdapter { } } -impl log::Log for LogAdapter { +impl log::Log for LogBridge { fn enabled(&self, metadata: &Metadata) -> bool { forward_enabled(&self.logger, metadata) } diff --git a/core/Cargo.toml b/core/Cargo.toml index 4516093..4bffb8b 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -41,8 +41,5 @@ anyhow = { workspace = true } # Optional dependencies serde = { workspace = true, optional = true } -[dev-dependencies] -insta = { workspace = true } - [lints] workspace = true diff --git a/core/src/filter/mod.rs b/core/src/filter/mod.rs index 2bbd212..3fc4786 100644 --- a/core/src/filter/mod.rs +++ b/core/src/filter/mod.rs @@ -21,10 +21,6 @@ use crate::record::FilterCriteria; use crate::record::LevelFilter; use crate::record::Record; -pub mod env_filter; - -pub use self::env_filter::EnvFilter; - /// The result of a filter check. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum FilterResult { diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 98a9b87..7b72c8d 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -48,6 +48,9 @@ layout-text = ["logforth/layout-text"] diagnostic-fastrace = ["logforth/diagnostic-fastrace"] diagnostic-task-local = ["logforth/diagnostic-task-local"] +# Filters +filter-rustlog = ["logforth/filter-rustlog"] + [dependencies] logforth = { workspace = true } diff --git a/examples/src/asynchronous.rs b/examples/src/asynchronous.rs index 9f69dd9..e33ff01 100644 --- a/examples/src/asynchronous.rs +++ b/examples/src/asynchronous.rs @@ -14,7 +14,7 @@ use logforth::append::asynchronous::AsyncBuilder; use logforth::append::file::FileBuilder; -use logforth::bridge::log::LogAdapter; +use logforth::bridge::log::LogBridge; use logforth::layout::JsonLayout; use logforth::record::LevelFilter; @@ -31,7 +31,7 @@ fn main() { .dispatch(|d| d.filter(LevelFilter::All).append(asynchronous)) .build(); - log::set_boxed_logger(Box::new(LogAdapter::new(logger))).unwrap(); + log::set_boxed_logger(Box::new(LogBridge::new(logger))).unwrap(); log::set_max_level(log::LevelFilter::Trace); log::error!("Hello single error!"); diff --git a/examples/src/log_with_logger.rs b/examples/src/log_with_logger.rs index 16d2271..0cf8832 100644 --- a/examples/src/log_with_logger.rs +++ b/examples/src/log_with_logger.rs @@ -13,7 +13,7 @@ // limitations under the License. use logforth::append; -use logforth::bridge::log::LogAdapter; +use logforth::bridge::log::LogBridge; fn main() { log::set_max_level(log::LevelFilter::Trace); @@ -22,7 +22,7 @@ fn main() { .dispatch(|d| d.append(append::Stdout::default())) .build(); - let l = LogAdapter::new(l); + let l = LogBridge::new(l); log::error!(logger: l, "Hello error!"); log::warn!(logger: l, "Hello warn!"); log::info!(logger: l, "Hello info!"); diff --git a/examples/src/per_module_log_levels.rs b/examples/src/per_module_log_levels.rs index 45fa417..38c7751 100644 --- a/examples/src/per_module_log_levels.rs +++ b/examples/src/per_module_log_levels.rs @@ -13,15 +13,15 @@ // limitations under the License. use logforth::append; -use logforth::filter::env_filter::EnvFilterBuilder; +use logforth::filter::rustlog::RustLogFilterBuilder; use logforth::record::Level; use logforth::record::LevelFilter; fn main() { // This is how you can allow trace level logs for everything else while silencing them // for the ones you probably don't need (in this case various rerun modules). - let my_filter = EnvFilterBuilder::from_default_env() - .filter_level(LevelFilter::MoreSevereEqual(logforth::record::Level::Trace)) + let my_filter = RustLogFilterBuilder::from_default_env() + .filter_level(LevelFilter::MoreSevereEqual(Level::Trace)) .filter_module("rerun", LevelFilter::MoreSevereEqual(Level::Warn)) .filter_module("re_chunk", LevelFilter::MoreSevereEqual(Level::Warn)) .filter_module("re_log", LevelFilter::MoreSevereEqual(Level::Warn)) diff --git a/examples/src/per_module_with_ctor.rs b/examples/src/per_module_with_ctor.rs index 5eccd6a..6249191 100644 --- a/examples/src/per_module_with_ctor.rs +++ b/examples/src/per_module_with_ctor.rs @@ -17,8 +17,8 @@ use std::sync::OnceLock; use std::sync::RwLock; use logforth::append::Stdout; -use logforth::filter::EnvFilter; -use logforth::filter::env_filter::EnvFilterBuilder; +use logforth::filter::RustLogFilter; +use logforth::filter::rustlog::RustLogFilterBuilder; use logforth::record::Level; use logforth::starter_log; @@ -59,7 +59,7 @@ fn main() { .filter( FILTER .get_or_init(|| Filter::new(Level::Info)) - .build_env_filter(), + .build_rustlog_filter(), ) .append(Stdout::default()) }) @@ -91,7 +91,7 @@ impl Filter { module_levels.insert(module_path.to_string(), level); } - pub fn build_env_filter(&self) -> EnvFilter { + pub fn build_rustlog_filter(&self) -> RustLogFilter { let module_levels = self.module_levels.read().expect("filter read is poisoned"); let mut directives = vec![self.default_level.name().to_string()]; @@ -100,6 +100,6 @@ impl Filter { directives.push(format!("{module_path}={}", level.name())); } - EnvFilterBuilder::from_spec(directives.join(",")).build() + RustLogFilterBuilder::from_spec(directives.join(",")).build() } } diff --git a/filters/rustlog/Cargo.toml b/filters/rustlog/Cargo.toml new file mode 100644 index 0000000..0df4d83 --- /dev/null +++ b/filters/rustlog/Cargo.toml @@ -0,0 +1,37 @@ +# Copyright 2024 FastLabs Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[package] +name = "logforth-filter-rustlog" +version = "0.1.0" + +description = "RUST_LOG directive pattern filter for Logforth." +keywords = ["logging", "log", "fastrace"] + +categories.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +rust-version.workspace = true + +[dependencies] +logforth-core = { workspace = true } + +[dev-dependencies] +insta = { workspace = true } + +[lints] +workspace = true diff --git a/core/src/filter/env_filter/README.md b/filters/rustlog/README.md similarity index 91% rename from core/src/filter/env_filter/README.md rename to filters/rustlog/README.md index ac2be08..209494a 100644 --- a/core/src/filter/env_filter/README.md +++ b/filters/rustlog/README.md @@ -1,4 +1,4 @@ -# RUST_LOG Environment Variable Filter +# Logforth RUST_LOG Filter This filter is derived by [env_filter](https://crates.io/crates/env_filter), with significant modifications to suit our needs: diff --git a/core/src/filter/env_filter/mod.rs b/filters/rustlog/src/lib.rs similarity index 80% rename from core/src/filter/env_filter/mod.rs rename to filters/rustlog/src/lib.rs index 5edcbe6..b9cb8d5 100644 --- a/core/src/filter/env_filter/mod.rs +++ b/filters/rustlog/src/lib.rs @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! A filter that can be configured via environment variables. +//! A filter that follows the famous `RUST_LOG` directive pattern. //! //! Log levels are controlled on a per-module basis, and by default all logging is disabled except //! for the `error` level. //! -//! Despite having "env" in its name, you can also use [`EnvFilterBuilder::from_spec`] to configure -//! the filter by directly passing a specification string. +//! You can use [`RustLogFilterBuilder::from_default_env`] to configure the filter from the +//! `RUST_LOG` environment variable, or [`RustLogFilterBuilder::from_spec`] to configure the +//! filter by directly passing a specification string. //! //! The specification string is a comma-separated list of logging directives. A logging directive is //! of the form: @@ -29,7 +30,7 @@ //! //! `target` is typically `path::to::module`, but it may also be set manually via the log macros. //! -//! The path to the module is rooted in the name of the crate it was compiled for, so if your +//! The path to the module is rooted in the name of the crate it was compiled for. Thus, if your //! program is contained in a file `hello.rs`, for example, to turn on logging for this file you //! would use a value of `RUST_LOG=hello`. Furthermore, this path is a prefix-search, so all modules //! nested in the specified module will also have logging enabled. @@ -38,8 +39,9 @@ //! If omitted, all logging for the item (and its children) will be enabled. //! //! The names of the log levels that may be specified correspond to the variations of the [`Level`] -//! enum from this crate. They are: +//! enum. The most common used levels include: //! +//! * `fatal` //! * `error` //! * `warn` //! * `info` @@ -53,7 +55,7 @@ //! As the log level for a module is optional, the module to enable logging for is also optional. If //! only a level is provided, then the global log level for all modules is set to this value. //! -//! Some examples of valid values are: +//! Some examples of valid values are: //! //! * `hello` turns on all logging for the 'hello' module //! * `trace` turns on all logging for the application, regardless of its name @@ -63,21 +65,21 @@ //! * `hello=debug` turns on debug logging for 'hello' //! * `hello=DEBUG` turns on debug logging for 'hello' (same as previous) //! * `hello,std::option` turns on hello, and std's option logging -//! * `error,hello=warn` turn on global error logging and also warn for hello -//! * `error,hello=off` turn on global error logging, but turn off logging for hello +//! * `error,hello=warn` turns on global error logging and also warn for hello +//! * `error,hello=off` turns on global error logging, but turn off logging for hello //! * `off` turns off all logging for the application //! * `OFF` turns off all logging for the application (same as previous) use std::borrow::Cow; use std::str::FromStr; -use crate::Diagnostic; -use crate::Error; -use crate::Filter; -use crate::filter::FilterResult; -use crate::record::FilterCriteria; -use crate::record::Level; -use crate::record::LevelFilter; +use logforth_core::Diagnostic; +use logforth_core::Error; +use logforth_core::Filter; +use logforth_core::filter::FilterResult; +use logforth_core::record::FilterCriteria; +use logforth_core::record::Level; +use logforth_core::record::LevelFilter; #[cfg(test)] mod tests; @@ -93,23 +95,23 @@ pub const DEFAULT_FILTER_ENV: &str = "RUST_LOG"; /// Less exclusive levels (like `trace` or `info`) are considered to be more verbose than more /// exclusive levels (like `error` or `warn`). /// -/// Read more from the [module level documentation](self) about the directive syntax and use cases. +/// Read more from the [crate level documentation](self) about the directive syntax and use cases. /// -/// [`Record`]: crate::record::Record +/// [`Record`]: logforth_core::record::Record #[derive(Debug)] -pub struct EnvFilter { +pub struct RustLogFilter { directives: Vec, } -impl EnvFilter { +impl RustLogFilter { fn from_directives(directives: Vec) -> Self { let mut directives = directives; directives.sort(); - EnvFilter { directives } + RustLogFilter { directives } } } -impl Filter for EnvFilter { +impl Filter for RustLogFilter { fn enabled(&self, criteria: &FilterCriteria, _: &[Box]) -> FilterResult { let level = criteria.level(); let target = criteria.target(); @@ -131,46 +133,46 @@ impl Filter for EnvFilter { } } -impl From for EnvFilter { +impl From for RustLogFilter { fn from(filter: LevelFilter) -> Self { - EnvFilterBuilder::default().filter_level(filter).build() + RustLogFilterBuilder::default().filter_level(filter).build() } } -impl<'a> From<&'a str> for EnvFilter { +impl<'a> From<&'a str> for RustLogFilter { fn from(filter: &'a str) -> Self { - EnvFilterBuilder::from_spec(filter).build() + RustLogFilterBuilder::from_spec(filter).build() } } -impl FromStr for EnvFilter { +impl FromStr for RustLogFilter { type Err = Error; fn from_str(s: &str) -> Result { - EnvFilterBuilder::try_from_spec(s).map(|b| b.build()) + RustLogFilterBuilder::try_from_spec(s).map(|b| b.build()) } } -/// A builder for [`EnvFilter`]. +/// A builder for [`RustLogFilter`]. /// -/// It can be used to parse a set of directives from a string before building an [`EnvFilter`] +/// It can be used to parse a set of directives from a string before building an [`RustLogFilter`] /// instance. /// /// ## Example /// /// ``` -/// use logforth_core::filter::env_filter::EnvFilterBuilder; +/// use logforth_filter_rustlog::RustLogFilterBuilder; /// /// // Parse the filter from the default environment variable `RUST_LOG`. -/// let builder = EnvFilterBuilder::from_default_env(); +/// let builder = RustLogFilterBuilder::from_default_env(); /// let filter = builder.build(); /// ``` #[derive(Debug, Default)] -pub struct EnvFilterBuilder { +pub struct RustLogFilterBuilder { directives: Vec, } -impl EnvFilterBuilder { +impl RustLogFilterBuilder { /// Initialize the filter builder from the environment using default variable name `RUST_LOG`. /// /// # Examples @@ -178,12 +180,12 @@ impl EnvFilterBuilder { /// Initialize a filter using the default environment variables: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::from_default_env().build(); + /// let filter = RustLogFilterBuilder::from_default_env().build(); /// ``` pub fn from_default_env() -> Self { - EnvFilterBuilder::from_env(DEFAULT_FILTER_ENV) + RustLogFilterBuilder::from_env(DEFAULT_FILTER_ENV) } /// Initialize the filter builder from the environment using default variable name `RUST_LOG`. @@ -195,15 +197,15 @@ impl EnvFilterBuilder { /// value: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::from_default_env_or("info").build(); + /// let filter = RustLogFilterBuilder::from_default_env_or("info").build(); /// ``` pub fn from_default_env_or<'a, V>(default: V) -> Self where V: Into>, { - EnvFilterBuilder::from_env_or(DEFAULT_FILTER_ENV, default) + RustLogFilterBuilder::from_env_or(DEFAULT_FILTER_ENV, default) } /// Initialize the filter builder from the environment using specific variable name. @@ -213,11 +215,11 @@ impl EnvFilterBuilder { /// Initialize a filter using the using specific variable name: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::from_env("MY_LOG").build(); + /// let filter = RustLogFilterBuilder::from_env("MY_LOG").build(); /// ``` - pub fn from_env<'a, V>(name: V) -> EnvFilterBuilder + pub fn from_env<'a, V>(name: V) -> RustLogFilterBuilder where V: Into>, { @@ -238,9 +240,9 @@ impl EnvFilterBuilder { /// value: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::from_env_or("MY_LOG", "info").build(); + /// let filter = RustLogFilterBuilder::from_env_or("MY_LOG", "info").build(); /// ``` pub fn from_env_or<'a, 'b, E, V>(name: E, default: V) -> Self where @@ -264,9 +266,9 @@ impl EnvFilterBuilder { /// Initialize a filter using the passed RUST_LOG specification: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::from_spec("info,my_crate=debug").build(); + /// let filter = RustLogFilterBuilder::from_spec("info,my_crate=debug").build(); /// ``` pub fn from_spec<'a, V>(spec: V) -> Self where @@ -277,7 +279,7 @@ impl EnvFilterBuilder { for error in errors { eprintln!("warning: {error}, ignoring it"); } - let mut builder = EnvFilterBuilder::default(); + let mut builder = RustLogFilterBuilder::default(); for directive in directives { builder.upsert_directive(directive); } @@ -291,9 +293,9 @@ impl EnvFilterBuilder { /// Initialize a filter using the passed RUST_LOG specification: /// /// ``` - /// use logforth_core::filter::env_filter::EnvFilterBuilder; + /// use logforth_filter_rustlog::RustLogFilterBuilder; /// - /// let filter = EnvFilterBuilder::try_from_spec("info,my_crate=debug") + /// let filter = RustLogFilterBuilder::try_from_spec("info,my_crate=debug") /// .unwrap() /// .build(); /// ``` @@ -306,27 +308,27 @@ impl EnvFilterBuilder { if let Some(error) = errors.into_iter().next() { return Err(Error::new(error)); } - let mut builder = EnvFilterBuilder::default(); + let mut builder = RustLogFilterBuilder::default(); for directive in directives { builder.upsert_directive(directive); } Ok(builder) } - /// Consume the builder to produce an [`EnvFilter`]. + /// Consume the builder to produce an [`RustLogFilter`]. /// /// If the builder has no directives configured, a default directive of the `error` level will /// be added. - pub fn build(self) -> EnvFilter { + pub fn build(self) -> RustLogFilter { let Self { directives } = self; if directives.is_empty() { - EnvFilter::from_directives(vec![Directive { + RustLogFilter::from_directives(vec![Directive { name: None, level: LevelFilter::MoreSevereEqual(Level::Error), }]) } else { - EnvFilter::from_directives(directives) + RustLogFilter::from_directives(directives) } } diff --git a/core/src/filter/env_filter/tests.rs b/filters/rustlog/src/tests.rs similarity index 90% rename from core/src/filter/env_filter/tests.rs rename to filters/rustlog/src/tests.rs index 0a2c514..522fbe1 100644 --- a/core/src/filter/env_filter/tests.rs +++ b/filters/rustlog/src/tests.rs @@ -13,19 +13,19 @@ // limitations under the License. use insta::assert_snapshot; - -use crate::Filter; -use crate::filter::EnvFilter; -use crate::filter::FilterResult; -use crate::filter::env_filter::Directive; -use crate::filter::env_filter::EnvFilterBuilder; -use crate::filter::env_filter::ParseResult; -use crate::filter::env_filter::parse_spec; -use crate::record::FilterCriteria; -use crate::record::Level; -use crate::record::LevelFilter; - -impl EnvFilter { +use logforth_core::Filter; +use logforth_core::filter::FilterResult; +use logforth_core::record::FilterCriteria; +use logforth_core::record::Level; +use logforth_core::record::LevelFilter; + +use crate::Directive; +use crate::ParseResult; +use crate::RustLogFilter; +use crate::RustLogFilterBuilder; +use crate::parse_spec; + +impl RustLogFilter { fn rejected(&self, level: Level, target: &str) -> bool { let criteria = FilterCriteria::builder() .level(level) @@ -328,7 +328,7 @@ fn parse_error_message_multiple_errors() { #[test] fn filter_info() { - let logger = EnvFilterBuilder::default() + let logger = RustLogFilterBuilder::default() .filter_level(LevelFilter::MoreSevereEqual(Level::Info)) .build(); assert!(!logger.rejected(Level::Info, "crate1")); @@ -337,7 +337,7 @@ fn filter_info() { #[test] fn filter_beginning_longest_match() { - let logger = EnvFilterBuilder::default() + let logger = RustLogFilterBuilder::default() .filter_module("crate2", LevelFilter::MoreSevereEqual(Level::Info)) .filter_module("crate2::mod", LevelFilter::MoreSevereEqual(Level::Debug)) .filter_module("crate1::mod1", LevelFilter::MoreSevereEqual(Level::Warn)) @@ -391,14 +391,14 @@ fn ensure_tests_cover_level_universe() { #[test] fn parse_default() { - let logger = EnvFilterBuilder::from_spec("info,crate1::mod1=warn").build(); + let logger = RustLogFilterBuilder::from_spec("info,crate1::mod1=warn").build(); assert!(!logger.rejected(Level::Warn, "crate1::mod1")); assert!(!logger.rejected(Level::Info, "crate2::mod2")); } #[test] fn parse_default_bare_level_off_lc() { - let logger = EnvFilterBuilder::from_spec("off").build(); + let logger = RustLogFilterBuilder::from_spec("off").build(); assert!(logger.rejected(Level::Error, "")); assert!(logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -408,7 +408,7 @@ fn parse_default_bare_level_off_lc() { #[test] fn parse_default_bare_level_off_uc() { - let logger = EnvFilterBuilder::from_spec("OFF").build(); + let logger = RustLogFilterBuilder::from_spec("OFF").build(); assert!(logger.rejected(Level::Error, "")); assert!(logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -418,7 +418,7 @@ fn parse_default_bare_level_off_uc() { #[test] fn parse_default_bare_level_error_lc() { - let logger = EnvFilterBuilder::from_spec("error").build(); + let logger = RustLogFilterBuilder::from_spec("error").build(); assert!(!logger.rejected(Level::Error, "")); assert!(logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -428,7 +428,7 @@ fn parse_default_bare_level_error_lc() { #[test] fn parse_default_bare_level_error_uc() { - let logger = EnvFilterBuilder::from_spec("ERROR").build(); + let logger = RustLogFilterBuilder::from_spec("ERROR").build(); assert!(!logger.rejected(Level::Error, "")); assert!(logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -438,7 +438,7 @@ fn parse_default_bare_level_error_uc() { #[test] fn parse_default_bare_level_warn_lc() { - let logger = EnvFilterBuilder::from_spec("warn").build(); + let logger = RustLogFilterBuilder::from_spec("warn").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -448,7 +448,7 @@ fn parse_default_bare_level_warn_lc() { #[test] fn parse_default_bare_level_warn_uc() { - let logger = EnvFilterBuilder::from_spec("WARN").build(); + let logger = RustLogFilterBuilder::from_spec("WARN").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(logger.rejected(Level::Info, "")); @@ -458,7 +458,7 @@ fn parse_default_bare_level_warn_uc() { #[test] fn parse_default_bare_level_info_lc() { - let logger = EnvFilterBuilder::from_spec("info").build(); + let logger = RustLogFilterBuilder::from_spec("info").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -468,7 +468,7 @@ fn parse_default_bare_level_info_lc() { #[test] fn parse_default_bare_level_info_uc() { - let logger = EnvFilterBuilder::from_spec("INFO").build(); + let logger = RustLogFilterBuilder::from_spec("INFO").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -478,7 +478,7 @@ fn parse_default_bare_level_info_uc() { #[test] fn parse_default_bare_level_debug_lc() { - let logger = EnvFilterBuilder::from_spec("debug").build(); + let logger = RustLogFilterBuilder::from_spec("debug").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -488,7 +488,7 @@ fn parse_default_bare_level_debug_lc() { #[test] fn parse_default_bare_level_debug_uc() { - let logger = EnvFilterBuilder::from_spec("DEBUG").build(); + let logger = RustLogFilterBuilder::from_spec("DEBUG").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -498,7 +498,7 @@ fn parse_default_bare_level_debug_uc() { #[test] fn parse_default_bare_level_trace_lc() { - let logger = EnvFilterBuilder::from_spec("trace").build(); + let logger = RustLogFilterBuilder::from_spec("trace").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -508,7 +508,7 @@ fn parse_default_bare_level_trace_lc() { #[test] fn parse_default_bare_level_trace_uc() { - let logger = EnvFilterBuilder::from_spec("TRACE").build(); + let logger = RustLogFilterBuilder::from_spec("TRACE").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -523,7 +523,7 @@ fn parse_default_bare_level_trace_uc() { #[test] fn parse_default_bare_level_debug_mixed() { { - let logger = EnvFilterBuilder::from_spec("Debug").build(); + let logger = RustLogFilterBuilder::from_spec("Debug").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -531,7 +531,7 @@ fn parse_default_bare_level_debug_mixed() { assert!(logger.rejected(Level::Trace, "")); } { - let logger = EnvFilterBuilder::from_spec("debuG").build(); + let logger = RustLogFilterBuilder::from_spec("debuG").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -539,7 +539,7 @@ fn parse_default_bare_level_debug_mixed() { assert!(logger.rejected(Level::Trace, "")); } { - let logger = EnvFilterBuilder::from_spec("deBug").build(); + let logger = RustLogFilterBuilder::from_spec("deBug").build(); assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -547,7 +547,7 @@ fn parse_default_bare_level_debug_mixed() { assert!(logger.rejected(Level::Trace, "")); } { - let logger = EnvFilterBuilder::from_spec("DeBuG").build(); // LaTeX flavor! + let logger = RustLogFilterBuilder::from_spec("DeBuG").build(); // LaTeX flavor! assert!(!logger.rejected(Level::Error, "")); assert!(!logger.rejected(Level::Warn, "")); assert!(!logger.rejected(Level::Info, "")); @@ -558,7 +558,7 @@ fn parse_default_bare_level_debug_mixed() { #[test] fn try_parse_valid_filter() { - let logger = EnvFilterBuilder::try_from_spec("info,crate1::mod1=warn") + let logger = RustLogFilterBuilder::try_from_spec("info,crate1::mod1=warn") .expect("valid filter returned error") .build(); assert!(!logger.rejected(Level::Warn, "crate1::mod1")); @@ -567,13 +567,13 @@ fn try_parse_valid_filter() { #[test] fn try_parse_invalid_filter() { - let error = EnvFilterBuilder::try_from_spec("info,crate1=invalid").unwrap_err(); + let error = RustLogFilterBuilder::try_from_spec("info,crate1=invalid").unwrap_err(); assert_snapshot!(error.to_string(), @"malformed logging spec 'invalid'"); } #[test] fn match_full_path() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: Some("crate2".to_owned()), level: LevelFilter::MoreSevereEqual(Level::Info), @@ -591,7 +591,7 @@ fn match_full_path() { #[test] fn no_match() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: Some("crate2".to_owned()), level: LevelFilter::MoreSevereEqual(Level::Info), @@ -606,7 +606,7 @@ fn no_match() { #[test] fn match_beginning() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: Some("crate2".to_owned()), level: LevelFilter::MoreSevereEqual(Level::Info), @@ -621,7 +621,7 @@ fn match_beginning() { #[test] fn match_beginning_longest_match() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: Some("crate2".to_owned()), level: LevelFilter::MoreSevereEqual(Level::Info), @@ -641,7 +641,7 @@ fn match_beginning_longest_match() { #[test] fn match_default() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: None, level: LevelFilter::MoreSevereEqual(Level::Info), @@ -657,7 +657,7 @@ fn match_default() { #[test] fn zero_level() { - let logger = EnvFilter::from_directives(vec![ + let logger = RustLogFilter::from_directives(vec![ Directive { name: None, level: LevelFilter::MoreSevereEqual(Level::Info), diff --git a/logforth/Cargo.toml b/logforth/Cargo.toml index 735e81e..be6c27b 100644 --- a/logforth/Cargo.toml +++ b/logforth/Cargo.toml @@ -36,11 +36,12 @@ default = [] # Starters starter-log = [ - "bridge-log", "dep:log", + "bridge-log", "append-file", "layout-text", "layout-json", + "filter-rustlog", ] # Bridges @@ -65,6 +66,9 @@ layout-text = ["dep:logforth-layout-text"] diagnostic-fastrace = ["dep:logforth-diagnostic-fastrace"] diagnostic-task-local = ["dep:logforth-diagnostic-task-local"] +# Filters +filter-rustlog = ["dep:logforth-filter-rustlog"] + # Standalone features native-tls = ["logforth-append-syslog?/native-tls"] rustls = ["logforth-append-syslog?/rustls"] @@ -83,6 +87,7 @@ logforth-append-syslog = { workspace = true, optional = true } logforth-bridge-log = { workspace = true, optional = true } logforth-diagnostic-fastrace = { workspace = true, optional = true } logforth-diagnostic-task-local = { workspace = true, optional = true } +logforth-filter-rustlog = { workspace = true, optional = true } logforth-layout-google-cloud-logging = { workspace = true, optional = true } logforth-layout-json = { workspace = true, optional = true } logforth-layout-logfmt = { workspace = true, optional = true } diff --git a/logforth/src/lib.rs b/logforth/src/lib.rs index 5f1e883..668dcd5 100644 --- a/logforth/src/lib.rs +++ b/logforth/src/lib.rs @@ -135,6 +135,10 @@ pub mod diagnostic { /// Filters for log records. pub mod filter { pub use logforth_core::filter::*; + #[cfg(feature = "filter-rustlog")] + pub use logforth_filter_rustlog as rustlog; + #[cfg(feature = "filter-rustlog")] + pub use logforth_filter_rustlog::RustLogFilter; } /// Layouts for formatting log records. diff --git a/logforth/src/starter_log.rs b/logforth/src/starter_log.rs index 2dcfbc4..b45455b 100644 --- a/logforth/src/starter_log.rs +++ b/logforth/src/starter_log.rs @@ -14,7 +14,7 @@ //! Starter configurations for quickly setting up logforth with the `log` crate -use logforth_bridge_log::LogAdapter; +use logforth_bridge_log::LogBridge; use logforth_core::Logger; use crate::Append; @@ -24,7 +24,7 @@ use crate::Layout; use crate::append; use crate::core::DispatchBuilder; use crate::core::LoggerBuilder; -use crate::filter::env_filter::EnvFilterBuilder; +use crate::filter::rustlog::RustLogFilterBuilder; /// A builder for setting up logforth with the `log` crate. pub struct LogStarterBuilder { @@ -89,7 +89,7 @@ impl LogStarterBuilder { pub fn try_apply(self) -> Result<(), Error> { let make_error = |_| Error::new("logging system has already been setup"); - let logger = Box::new(LogAdapter::new(self.build())); + let logger = Box::new(LogBridge::new(self.build())); log::set_boxed_logger(logger).map_err(make_error)?; log::set_max_level(log::LevelFilter::Trace); @@ -131,10 +131,10 @@ impl LogStarterBuilder { /// ``` /// use std::sync::Arc; /// - /// use logforth::bridge::log::LogAdapter; + /// use logforth::bridge::log::LogBridge; /// /// let logger = logforth::starter_log::builder().build(); - /// let logger = Arc::new(LogAdapter::new(logger)); + /// let logger = Arc::new(LogBridge::new(logger)); /// log::set_boxed_logger(Box::new(logger.clone())).unwrap(); /// log::set_max_level(log::LevelFilter::Trace); /// @@ -153,10 +153,10 @@ pub struct LogStarterTestingBuilder { layout: Box, } -/// Create a starter builder with a default [`append::Testing`] appender and an [`EnvFilter`] +/// Create a starter builder with a default [`append::Testing`] appender and a [`RustLogFilter`] /// respecting `RUST_LOG`. /// -/// [`EnvFilter`]: crate::filter::EnvFilter +/// [`RustLogFilter`]: crate::filter::RustLogFilter /// /// # Examples /// @@ -261,10 +261,10 @@ impl LogStarterTestingBuilder { /// ``` /// use std::sync::Arc; /// - /// use logforth::bridge::log::LogAdapter; + /// use logforth::bridge::log::LogBridge; /// /// let logger = logforth::starter_log::testing().build(); - /// let logger = Arc::new(LogAdapter::new(logger)); + /// let logger = Arc::new(LogBridge::new(logger)); /// log::set_boxed_logger(Box::new(logger.clone())).unwrap(); /// log::set_max_level(log::LevelFilter::Trace); /// @@ -293,10 +293,10 @@ pub struct LogStarterStdStreamBuilder { layout: Box, } -/// Create a starter builder with a default [`append::Stdout`] appender and an [`EnvFilter`] +/// Create a starter builder with a default [`append::Stdout`] appender and a [`RustLogFilter`] /// respecting `RUST_LOG`. /// -/// [`EnvFilter`]: crate::filter::EnvFilter +/// [`RustLogFilter`]: crate::filter::RustLogFilter /// /// # Examples /// @@ -312,10 +312,10 @@ pub fn stdout() -> LogStarterStdStreamBuilder { } } -/// Create a starter builder with a default [`append::Stderr`] appender and an [`EnvFilter`] +/// Create a starter builder with a default [`append::Stderr`] appender and a [`RustLogFilter`] /// respecting `RUST_LOG`. /// -/// [`EnvFilter`]: crate::filter::EnvFilter +/// [`RustLogFilter`]: crate::filter::RustLogFilter /// /// # Examples /// @@ -421,10 +421,10 @@ impl LogStarterStdStreamBuilder { /// ``` /// use std::sync::Arc; /// - /// use logforth::bridge::log::LogAdapter; + /// use logforth::bridge::log::LogBridge; /// /// let logger = logforth::starter_log::stdout().build(); - /// let logger = Arc::new(LogAdapter::new(logger)); + /// let logger = Arc::new(LogBridge::new(logger)); /// log::set_boxed_logger(Box::new(logger.clone())).unwrap(); /// log::set_max_level(log::LevelFilter::Trace); /// @@ -451,7 +451,7 @@ impl LogStarterStdStreamBuilder { } fn default_filter() -> Box { - Box::new(EnvFilterBuilder::from_default_env().build()) + Box::new(RustLogFilterBuilder::from_default_env().build()) } fn default_layout() -> Box {