Hello,大家好,我是樓下小黑哥~
最近被公司派去北京出差,本以為是個輕鬆的差事,北京一週遊~
但是沒想到第一天就是九點半下班, 大意了~
好了,回到正題,今天來講下最近除錯專案的時候發現的一個 Logback 日誌級別設定不生效的問題。
問題背景
事情是這樣的,我們的專案是一個 SpringBoot 的工程的,其中日誌框架使用的是 LogBack,配置檔案如下所示:
<configuration scan="true" scanPeriod=" 5 seconds" debug="true">
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="DEBUG"/>
<root level="debug">
<appender-ref ref="stdout"/>
</root>
</configuration>
為了方便檢視專案執行的 SQL,這裡我把日誌的級別調整成 DEBUG
。
執行的專案,執行結果比較令人驚訝,日誌僅僅輸出了 INFO
日誌,並沒有輸出 DEBUG
日誌。
剛開始還以為 Logback 配置檔案寫的有問題,才導致這個問題。網上找了幾個例子,對比了一下,這類的配置檔案並沒有什麼問題。
於是進行一系列深度排查(令人頭禿),最終終於找到了問題的原因。
問題原因
由於 Logback 的配置 debug=true
,專案啟動的時候,將會列印出 Logback 內部日誌資訊,日誌如下:
從這個日誌可以看到,Logback Root 已經設定為 DEBUG
。
那為什麼專案啟動之後,DEBUG 就失效了?
不要急,接著往下看。
當 Spring 容器啟動之後,Spring 內部將會發出一些列的 ApplicationEvent
,然後這些將會被各類已經註冊的 ApplicationListener
監聽。
由於這個專案是一個 SpringBoot 的工程,裡面有一個 LoggingApplicationListener
將會監聽 ApplicationEnvironmentPreparedEvent
,程式碼如下:
這裡面的邏輯比較簡單,獲取系統配置的日誌級別,levels
值如下:
可以看到這裡 root 對應的值為 info
,這裡將會繼續呼叫 Logback 的的方法設定日誌級別,日誌輸出如下:
上面這些日誌級別配置來自其實來自 SpringBoot 的配置檔案 application.properties
總結
最後,總結一下,SpringBoot 專案,如果使用單獨的 LogBack 配置檔案,SpringBoot 的配置檔案 application.properties 配置的 logging.level.root 將會覆蓋的 Logback 配置檔案中的 root 的配置:
<root level="debug">
<appender-ref ref="stdout"/>
</root>
問題看起來是那麼簡單,排查的過程真的是令人頭禿。