前言
????套用網(wǎng)絡(luò)流行的標(biāo)題楼镐,開始了這篇文章。之前使用Spring Boot往枷,日志一直都是nohup再把標(biāo)準(zhǔn)輸出重定向到一個文件里框产,這樣毫無疑問是很low的凄杯。于是趁著項目的間歇,照著網(wǎng)上的教程哼哧哼哧的把logback配起來秉宿。配完之后戒突,再想想怎么用起來更高大上一點,就給自己提了下面幾個問題:
- 不同級別的日志怎么輸出到不同的文件描睦?
- 不同服務(wù)的日志怎么輸出到不同的文件膊存?
- 怎么通過一個traceId把同一次請求里的多條日志串起來?
- 日志的配置怎么在打包時能根據(jù)不同的環(huán)境去調(diào)整忱叭?
- 運行中的服務(wù)可以動態(tài)的調(diào)整日志級別么隔崎?
????為了解決這些問題,就有了文章標(biāo)題所說的那XX件事韵丑。下面將大概介紹下各個問題的解決方案爵卒。最終的成果在代碼中:
????logtest
1.Filter
????第一個問題的解決方案,就是使用appender中的Filter埂息。logback支持多種Filter技潘,對于日志級別的過濾使用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
????之前配置日志總是喜歡把appender都配置在root下千康,這個是一種全局的配置,其實可以通過logger進(jìn)一步細(xì)化铲掐。
<logger name="tactics" additivity="false" level="INFO">
<appender-ref ref="tactics"/>
</logger>
????對應(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>
????對應(yīng)的獲取logger方法為:
private final Logger tacticsLogger = LoggerFactory.getLogger(getClass());
????logger里面有個很重要的屬性additivity拾弃,這個屬性決定了日志里的內(nèi)容是否會向上一級日志傳遞。
3.MDC
????對于第三個問題想過自己去封裝一個日志工具類摆霉,通過ThreadLocal的方式來提供uuid豪椿,但是總覺得沒那么自然。也看到有人用Spring Cloud Sleuth來達(dá)到目的携栋,又覺得太重搭盾。后面發(fā)現(xiàn)了MDC這個好東西,覺得很滿意婉支。
????MDC(Mapped Diagnostic Context鸯隅,映射調(diào)試上下文)是 logback 提供的一種方便在多線程條件下記錄日志的功能。MDC 可以看成是一個與當(dāng)前線程綁定的哈希表向挖,可以往其中添加鍵值對蝌以。
????具體的使用代碼可以參考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中存儲的uuid何之。
4.logback-spring.xml
????既然加上了spring這么個后綴跟畅,肯定會給你好處的。
- 可以拿到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版本引入的一個新的控制端點:/loggers溶推,這個端點非常強大徊件,可以查看當(dāng)前的日志級別奸攻,還可以動態(tài)修改日志級別。比如要修改LogtestController的日志級別虱痕,通過發(fā)送POST請求到:
http://localhost:9011/manage/loggers/com.qcd.logtest.controller.LogtestController
????請求體為:
{
"configuredLevel": "DEBUG"
}
最后
????感謝強大的開源社區(qū)舞箍,感謝互聯(lián)網(wǎng)上那些無私奉獻(xiàn)的同道!=哉睢疏橄!