logback過濾部分日志輸出的操作
logback過濾部分日志輸出
場景
使用監(jiān)控異常日志進行告警時,部分異常日志可能只是不需要告警,但無法通過編碼去除時,可以通過不輸出這類異常日志達到忽略告警的目的。
比如在系統(tǒng)中經(jīng)常會出現(xiàn)斷開的管道的相關(guān)問題,異常如下
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 斷開的管道
org.apache.catalina.connector.ClientAbortException: java.io.IOException: broken pipe
[587ce8c8] Error [reactor.netty.ReactorNetty$InternalNettyException: java.nio.channels.ClosedChannelException] for HTTP GET "/xxxx", but ServerHttpResponse already committed (200 OK)
有因為使用框架的原因異常無法捕獲,在不改源碼的情況下可以通過是用日志過濾的方式處理。
日志過濾
基于logback的基礎(chǔ)上引入jar包,不引入無法啟動。
<!--日志過濾-->
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>commons-compiler</artifactId>
<version>3.0.12</version>
</dependency>
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.12</version>
</dependency>
添加過濾條件
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--增加日志匹配處理-->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<!--匹配處理器-->
<evaluator>
<!-- 處理模式,默認為 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
<!-- 存在某個字符串則匹配成功 -->
<expression>return message.contains("broken pipe");</expression>
<!-- <expression>return message.contains("broken pipe")
|| message.contains("斷開的管道") ;</expression> -->
</evaluator>
<!--匹配則停止執(zhí)行日志輸出-->
<OnMatch>DENY</OnMatch>
<!--不匹配則往下執(zhí)行-->
<OnMismatch>ACCEPT</OnMismatch>
</filter>
<!--調(diào)用其他日志處理-->
<appender-ref ref="KAFKA"/>
</appender>
Logback 自定義靈活的日志過濾規(guī)則
當我們需要對日志的打印要做一些范圍的控制的時候,通常都是通過為各個Appender設(shè)置不同的Filter配置來實現(xiàn)。在Logback中自帶了兩個過濾器實現(xiàn):ch.qos.logback.classic.filter.LevelFilter和ch.qos.logback.classic.filter.ThresholdFilter,用戶可以根據(jù)需要來配置一些簡單的過濾規(guī)則,下面先簡單介紹一下這兩個原生的基礎(chǔ)過濾器。
ch.qos.logback.classic.filter.LevelFilter過濾器的作用是通過比較日志級別來控制日志輸出。
下面是一個只記錄日志級別為ERROR的例子
<appender name="ERROR_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/error.log</file>ds
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
</encoder>
</appender>
LevelFilter通過定義日志級別,并設(shè)置匹配與不匹配的處理策略來控制針對某個級別日志的輸出策略。
當我們要設(shè)置多個不同級別的日志策略的時候,如果僅依靠這個過濾器,我們就要級聯(lián)的定義多個filter來控制才能實現(xiàn),顯然不是很方便,所以此時我們就可以使用ch.qos.logback.classic.filter.ThresholdFilter過濾器來控制了。
比如下面的配置,實現(xiàn)了只記錄WARN及以上級別的控制,比WARN級別低(如:INFO、DEBUG、TRACE)都不會記錄。
<appender name="WARN_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/warn_error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
</encoder>
</appender>
通過上述介紹的兩個過濾器來控制日志的記錄級別已經(jīng)滿足絕大部分的需求,但是可能還是會出現(xiàn)一些特殊情況,需要自定義復雜的過濾規(guī)則,比如想過濾掉一些框架中的日志,通過自帶的幾個過濾器已經(jīng)無法完全控制,并且也不希望修改框架源碼來實現(xiàn)。這個時候,我們就可以自己來實現(xiàn)過濾器,并配置使用。實現(xiàn)的方式也很簡單,只需要實現(xiàn)Logback提供的ch.qos.logback.core.filter.Filter接口即可。
下面舉一個簡單的例子
public class MyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if (event.getLevel() == Level.ERROR) {
switch (event.getLoggerName()) {
case "org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter":
return FilterReply.DENY;
}
return FilterReply.ACCEPT;
}
return FilterReply.DENY;
}
}
上面過濾器的功能主要是通過重寫decide,限制了org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter類輸出ERROR級別的日志記錄。在編寫好自己的過濾器實現(xiàn)之后,只需要在Appender中配置使用就能實現(xiàn)自己需要的靈活過濾規(guī)則了:
<appender name="WARN_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/warn_error.log</file>
<filter class="com.didispace.log.filter.ExceptionClassFilter"></filter>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
</encoder>
</appender>
更多關(guān)于Logback過濾器的內(nèi)容可參考官方文檔
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring多線程通過@Scheduled實現(xiàn)定時任務(wù)
這篇文章主要介紹了Spring多線程通過@Scheduled實現(xiàn)定時任務(wù),@Scheduled?定時任務(wù)調(diào)度注解,是spring定時任務(wù)中最重要的,下文關(guān)于其具體介紹,需要的小伙伴可以參考一下2022-05-05
SpringCloud通過Feign傳遞List類型參數(shù)方式
這篇文章主要介紹了SpringCloud通過Feign傳遞List類型參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

