Skip to content

Commit 2d35260

Browse files
committed
feat(filter): Add a Logger decorator
1 parent e6e2b63 commit 2d35260

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

crates/env_filter/src/filtered_log.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use log::Log;
2+
3+
use crate::Filter;
4+
5+
/// Decorate a [`log::Log`] with record [`Filter`]ing.
6+
///
7+
/// Records that match the filter will be forwarded to the wrapped log.
8+
/// Other records will be ignored.
9+
#[derive(Debug)]
10+
pub struct FilteredLog<T> {
11+
log: T,
12+
filter: Filter,
13+
}
14+
15+
impl<T: Log> FilteredLog<T> {
16+
/// Create a new filtered log.
17+
pub fn new(log: T, filter: Filter) -> Self {
18+
Self { log, filter }
19+
}
20+
}
21+
22+
impl<T: Log> Log for FilteredLog<T> {
23+
/// Determines if a log message with the specified metadata would be logged.
24+
///
25+
/// For the wrapped log, this returns `true` only if both the filter and the wrapped log return `true`.
26+
fn enabled(&self, metadata: &log::Metadata) -> bool {
27+
self.filter.enabled(metadata) && self.log.enabled(metadata)
28+
}
29+
30+
/// Logs the record.
31+
///
32+
/// Forwards the record to the wrapped log, but only if the record matches the filter.
33+
fn log(&self, record: &log::Record) {
34+
if self.filter.matches(record) {
35+
self.log.log(record)
36+
}
37+
}
38+
39+
/// Flushes any buffered records.
40+
///
41+
/// Forwards directly to the wrapped log.
42+
fn flush(&self) {
43+
self.log.flush()
44+
}
45+
}

crates/env_filter/src/lib.rs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,32 @@
1414
//! use env_filter::Filter;
1515
//! use log::{Log, Metadata, Record};
1616
//!
17-
//! struct MyLogger {
18-
//! filter: Filter
19-
//! }
20-
//!
21-
//! impl MyLogger {
22-
//! fn new() -> MyLogger {
23-
//! use env_filter::Builder;
24-
//! let mut builder = Builder::new();
25-
//!
26-
//! // Parse a directives string from an environment variable
27-
//! if let Ok(ref filter) = std::env::var("MY_LOG_LEVEL") {
28-
//! builder.parse(filter);
29-
//! }
17+
//! struct PrintLogger;
3018
//!
31-
//! MyLogger {
32-
//! filter: builder.build()
33-
//! }
34-
//! }
35-
//! }
36-
//!
37-
//! impl Log for MyLogger {
19+
//! impl Log for PrintLogger {
3820
//! fn enabled(&self, metadata: &Metadata) -> bool {
39-
//! self.filter.enabled(metadata)
21+
//! true
4022
//! }
4123
//!
4224
//! fn log(&self, record: &Record) {
43-
//! // Check if the record is matched by the filter
44-
//! if self.filter.matches(record) {
45-
//! println!("{:?}", record);
46-
//! }
25+
//! println!("{:?}", record);
4726
//! }
4827
//!
4928
//! fn flush(&self) {}
5029
//! }
30+
//!
31+
//! let mut builder = env_filter::Builder::new();
32+
//! // Parse a directives string from an environment variable
33+
//! if let Ok(ref filter) = std::env::var("MY_LOG_LEVEL") {
34+
//! builder.parse(filter);
35+
//! }
36+
//!
37+
//! let logger = env_filter::FilteredLog::new(PrintLogger, builder.build());
5138
//! ```
5239
5340
mod directive;
5441
mod filter;
42+
mod filtered_log;
5543
mod op;
5644
mod parser;
5745

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

6351
pub use filter::Builder;
6452
pub use filter::Filter;
53+
pub use filtered_log::FilteredLog;

0 commit comments

Comments
 (0)