Spring Boot與logback的那XX件事

前言

????套用網(wǎng)絡(luò)流行的標(biāo)題,開始了這篇文章。之前使用Spring Boot,日志一直都是nohup再把標(biāo)準(zhǔn)輸出重定向到一個(gè)文件里,這樣毫無疑問是很low的。于是趁著項(xiàng)目的間歇,照著網(wǎng)上的教程哼哧哼哧的把logback配起來。配完之后,再想想怎么用起來更高大上一點(diǎn),就給自己提了下面幾個(gè)問題:

  • 不同級(jí)別的日志怎么輸出到不同的文件?
  • 不同服務(wù)的日志怎么輸出到不同的文件?
  • 怎么通過一個(gè)traceId把同一次請(qǐng)求里的多條日志串起來?
  • 日志的配置怎么在打包時(shí)能根據(jù)不同的環(huán)境去調(diào)整?
  • 運(yùn)行中的服務(wù)可以動(dòng)態(tài)的調(diào)整日志級(jí)別么?

????為了解決這些問題,就有了文章標(biāo)題所說的那XX件事。下面將大概介紹下各個(gè)問題的解決方案。最終的成果在代碼中:
????logtest

1.Filter

????第一個(gè)問題的解決方案,就是使用appender中的Filter。logback支持多種Filter,對(duì)于日志級(jí)別的過濾使用LevelFilter。

<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{requestId}] [%-5level] [%logger{36}:%line] - [%msg]%n
        </pattern>
        <charset>UTF-8</charset>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${LOG_HOME}/${APP_NAME}/debug.log.%d{yyyy-MM-dd}</FileNamePattern>
        <MaxHistory>${LOG_KEEP_TIME}</MaxHistory>
    </rollingPolicy>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>DEBUG</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
 </appender>

2.logger

????之前配置日志總是喜歡把a(bǔ)ppender都配置在root下,這個(gè)是一種全局的配置,其實(shí)可以通過logger進(jìn)一步細(xì)化。

<logger name="tactics" additivity="false" level="INFO">
    <appender-ref ref="tactics"/>
</logger>

????對(duì)應(yīng)的獲取logger方法為:

private final Logger tacticsLogger = LoggerFactory.getLogger("tactics");

????也可以按照我們慣用的方式:

<logger name="com.qcd.logtest.TacticsLogger" additivity="false" level="INFO">
    <appender-ref ref="tactics"/>
</logger>

????對(duì)應(yīng)的獲取logger方法為:

private final Logger tacticsLogger = LoggerFactory.getLogger(getClass());

????logger里面有個(gè)很重要的屬性additivity,這個(gè)屬性決定了日志里的內(nèi)容是否會(huì)向上一級(jí)日志傳遞。

3.MDC

????對(duì)于第三個(gè)問題想過自己去封裝一個(gè)日志工具類,通過ThreadLocal的方式來提供uuid,但是總覺得沒那么自然。也看到有人用Spring Cloud Sleuth來達(dá)到目的,又覺得太重。后面發(fā)現(xiàn)了MDC這個(gè)好東西,覺得很滿意。
????MDC(Mapped Diagnostic Context,映射調(diào)試上下文)是 logback 提供的一種方便在多線程條件下記錄日志的功能。MDC 可以看成是一個(gè)與當(dāng)前線程綁定的哈希表,可以往其中添加鍵值對(duì)。
????具體的使用代碼可以參考LogInterceptor.java。
????其中比較關(guān)鍵的兩處如下:

MDC.put("requestId", uuid);
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{requestId}] [%-5level] [%logger{36}:%line] - [%msg]%n

????在pattern中使用的[%X{requestId}]就是來自在MDC中存儲(chǔ)的uuid。

4.logback-spring.xml

????既然加上了spring這么個(gè)后綴,肯定會(huì)給你好處的。

  • 可以拿到application.properties里的配置:
<springProperty scope="context" name="logPath" source="logging.path"/>
<property name="LOG_HOME" value="${logPath}"/>
  • 可以拿到使用的profile
<springProfile name="test,dev">
     <logger name="com.qcd.logtest.TacticsLogger" level="INFO" />
</springProfile>
<springProfile name="pro">
     <logger name="com.qcd.logtest.TacticsLogger" level="ERROR" />
</springProfile>

5.actuator

????spring1.5.X版本引入的一個(gè)新的控制端點(diǎn):/loggers,這個(gè)端點(diǎn)非常強(qiáng)大,可以查看當(dāng)前的日志級(jí)別,還可以動(dòng)態(tài)修改日志級(jí)別。比如要修改LogtestController的日志級(jí)別,通過發(fā)送POST請(qǐng)求到:

http://localhost:9011/manage/loggers/com.qcd.logtest.controller.LogtestController

????請(qǐng)求體為:

{
    "configuredLevel": "DEBUG"
}

最后

????感謝強(qiáng)大的開源社區(qū),感謝互聯(lián)網(wǎng)上那些無私奉獻(xiàn)的同道?。?!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,551評(píng)論 19 139
  • 原文鏈接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao閱讀 4,892評(píng)論 0 9
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,272評(píng)論 6 342
  • 要加“m”說明是MB,否則就是KB了. -Xms:初始值 -Xmx:最大值 -Xmn:最小值 java -Xms8...
    dadong0505閱讀 5,067評(píng)論 0 53
  • 原本計(jì)劃在青島休息幾天再飛往下一站濰坊的,可是因?yàn)槭虑閬淼帽容^急一些,一個(gè)在濰坊的朋友打來電話,說他馬上就要...
    掠岸飛閱讀 429評(píng)論 0 0

友情鏈接更多精彩內(nèi)容