From a434e9ebcafbc2fb346dc30581f8c76e140f6ef8 Mon Sep 17 00:00:00 2001 From: Andy Lok Date: Tue, 13 Aug 2024 22:37:58 +0800 Subject: [PATCH] feat: add target filter (#44) Co-authored-by: tison --- src/filter/level.rs | 8 ++++-- src/filter/mod.rs | 4 +++ src/filter/target.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/filter/target.rs diff --git a/src/filter/level.rs b/src/filter/level.rs index 66e74da..8426b71 100644 --- a/src/filter/level.rs +++ b/src/filter/level.rs @@ -17,7 +17,7 @@ use log::Metadata; use crate::filter::Filter; use crate::filter::FilterResult; -/// A filter that checks if the log level is at most the specified level. +/// A filter that checks if the log level is higher than the specified level. /// /// From least to most verbose, the levels are: /// @@ -31,9 +31,13 @@ use crate::filter::FilterResult; /// /// If LevelFilter is set to `Off`, it will reject all logs. #[derive(Debug, Clone)] -pub struct LevelFilter(pub log::LevelFilter); +pub struct LevelFilter(log::LevelFilter); impl LevelFilter { + pub fn new(level: log::LevelFilter) -> Self { + LevelFilter(level) + } + pub(crate) fn filter(&self, metadata: &Metadata) -> FilterResult { let level = metadata.level(); if level <= self.0 { diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 2038c4a..d641c30 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -16,9 +16,11 @@ pub use self::custom::CustomFilter; pub use self::level::LevelFilter; +pub use self::target::TargetFilter; mod custom; mod level; +mod target; /// The result of a filter may return. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -34,6 +36,7 @@ pub enum FilterResult { #[derive(Debug)] pub enum Filter { Level(LevelFilter), + Target(TargetFilter), Custom(CustomFilter), } @@ -41,6 +44,7 @@ impl Filter { pub(crate) fn filter(&self, metadata: &log::Metadata) -> FilterResult { match self { Filter::Level(filter) => filter.filter(metadata), + Filter::Target(filter) => filter.filter(metadata), Filter::Custom(filter) => filter.filter(metadata), } } diff --git a/src/filter/target.rs b/src/filter/target.rs new file mode 100644 index 0000000..4182f37 --- /dev/null +++ b/src/filter/target.rs @@ -0,0 +1,59 @@ +// 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. + +use std::borrow::Cow; + +use log::Metadata; + +use crate::filter::Filter; +use crate::filter::FilterResult; + +/// A filter that checks if the log level is higher than the specified level for a specific +/// target. +/// +/// Only if the target has a prefix that matches the target of the log record, the filter +/// will be applied. +#[derive(Debug, Clone)] +pub struct TargetFilter { + target: Cow<'static, str>, + level: log::LevelFilter, +} + +impl TargetFilter { + pub fn level_for(target: impl Into>, level: log::LevelFilter) -> Self { + TargetFilter { + target: target.into(), + level, + } + } + + pub(crate) fn filter(&self, metadata: &Metadata) -> FilterResult { + if metadata.target().starts_with(self.target.as_ref()) { + let level = metadata.level(); + if level <= self.level { + FilterResult::Neutral + } else { + FilterResult::Reject + } + } else { + FilterResult::Neutral + } + } +} + +impl From for Filter { + fn from(filter: TargetFilter) -> Self { + Filter::Target(filter) + } +}