filter分为两类,
第一类,TurboFilters,它构成了filter链,类似于servlet的filter。适用于处理请求流程的第一步。
第二类,Appender中配置的filter。适用于其对应的appender,在FileAppender中配置的filter不会对ConsoleAppender有效。
1、TurboFilters
它的知识点分为两部分。
第一部分,介绍内置的TurboFilter。
第二部分,介绍如何自定义Filter。
1.1 MDCTurboFilter
MDCTurboFilter根据MDC中的变量进行过滤,首先检查变量是否存在,其次检查变量的值是否与配置的值相等。
示例:只输出test用户的日志。
<turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
<MDCKey>username</MDCKey>
<Value>test</Value>
<OnMatch>ACCEPT</OnMatch>
<OnMismatch>DENY</OnMismatch>
</turboFilter>
1.2 MarkerFilter
MarkerFilter根据日志请求携带的标记进行过滤,检查二者的Marker对象是否相等,即name属性是否相等。
示例:输出只携带Important标记的日志
<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
<Marker>Important</Marker>
<OnMatch>DENY</OnMatch>
</turboFilter>
1.3 DuplicateMessageFilter
DuplicateMessageFilter根据日志信息的重复次数进行过滤。日志信息重复的判断条件有:
- 非参数化情形下,日志信息完全相同。即日志信息中不包含{}。
- 参数化情况下,日志信息相同,包含的{}个数和位置相同,参数的值可以不同。
它的AllowedRepetitions代表可以重复的次数,默认值为5。
需要注意的是日志信息第一次出现,第二次出现表示第一次重复的含义,所以当设置为5时,总共包含日志信息本身和5次重复信息,总共是6次。
示例:
<turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter">
<!-- 最多重复3次 -->
<AllowedRepetitions>3</AllowedRepetitions>
</turboFilter>
1.4 自定义
步骤如下:
第一步,继承TurboFilter,重写decide方法。
public class MyTurboFilter extends TurboFilter {
private String testMarkerStr;
private Marker testMarker;
@Override
public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
if (!isStarted()) {
return FilterReply.NEUTRAL;
}
// Marker对象重写了equals方法,Marker相等只需要Marker的name属性相等
if ((testMarker.equals(marker))) {
return FilterReply.NEUTRAL;
} else {
return FilterReply.DENY;
}
}
public String getTestMarkerStr() {
return testMarkerStr;
}
public void setTestMarkerStr(String testMarkerStr) {
this.testMarkerStr = testMarkerStr;
}
// 每一种日志框架的核心对象都有生命周期的概念,在使用前必须确保已经start
@Override
public void start() {
if (testMarkerStr != null && testMarkerStr.length() != 0) {
// 将字符串转换为Marker对象
testMarker = MarkerFactory.getMarker(testMarkerStr);
super.start();
}
}
}
第二步,注册。
<turboFilter class="learn.logback.chapter7.MyTurboFilter">
<Marker>sample</Marker>
</turboFilter>
2、Appender Filter
与TurboFilter类似,它的知识点也分为两部分,内置和自定义。
2.1 LevelFilter
当logging request的日志级别与levelFilter中配置的日志级别相等时,符合过滤器条件。
示例:只输出info级别的日志
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置levelFilter -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>NEUTRAL</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${default_pattern}</pattern>
</encoder>
</appender>
2.2 ThresholdFilter
当logging request的日志级别大于等于配置中的日志级别时,符合过滤器条件。
示例:输出info和高于info级别的日志
<appender name="console"
class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置ThresholdFilter -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>${default_pattern}</pattern>
</encoder>
</appender>
2.3 EvaluatorFilter
官网中提及两种EvaluatorFilter,一种是GEventEvaluatorFilter,它需要在配置文件中添加Groovy表达式作为过滤条件,另外一种是JaninoEventEvaluator,它需要在配置文件中添加Java代码作为过滤条件。
首先不建议在配置文件中夹杂其他语言的语法,不论是Groovy还是Java。
其次是EvaluatorFilter它实现的功能,其他过滤器也可以实现。
这样做可以避免在配置文件中夹杂其他语言的语法,使得配置文件更简洁,更方便阅读和维护。
2.4 自定义
步骤如下:
第一步,继承Filter抽象类,实现decide方法。
public class MyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
// 如果loggerName 中存在 test,忽略这些日志信息
if (event.getLoggerName().toUpperCase().contains("TEST")) {
return FilterReply.DENY;
}
return FilterReply.DENY;
}
}
第二步,注册
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 注册myFilter -->
<filter class="learn.logback.chapter7.MyFilter"/>
<encoder>
<pattern>${default_pattern}</pattern>
</encoder>
</appender>
3、比较
第一点,适用范围不同。TurboFilter是影响所有的log 请求。Appender filter只适用于其对应的Appender。
第二点,执行顺序不同,获取到的信息也不同。TurboFilter发生在流程第一步,此时未生成LoggingEvent对象。Appender filter在流程第四步,获取到的信息更全面,可以获取到LoggingEvent对象
作者:蜗牛旅行1899