可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就行了吗?为什么要搞那么复杂呢?因此,先说一下场景,为何要经过TurboFilter去动态的修改日志级别。咱们在使用Java开发各类项目的时候必然的会引入不少框架,这些框架经过堆叠的方式完成所要提供的业务服务(一个服务请求在进入后会在这些框架中兜一圈,而后返回结果),当一个比较底层的框架在处理过程当中抛出了异常以后,这个异常会不断的向上传递。这个时候,有的框架直接throw,继续向上抛,而有的在throw以前还会本身打印一下error日志,这就致使了当出现异常的时候,每每会出现一连串相似的错误日志记录。若是对接了错误日志告警,就会出现重复告警的现象。为了解决相似这样的问题,修改源码从新编译最直接,可是不可取。因此但愿能够有更好的手段去控制这些已经被编码固化的日志打印信息。当咱们使用Logback的时候,TurboFilter就是解决该问题的工具之一。html
TurboFIlter不一样于以前在[《Logback中如何自定义灵活的日志过滤规则》]一文中介绍的那些经过ch.qos.logback.core.filter.Filter
接口实现的过滤器。ch.qos.logback.core.filter.Filter
实现的过滤器是与Appender绑定的,而TurboFIlter是与日志上下文绑定的,它会过滤全部的日志请求,而且TurboFIlter的方法中提供了丰富的可访问信息用来进行控制和改写。java
好比下面的实现,经过继承ch.qos.logback.classic.turbo.TurboFilter
类,并重写decide
方法,将org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter
类中本来要打印的ERROR日志DENY掉(过滤掉),同时以WARN级别打印一封相同的内容,这样就实现了对已定义日志的动态修改。web
public class ForceWarnFilter extends TurboFilter {
@Override
public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable throwable) {
if (level == Level.ERROR && logger.getName().equals("org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter")) {
logger.warn(marker, format, params);
return FilterReply.DENY;
}
return FilterReply.NEUTRAL;
}
}
复制代码
为了让上面定义的过滤器生效,须要在logback的配置xml中增长以下配置:spring
<configuration>
<turboFilter class="com.didispace.log.filter.ForceWarnFilter" />
......
</configuration>
复制代码
或者也能够在应用主类中增长:框架
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.addTurboFilter(new MyTurboFilter());
复制代码
更多关于Logback过滤器的内容可参考官方文档:logback.qos.ch/manual/filt…ide