如何使用log4rs创建自定义过滤器类型? [英] How can I create a custom filter type using log4rs?

查看:56
本文介绍了如何使用log4rs创建自定义过滤器类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

唯一可用的过滤器是级别阈值,但是说我想按特定的 target:$ expr 进行过滤.如何以编程方式(或在yml文件中)让log4rs知道我需要其他类型的过滤器?我是否需要添加自定义功能来适应实现过滤器特征的新过滤器类型的添加?

The only available filter is a level threshold, but say I wanted to filter by a specific target: $expr instead. How would I programmatically (or in the yml file) let log4rs know that I need a different kind of filter? Would I need to add a custom feature to accommodate the addition of my new filter type that implements the filter trait?

我已尝试根据

I have tried implementing my own filter type with all of the associated implementations as per the source code in the documentation of the threshold filter type. I even have the custom filter name specified in the - kind: section of a filter the the .yml config file. What more could log4rs need to implement something like this?

另外,当我运行 let handle = log4rs :: load_config_file("../log4rs.yml",Default :: default()).unwrap(); 时,我收到以下错误消息:

In addition, I am receiving the following error when I run let handle = log4rs::load_config_file("../log4rs.yml", Default::default()).unwrap();

log4rs:将反序列化过滤器附加到附加程序custom_filter_appender时出错:没有为 custom_filter 类型注册的过滤器反序列化器

log4rs: error deserializing filter attached to appender custom_filter_appender: no filter deserializer for kind custom_filter registered

即使我已经为上述自定义过滤器明确定义了反序列化器.

Even though I have explicitly defined a deserializer for said custom filter.

推荐答案

对此问题有几点回应:

  1. 首先,参考 target: $expr 过滤,您只需创建一个新的记录器,该记录器与您要过滤的目标共享相同的名称.这是因为 log4rs 仅将 log 板条箱中的宏发送到与记录器名称具有相同目标字符串的记录器.因此,这里有一种内置的过滤器.
  2. 第二,关于需要自定义功能,您不需要一个.我将在下面显示的所有内容都不需要运行自定义功能.
  3. 第三,也是最有趣的是创建自定义过滤器的语法和形式.我将在下面详细说明必要的修改:
  1. First, with reference to filtering by target: $expr, you can get away with merely creating a new logger that shares the same name as the target(s) you'd like to filter by. This is because log4rs only sends macros from the log crate to loggers with the same target string as the logger name. As such, there is a kind of built in filtering going on here.
  2. Second, with regard to needing a custom feature, you don't need one. Everything I will show below did not require a custom feature to run.
  3. Thirdly, and most interestingly, is the syntax and form of creating a custom filter. I will detail the necessary modifications below:

首先配置log4rs.yml文件:

First the configuration log4rs.yml file:

 appenders:
    custom_filter_appender:
        kind: file
        path: "log/custom_filter.log"
        filters:
        - kind: custom_filter
        interesting_field: interesting_value
        encoder:
          pattern: "{d} {m}{n}"
 root:
   level: error
 loggers:
     filter_logger:
       level: <level you want to filter by>
       appenders:
         - custom_filter_appender
       additive: false

我在上面所做的操作说明了使用配置文件使用 log4rs 配置自定义过滤器的必要条件.请注意,过滤器已附加到附加程序,附加器已附加到记录器.这是附加事物的唯一方法.接下来,我将详细说明custom_filter.rs中所需的自定义过滤器的特征实现,以及它们如何影响代表 custom_filter 的字段.

What I did above illustrates what would be necessary to configure a custom filter with log4rs using a configuration file. Observe that filters are attached to appenders and appenders to loggers. This is the only way to attach things. Next I will detail the trait implementations needed in custom_filter.rs for a custom filter and how they will affect the fields representing the custom_filter.

// First remember to include the appropriate log4rs or whatever other libraries you want in the custom_filter.rs file
#[derive(Deserialize)]
pub struct CustomFilterConfig {
    interesting_field: InterestingFieldType,
}
#[derive(Debug)]
pub struct CustomFilter {
    interesting_field: InterestingFieldType,
}

impl CustomFilter {
    /// Creates a new `CustomFilter` with the specified interesting field.
    pub fn new(interesting_field: InterestingFieldType,) -> CustomFilter {
        CustomFilter { interesting_field }
    }
}

impl Filter for CustomFilter {
    fn filter(&self, record: &Record) -> Response {
        if <Some comparison about self.interesting_field> {
            Response::Accept
        } else {
            Response::Reject
        }
    }
}

pub struct CustomFilterDeserializer;

impl Deserialize for CustomFilterDeserializer {
    type Trait = dyn Filter;

    type Config = CustomFilterConfig;

    fn deserialize(
        &self,
        config: CustomFilterConfig,
        _: &Deserializers,
    ) -> Result<Box<dyn Filter>, Box<dyn Error + Sync + Send>> {
        Ok(Box::new(CustomFilter::new(config.interesting_field)))
    }
}

如果要使 log4rs 能够识别并运行过滤器,则必须实现所有这些功能.请记住,只有与名称 filter_logger (在这种情况下)具有相同目标的 log 条板箱宏会进入此过滤器进行过滤.现在,要完成此操作,我们需要知道如何从main.rs中的文件中设置 log4rs 配置,并添加正确的过滤器,以便可以使用它.

All of these must be implemented if log4rs is to have a prayer of recognizing and running your filter. And remember that only log crate macros that have the same target as the name filter_logger (in this case) will go to this filter for filtering. Now to finish this off we need to know how to set up the log4rs configuration from a file in main.rs with the correct filter added so it can be used.

let mut custom_filter_deserializer = log4rs::file::Deserializers::new();
custom_filter_deserializer.insert(
    "custom_filter",
    crate::custom_filter::CustomFilterDeserializer,
);
log4rs::init_file("log4rs.yml", custom_filter_deserializer).unwrap();

这应该是您自己使用 log4rs 配置自定义过滤器所需的所有内容.

And that should be everything you need to configure a custom filter yourself using log4rs.

这篇关于如何使用log4rs创建自定义过滤器类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆