您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關日志級別怎么利用logback進行設置,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1、實現效果:項目的整體的日志打印級別為ERROR,但在某個包下或某個類想打印INFO級別的日志。
2、配置:
FILE是ERROR級別日志打印;
SPECIAL 是INFO級別日志打印;
FILE與SPECIAL唯一不同是日志保存路徑不同,其它策略相同;
通過 logger標簽指定包路徑或類路徑并引用SPECIAL;
<?xml version="1.0" encoding="UTF-8"?> <configuration> <contextName>test</contextName> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${catalina.home}/logs/test/test.%d.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d %p (%file:%line\)- %m%n -[%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}]</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="SPECIAL" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${catalina.home}/logs/test/special/special.%d.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%d %p (%file:%line\)- %m%n -[%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}]</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d %p (%file:%line\)- %m%n </pattern> <charset>UTF-8</charset> </encoder> </appender> <!--打印SQL--> <logger name="daoLog" level="ERROR" /> <!-- 記錄special操作日志 --> <logger name="aaa.bbb.ccc.DemoService" level="INFO" > <appender-ref ref="SPECIAL"/> </logger> <root level="error"> <appender-ref ref="FILE"/> <appender-ref ref="STDOUT"/> </root> </configuration>
補充知識:logback框架使用誤區 如何將所有包的ERROR級別日志集中打印到一個日志文件中
早就想寫這個事情了,起因是自己想寫一個東西,其中使用logback日志框架記錄日志
打算 將所有包的ERROR及以上級別日志打到一個文件中,各個包下的日志打到對應包的文件中。
起初寫的xml配置類似于這樣:
<!-- 其中一個appender,其他appender與其相同 ,只有name、file和fileNamePattern不同--> <appender name="ALL-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>all-error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern> ${log_dir}/all-error.%d{yyyy-MM-dd}.%i.log </fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>20GB</totalSizeCap> </rollingPolicy> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <logger name="com.some.package1" level="INFO" additivty="true"> <appender-ref ref="appender-1"/> </logger> <logger name="com.some.package2" level="INFO" additivty="true"> <appender-ref ref="appender-2"/> </logger> <logger name="com.some" level="ERROR" additivty="true"> <appender-ref ref="ALL-ERROR"/> </logger>
然而運行后卻發現,這樣配置后的,并沒有達到預期目標。
反而,所有INFO及以上的信息,不僅在appender appender-1和appender-2對應的日志文件中有,在appender為ALL-ERROR對應的日志文件中也都有,這是為何?
追蹤了一下斷點,發現如下代碼片段:
/** * Invoke all the appenders of this logger. * * @param event * The event to log */ public void callAppenders(ILoggingEvent event) { int writes = 0; for (Logger l = this; l != null; l = l.parent) { writes += l.appendLoopOnAppenders(event); if (!l.additive) { break; } } // No appenders in hierarchy if (writes == 0) { loggerContext.noAppenderDefinedWarning(this); } }
這段代碼來自logback的 ch.qos.logback.classic.Logger文件,是最終決定日志內容輸出在哪里的代碼。
從這段代碼我們可以發現:
1. logback會找到第一個符合日志級別要求的logger,然后將日志內容輸入到這個logger下配置的appender中。舉例來說:如果有一個com.some.package1內的類的INFO級別日志,那么首先會找到logger com.some.package1,然后找到logger下配置的appender appender-1;最后根據appender-1的配置,將日志內容輸出到appender-1配置的文件中。
2. 之后,logback根據additivty檢查logger是否允許繼承,如果配置為true(默認為true),則查找上一級logger(實際是按照以包名為name查找上一層包的logger),找到logger后,不再判斷logger配置是否符合日志級別要求,直接找到對應的appender,將日志內容輸出。
這就帶來了一個問題,位于低層次包的logger,在接收到日志后,不僅會把它輸出到自身的appender中,還會將其傳遞給位于高層次包logger的appender中,無論高層次包logger配置的日志級別是什么。正因為如此,所以我打算將所有包的ERROR級別 日志輸出到一個文件的目的沒有實現,反而所有INFO及以上級別的日志都輸出了。
按照這個思路,如果logger com.some.package1和com.some.package2日記級別為ERROR,而logger com.some日志級別為INFO的話,是否所有INFO及以上級別的日志都可以記入logger com.some對應的appender下,而ERROR及以上級別的日志會記入logger com.some.package1和com.some.package2呢?測試證明,是這樣。
知道了為什么上面的配置達不到目的,接下來要考慮的是,借助什么方式實現這個需求呢?
logback提供了實現需求的方式:借助Filter來做:
既然logger無法判斷日志級別,那我們可以在對應的appender里判斷日志級別。
logback的過濾器使用起來可以達到對每一條日志的DENY、ACCEPT和NEUTRAL。
根據文章開始提出的需求,我們需要的是一個綁定appender的,過濾日志等級的filter,那么ch.qos.logback.classic.filter.ThresholdFilter正好是我們需要的。通過加入如下配置,appender ALL-ERROR將只能接受ERROR及以上的日志:
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter>
完整的xml配置如下,僅改變了filter的部分,就實現了需求:
<!-- 其中一個appender,其他appender與其相同 ,只有name、file和fileNamePattern不同,并且沒有filter的標簽--> <appender name="ALL-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>all-error.log</file> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern> ${log_dir}/all-error.%d{yyyy-MM-dd}.%i.log </fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>60</maxHistory> <totalSizeCap>20GB</totalSizeCap> </rollingPolicy> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender> <logger name="com.some.package1" level="INFO" additivty="true"> <appender-ref ref="appender-1"/> </logger> <logger name="com.some.package2" level="INFO" additivty="true"> <appender-ref ref="appender-2"/> </logger> <logger name="com.some" level="ERROR" additivty="true"> <appender-ref ref="ALL-ERROR"/> </logger>
上述就是小編為大家分享的日志級別怎么利用logback進行設置了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。