Skip to content

Commit

Permalink
feat(filter): Add a Logger decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Jan 19, 2024
1 parent e6e2b63 commit 2d35260
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 25 deletions.
45 changes: 45 additions & 0 deletions crates/env_filter/src/filtered_log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use log::Log;

use crate::Filter;

/// Decorate a [`log::Log`] with record [`Filter`]ing.
///
/// Records that match the filter will be forwarded to the wrapped log.
/// Other records will be ignored.
#[derive(Debug)]
pub struct FilteredLog<T> {
log: T,
filter: Filter,
}

impl<T: Log> FilteredLog<T> {
/// Create a new filtered log.
pub fn new(log: T, filter: Filter) -> Self {
Self { log, filter }
}
}

impl<T: Log> Log for FilteredLog<T> {
/// 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()
}
}
39 changes: 14 additions & 25 deletions crates/env_filter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,32 @@
//! use env_filter::Filter;
//! use log::{Log, Metadata, Record};
//!
//! struct MyLogger {
//! filter: Filter
//! }
//!
//! impl MyLogger {
//! fn new() -> MyLogger {
//! use env_filter::Builder;
//! let mut builder = Builder::new();
//!
//! // Parse a directives string from an environment variable
//! if let Ok(ref filter) = std::env::var("MY_LOG_LEVEL") {
//! builder.parse(filter);
//! }
//! struct PrintLogger;
//!
//! MyLogger {
//! filter: builder.build()
//! }
//! }
//! }
//!
//! impl Log for MyLogger {
//! impl Log for PrintLogger {
//! fn enabled(&self, metadata: &Metadata) -> bool {
//! self.filter.enabled(metadata)
//! true
//! }
//!
//! fn log(&self, record: &Record) {
//! // Check if the record is matched by the filter
//! if self.filter.matches(record) {
//! println!("{:?}", record);
//! }
//! println!("{:?}", record);
//! }
//!
//! fn flush(&self) {}
//! }
//!
//! 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") {
//! builder.parse(filter);
//! }
//!
//! let logger = env_filter::FilteredLog::new(PrintLogger, builder.build());
//! ```
mod directive;
mod filter;
mod filtered_log;
mod op;
mod parser;

Expand All @@ -62,3 +50,4 @@ use parser::parse_spec;

pub use filter::Builder;
pub use filter::Filter;
pub use filtered_log::FilteredLog;

0 comments on commit 2d35260

Please sign in to comment.