diff --git a/Cargo.lock b/Cargo.lock index 2bb97a6a..70b09820 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,14 +29,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "env_filter" +version = "0.10.1" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" version = "0.10.1" dependencies = [ + "env_filter", "humantime", "is-terminal", "log", - "regex", "termcolor", ] diff --git a/Cargo.toml b/Cargo.toml index 7a1ae457..4f977f89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,67 +1,6 @@ -[package] -name = "env_logger" -version = "0.10.1" -description = """ -A logging implementation for `log` which is configured via an environment -variable. -""" -repository = "https://github.com/rust-cli/env_logger" -categories = ["development-tools::debugging"] -keywords = ["logging", "log", "logger"] -license = "MIT OR Apache-2.0" -edition = "2021" -rust-version = "1.60.0" # MSRV -include = [ - "build.rs", - "src/**/*", - "Cargo.toml", - "Cargo.lock", - "LICENSE*", - "README.md", - "benches/**/*", - "examples/**/*", - "tests/**/*", +[workspace] +resolver = "2" +members = [ + "env_filter", + "env_logger", ] - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[package.metadata.release] -pre-release-replacements = [ - {file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1}, - {file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1}, - {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1}, - {file="CHANGELOG.md", search="", replace="\n## [Unreleased] - ReleaseDate\n", exactly=1}, - {file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/rust-cli/env_logger/compare/{{tag_name}}...HEAD", exactly=1}, -] - -[features] -default = ["auto-color", "humantime", "regex"] -color = ["dep:termcolor"] -auto-color = ["dep:is-terminal", "color"] -humantime = ["dep:humantime"] -regex = ["dep:regex"] - -[dependencies] -log = { version = "0.4.8", features = ["std"] } -regex = { version = "1.0.3", optional = true, default-features=false, features=["std", "perf"] } -termcolor = { version = "1.1.1", optional = true } -humantime = { version = "2.0.0", optional = true } -is-terminal = { version = "0.4.0", optional = true } - -[[test]] -name = "regexp_filter" -harness = false - -[[test]] -name = "log-in-log" -harness = false - -[[test]] -name = "log_tls_dtors" -harness = false - -[[test]] -name = "init-twice-retains-filter" -harness = false diff --git a/env_filter/Cargo.toml b/env_filter/Cargo.toml new file mode 100644 index 00000000..b46d861f --- /dev/null +++ b/env_filter/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "env_filter" +version = "0.10.1" +description = """ +A log filtering implementation for `log` which is configured via an environment +variable. +""" +repository = "https://github.com/rust-cli/env_logger" +categories = ["development-tools::debugging"] +keywords = ["logging", "log", "logger"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.60.0" # MSRV +include = [ + "build.rs", + "src/**/*", + "Cargo.toml", + "Cargo.lock", + "LICENSE*", + "README.md", + "benches/**/*", + "examples/**/*", + "tests/**/*", +] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.release] +pre-release-replacements = [ + {file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1}, + {file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1}, + {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1}, + {file="CHANGELOG.md", search="", replace="\n## [Unreleased] - ReleaseDate\n", exactly=1}, + {file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/rust-cli/env_logger/compare/{{tag_name}}...HEAD", exactly=1}, +] + +[features] +default = ["regex"] +regex = ["dep:regex"] + +[dependencies] +log = { version = "0.4.8", features = ["std"] } +regex = { version = "1.0.3", optional = true, default-features=false, features=["std", "perf"] } diff --git a/env_filter/LICENSE-APACHE b/env_filter/LICENSE-APACHE new file mode 120000 index 00000000..965b606f --- /dev/null +++ b/env_filter/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/env_filter/LICENSE-MIT b/env_filter/LICENSE-MIT new file mode 120000 index 00000000..76219eb7 --- /dev/null +++ b/env_filter/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/env_filter/src/filtered_log.rs b/env_filter/src/filtered_log.rs new file mode 100644 index 00000000..41d1835c --- /dev/null +++ b/env_filter/src/filtered_log.rs @@ -0,0 +1,69 @@ +use super::Filter; +use log::Log; + +/// Wrapper that combines a [`Filter`] with an existing [`log::Log`] implementation. +/// +/// Records that match the filter will be forwarded to the wrapped log. +/// Other records will be ignored. +#[derive(Debug)] +pub struct FilteredLog { + filter: Filter, + log: T, +} + +impl FilteredLog { + /// Create a new filtered log. + pub fn new(filter: Filter, log: T) -> Self { + Self { filter, log } + } + + /// Gets a reference to the filter. + pub fn filter(&self) -> &Filter { + &self.filter + } + + /// Gets a mutable reference to the filter. + pub fn filter_mut(&mut self) -> &mut Filter { + &mut self.filter + } + + /// Gets a reference to the wrapped log. + pub fn inner(&self) -> &T { + &self.log + } + + /// Gets a mutable reference to the wrapped log. + pub fn inner_mut(&mut self) -> &mut T { + &mut self.log + } + + /// Consumes the filtered log to take back ownership of the filter and the wrapped log. + pub fn into_parts(self) -> (Filter, T) { + (self.filter, self.log) + } +} + +impl Log for FilteredLog { + /// Determines if a log message with the specified metadata would be logged. + /// + /// For the wrapped log, this returns `true` only if both the filter and the wrapped log return `true`. + fn enabled(&self, metadata: &log::Metadata) -> bool { + self.filter.enabled(metadata) && self.log.enabled(metadata) + } + + /// Logs the record. + /// + /// Forwards the record to the wrapped log, but only if the record matches the filter. + fn log(&self, record: &log::Record) { + if self.filter.matches(record) { + self.log.log(record) + } + } + + /// Flushes any buffered records. + /// + /// Forwards directly to the wrapped log. + fn flush(&self) { + self.log.flush() + } +} diff --git a/src/filter/mod.rs b/env_filter/src/lib.rs similarity index 97% rename from src/filter/mod.rs rename to env_filter/src/lib.rs index d4acf632..ddb5b3f6 100644 --- a/src/filter/mod.rs +++ b/env_filter/src/lib.rs @@ -1,31 +1,27 @@ //! Filtering for log records. //! -//! This module contains the log filtering used by `env_logger` to match records. +//! This crate contains the log filtering used by `env_logger` to match records. //! You can use the `Filter` type in your own logger implementation to use the same //! filter parsing and matching as `env_logger`. For more details about the format //! for directive strings see [Enabling Logging]. //! -//! ## Using `env_logger` in your own logger +//! ## Using `env_filter` in your own logger //! -//! You can use `env_logger`'s filtering functionality with your own logger. +//! You can use `env_filter`'s filtering functionality with your own logger. //! Call [`Builder::parse`] to parse directives from a string when constructing //! your logger. Call [`Filter::matches`] to check whether a record should be //! logged based on the parsed filters when log records are received. //! //! ``` -//! extern crate log; -//! extern crate env_logger; -//! use env_logger::filter::Filter; //! use log::{Log, Metadata, Record}; //! //! struct MyLogger { -//! filter: Filter +//! filter: env_filter::Filter //! } //! //! impl MyLogger { //! fn new() -> MyLogger { -//! use env_logger::filter::Builder; -//! let mut builder = Builder::new(); +//! let mut builder = env_filter::Builder::new(); //! //! // Parse a directives string from an environment variable //! if let Ok(ref filter) = std::env::var("MY_LOG_LEVEL") { @@ -55,8 +51,6 @@ //! ``` //! //! [Enabling Logging]: ../index.html#enabling-logging -//! [`Builder::parse`]: struct.Builder.html#method.parse -//! [`Filter::matches`]: struct.Filter.html#method.matches use log::{Level, LevelFilter, Metadata, Record}; use std::env; @@ -71,6 +65,9 @@ mod inner; #[path = "string.rs"] mod inner; +mod filtered_log; +pub use filtered_log::FilteredLog; + /// A builder for a log filter. /// /// It can be used to parse a set of directives from a string before building @@ -79,14 +76,10 @@ mod inner; /// ## Example /// /// ``` -/// # #[macro_use] extern crate log; -/// # use std::env; -/// use env_logger::filter::Builder; -/// -/// let mut builder = Builder::new(); +/// let mut builder = env_filter::Builder::new(); /// /// // Parse a logging filter from an environment variable. -/// if let Ok(rust_log) = env::var("RUST_LOG") { +/// if let Ok(rust_log) = std::env::var("RUST_LOG") { /// builder.parse(&rust_log); /// } /// @@ -248,9 +241,8 @@ impl Filter { /// /// ```rust /// use log::LevelFilter; - /// use env_logger::filter::Builder; /// - /// let mut builder = Builder::new(); + /// let mut builder = env_filter::Builder::new(); /// builder.filter(Some("module1"), LevelFilter::Info); /// builder.filter(Some("module2"), LevelFilter::Error); /// @@ -287,6 +279,13 @@ impl Filter { enabled(&self.directives, level, target) } + + /// Wraps an existing [`Log`] implementation with the filter. + /// + /// The returned log forwards all records that match the filter to the wrapped [`Log`] implementation. + pub fn wrap_log(self, log: T) -> FilteredLog { + FilteredLog::new(self, log) + } } impl fmt::Debug for Filter { diff --git a/src/filter/regex.rs b/env_filter/src/regex.rs similarity index 91% rename from src/filter/regex.rs rename to env_filter/src/regex.rs index fb21528a..718614eb 100644 --- a/src/filter/regex.rs +++ b/env_filter/src/regex.rs @@ -1,9 +1,6 @@ -extern crate regex; - +use regex::Regex; use std::fmt; -use self::regex::Regex; - #[derive(Debug)] pub struct Filter { inner: Regex, diff --git a/src/filter/string.rs b/env_filter/src/string.rs similarity index 100% rename from src/filter/string.rs rename to env_filter/src/string.rs diff --git a/CHANGELOG.md b/env_logger/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to env_logger/CHANGELOG.md diff --git a/env_logger/Cargo.toml b/env_logger/Cargo.toml new file mode 100644 index 00000000..48478937 --- /dev/null +++ b/env_logger/Cargo.toml @@ -0,0 +1,67 @@ +[package] +name = "env_logger" +version = "0.10.1" +description = """ +A logging implementation for `log` which is configured via an environment +variable. +""" +repository = "https://github.com/rust-cli/env_logger" +categories = ["development-tools::debugging"] +keywords = ["logging", "log", "logger"] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.60.0" # MSRV +include = [ + "build.rs", + "src/**/*", + "Cargo.toml", + "Cargo.lock", + "LICENSE*", + "README.md", + "benches/**/*", + "examples/**/*", + "tests/**/*", +] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.release] +pre-release-replacements = [ + {file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1}, + {file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1}, + {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1}, + {file="CHANGELOG.md", search="", replace="\n## [Unreleased] - ReleaseDate\n", exactly=1}, + {file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/rust-cli/env_logger/compare/{{tag_name}}...HEAD", exactly=1}, +] + +[features] +default = ["auto-color", "humantime", "regex"] +color = ["dep:termcolor"] +auto-color = ["dep:is-terminal", "color"] +humantime = ["dep:humantime"] +regex = ["env_filter/regex"] + +[dependencies] +env_filter = { version = "0.10.1", path = "../env_filter", default-features=false } +log = { version = "0.4.8", features = ["std"] } +termcolor = { version = "1.1.1", optional = true } +humantime = { version = "2.0.0", optional = true } +is-terminal = { version = "0.4.0", optional = true } + +[[test]] +name = "regexp_filter" +harness = false + +[[test]] +name = "log-in-log" +harness = false + +[[test]] +name = "log_tls_dtors" +harness = false + +[[test]] +name = "init-twice-retains-filter" +harness = false diff --git a/env_logger/LICENSE-APACHE b/env_logger/LICENSE-APACHE new file mode 120000 index 00000000..965b606f --- /dev/null +++ b/env_logger/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/env_logger/LICENSE-MIT b/env_logger/LICENSE-MIT new file mode 120000 index 00000000..76219eb7 --- /dev/null +++ b/env_logger/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/README.md b/env_logger/README.md similarity index 100% rename from README.md rename to env_logger/README.md diff --git a/examples/custom_default_format.rs b/env_logger/examples/custom_default_format.rs similarity index 100% rename from examples/custom_default_format.rs rename to env_logger/examples/custom_default_format.rs diff --git a/examples/custom_format.rs b/env_logger/examples/custom_format.rs similarity index 100% rename from examples/custom_format.rs rename to env_logger/examples/custom_format.rs diff --git a/examples/custom_logger.rs b/env_logger/examples/custom_logger.rs similarity index 100% rename from examples/custom_logger.rs rename to env_logger/examples/custom_logger.rs diff --git a/examples/default.rs b/env_logger/examples/default.rs similarity index 100% rename from examples/default.rs rename to env_logger/examples/default.rs diff --git a/examples/direct_logger.rs b/env_logger/examples/direct_logger.rs similarity index 100% rename from examples/direct_logger.rs rename to env_logger/examples/direct_logger.rs diff --git a/examples/filters_from_code.rs b/env_logger/examples/filters_from_code.rs similarity index 100% rename from examples/filters_from_code.rs rename to env_logger/examples/filters_from_code.rs diff --git a/examples/in_tests.rs b/env_logger/examples/in_tests.rs similarity index 100% rename from examples/in_tests.rs rename to env_logger/examples/in_tests.rs diff --git a/examples/syslog_friendly_format.rs b/env_logger/examples/syslog_friendly_format.rs similarity index 100% rename from examples/syslog_friendly_format.rs rename to env_logger/examples/syslog_friendly_format.rs diff --git a/release.toml b/env_logger/release.toml similarity index 100% rename from release.toml rename to env_logger/release.toml diff --git a/src/fmt/humantime.rs b/env_logger/src/fmt/humantime.rs similarity index 100% rename from src/fmt/humantime.rs rename to env_logger/src/fmt/humantime.rs diff --git a/src/fmt/mod.rs b/env_logger/src/fmt/mod.rs similarity index 100% rename from src/fmt/mod.rs rename to env_logger/src/fmt/mod.rs diff --git a/src/fmt/writer/atty.rs b/env_logger/src/fmt/writer/atty.rs similarity index 100% rename from src/fmt/writer/atty.rs rename to env_logger/src/fmt/writer/atty.rs diff --git a/src/fmt/writer/mod.rs b/env_logger/src/fmt/writer/mod.rs similarity index 100% rename from src/fmt/writer/mod.rs rename to env_logger/src/fmt/writer/mod.rs diff --git a/src/fmt/writer/termcolor/extern_impl.rs b/env_logger/src/fmt/writer/termcolor/extern_impl.rs similarity index 100% rename from src/fmt/writer/termcolor/extern_impl.rs rename to env_logger/src/fmt/writer/termcolor/extern_impl.rs diff --git a/src/fmt/writer/termcolor/mod.rs b/env_logger/src/fmt/writer/termcolor/mod.rs similarity index 100% rename from src/fmt/writer/termcolor/mod.rs rename to env_logger/src/fmt/writer/termcolor/mod.rs diff --git a/src/fmt/writer/termcolor/shim_impl.rs b/env_logger/src/fmt/writer/termcolor/shim_impl.rs similarity index 100% rename from src/fmt/writer/termcolor/shim_impl.rs rename to env_logger/src/fmt/writer/termcolor/shim_impl.rs diff --git a/src/lib.rs b/env_logger/src/lib.rs similarity index 99% rename from src/lib.rs rename to env_logger/src/lib.rs index cdc2badc..d68e7c79 100644 --- a/src/lib.rs +++ b/env_logger/src/lib.rs @@ -277,7 +277,8 @@ mod logger; -pub mod filter; +pub use env_filter as filter; + pub mod fmt; pub use self::fmt::glob::*; diff --git a/src/logger.rs b/env_logger/src/logger.rs similarity index 100% rename from src/logger.rs rename to env_logger/src/logger.rs diff --git a/tests/init-twice-retains-filter.rs b/env_logger/tests/init-twice-retains-filter.rs similarity index 100% rename from tests/init-twice-retains-filter.rs rename to env_logger/tests/init-twice-retains-filter.rs diff --git a/tests/log-in-log.rs b/env_logger/tests/log-in-log.rs similarity index 100% rename from tests/log-in-log.rs rename to env_logger/tests/log-in-log.rs diff --git a/tests/log_tls_dtors.rs b/env_logger/tests/log_tls_dtors.rs similarity index 100% rename from tests/log_tls_dtors.rs rename to env_logger/tests/log_tls_dtors.rs diff --git a/tests/regexp_filter.rs b/env_logger/tests/regexp_filter.rs similarity index 100% rename from tests/regexp_filter.rs rename to env_logger/tests/regexp_filter.rs