利用logback 設(shè)置不同包下的日志級(jí)別
1、實(shí)現(xiàn)效果:項(xiàng)目的整體的日志打印級(jí)別為ERROR,但在某個(gè)包下或某個(gè)類想打印INFO級(jí)別的日志。
2、配置:
FILE是ERROR級(jí)別日志打??;
SPECIAL 是INFO級(jí)別日志打??;
FILE與SPECIAL唯一不同是日志保存路徑不同,其它策略相同;
通過(guò) logger標(biāo)簽指定包路徑或類路徑并引用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>
補(bǔ)充知識(shí):logback框架使用誤區(qū) 如何將所有包的ERROR級(jí)別日志集中打印到一個(gè)日志文件中
早就想寫這個(gè)事情了,起因是自己想寫一個(gè)東西,其中使用logback日志框架記錄日志
打算 將所有包的ERROR及以上級(jí)別日志打到一個(gè)文件中,各個(gè)包下的日志打到對(duì)應(yīng)包的文件中。
起初寫的xml配置類似于這樣:
<!-- 其中一個(gè)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>
然而運(yùn)行后卻發(fā)現(xiàn),這樣配置后的,并沒(méi)有達(dá)到預(yù)期目標(biāo)。
反而,所有INFO及以上的信息,不僅在appender appender-1和appender-2對(duì)應(yīng)的日志文件中有,在appender為ALL-ERROR對(duì)應(yīng)的日志文件中也都有,這是為何?
追蹤了一下斷點(diǎn),發(fā)現(xiàn)如下代碼片段:
/**
* 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);
}
}
這段代碼來(lái)自logback的 ch.qos.logback.classic.Logger文件,是最終決定日志內(nèi)容輸出在哪里的代碼。
從這段代碼我們可以發(fā)現(xiàn):
1. logback會(huì)找到第一個(gè)符合日志級(jí)別要求的logger,然后將日志內(nèi)容輸入到這個(gè)logger下配置的appender中。舉例來(lái)說(shuō):如果有一個(gè)com.some.package1內(nèi)的類的INFO級(jí)別日志,那么首先會(huì)找到logger com.some.package1,然后找到logger下配置的appender appender-1;最后根據(jù)appender-1的配置,將日志內(nèi)容輸出到appender-1配置的文件中。
2. 之后,logback根據(jù)additivty檢查logger是否允許繼承,如果配置為true(默認(rèn)為true),則查找上一級(jí)logger(實(shí)際是按照以包名為name查找上一層包的logger),找到logger后,不再判斷l(xiāng)ogger配置是否符合日志級(jí)別要求,直接找到對(duì)應(yīng)的appender,將日志內(nèi)容輸出。
這就帶來(lái)了一個(gè)問(wèn)題,位于低層次包的logger,在接收到日志后,不僅會(huì)把它輸出到自身的appender中,還會(huì)將其傳遞給位于高層次包logger的appender中,無(wú)論高層次包logger配置的日志級(jí)別是什么。正因?yàn)槿绱?,所以我打算將所有包的ERROR級(jí)別 日志輸出到一個(gè)文件的目的沒(méi)有實(shí)現(xiàn),反而所有INFO及以上級(jí)別的日志都輸出了。
按照這個(gè)思路,如果logger com.some.package1和com.some.package2日記級(jí)別為ERROR,而logger com.some日志級(jí)別為INFO的話,是否所有INFO及以上級(jí)別的日志都可以記入logger com.some對(duì)應(yīng)的appender下,而ERROR及以上級(jí)別的日志會(huì)記入logger com.some.package1和com.some.package2呢?測(cè)試證明,是這樣。
知道了為什么上面的配置達(dá)不到目的,接下來(lái)要考慮的是,借助什么方式實(shí)現(xiàn)這個(gè)需求呢?
logback提供了實(shí)現(xiàn)需求的方式:借助Filter來(lái)做:
既然logger無(wú)法判斷日志級(jí)別,那我們可以在對(duì)應(yīng)的appender里判斷日志級(jí)別。
logback的過(guò)濾器使用起來(lái)可以達(dá)到對(duì)每一條日志的DENY、ACCEPT和NEUTRAL。
根據(jù)文章開(kāi)始提出的需求,我們需要的是一個(gè)綁定appender的,過(guò)濾日志等級(jí)的filter,那么ch.qos.logback.classic.filter.ThresholdFilter正好是我們需要的。通過(guò)加入如下配置,appender ALL-ERROR將只能接受ERROR及以上的日志:
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter>
完整的xml配置如下,僅改變了filter的部分,就實(shí)現(xiàn)了需求:
<!-- 其中一個(gè)appender,其他appender與其相同 ,只有name、file和fileNamePattern不同,并且沒(méi)有filter的標(biāo)簽-->
<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>
更多關(guān)于logback的Filter的講解,請(qǐng)見(jiàn)
以上這篇利用logback 設(shè)置不同包下的日志級(jí)別就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
淺析Java.IO輸入輸出流 過(guò)濾流 buffer流和data流
這篇文章主要介紹了Java.IO輸入輸出流 過(guò)濾流 buffer流和data流的相關(guān)資料,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10
Java批量操作文件系統(tǒng)的實(shí)現(xiàn)示例
文件上傳和下載是java web中常見(jiàn)的操作,本文主要介紹了Java批量操作文件系統(tǒng)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03
springboot @Valid注解對(duì)嵌套類型的校驗(yàn)功能
這篇文章主要介紹了springboot~@Valid注解對(duì)嵌套類型的校驗(yàn),主要介紹 @Valid在項(xiàng)目中的使用,需要的朋友可以參考下2018-05-05
Java連接MySQL數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)交互的示例
數(shù)據(jù)庫(kù)是非常重要的一種存儲(chǔ)格式,可以大大提高存儲(chǔ)效率,本文主要介紹了Java連接MySQL數(shù)據(jù)庫(kù)并實(shí)現(xiàn)數(shù)據(jù)交互的示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
java.io.EOFException: Unexpected end of
本文主要介紹了java.io.EOFException: Unexpected end of ZLIB input stream異常解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Spring三級(jí)緩存解決循環(huán)依賴的過(guò)程分析
這篇文章主要介紹了Spring三級(jí)緩存解決循環(huán)依賴,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
云計(jì)算實(shí)驗(yàn):Java?MapReduce編程
這篇文章主要介紹了云計(jì)算實(shí)驗(yàn):Java?MapReduce編程,?居于Java圍繞MapReduce編程展開(kāi)詳細(xì)內(nèi)容,文章助大家掌握MapReduce編程,理解MapReduce原理,需要的朋友可以參考一下2021-12-12
Spring?Boot集成etcd的詳細(xì)過(guò)程
etcd是一個(gè)分布式鍵值存儲(chǔ)數(shù)據(jù)庫(kù),用于共享配置和服務(wù)發(fā)現(xiàn),etcd采用Go語(yǔ)言編寫,具有出色的跨平臺(tái)支持,很小的二進(jìn)制文件和強(qiáng)大的社區(qū),這篇文章主要介紹了SpringBoot集成etcd,需要的朋友可以參考下2023-08-08

