SpringBoot logging - 1

SpringBoot的日志系統(tǒng)

SpringBoot支持三種日志系統(tǒng),分別是Log4J2、Logback和j.u.l。其中Log4J2和Logback實(shí)現(xiàn)了Slf4J API。SpringBoot中默認(rèn)的日志系統(tǒng)是Logback。

image.png

Springboot logging 分為三個階段,

  • 第一個階段是在進(jìn)入SpringApplication.run 方法后,采用的logging,第二個階段 LoggingApplicationListener之后,實(shí)現(xiàn)的logging, 第三個階段是,用戶可以自己實(shí)現(xiàn)Springboot 的listener 來替代Springboot 本身的logging。
  1. 第一步
    在日志系統(tǒng)的配置尚未生效前,通過org.apache.commons.logging.LogFactory#getLog(java.lang.String)獲取LoggerContext,使用各日志系統(tǒng)的默認(rèn)配置。
  2. 第二步
  • 使用最新的配置文件更新LoggerContext,更新前需要stop and reset LoggerContext。
  • 使用屬性配置更新各Logger的日志輸出級別。
  • 按照最新的LoggerContext進(jìn)行日志處理。
  1. 第三步
    可選。 可以根據(jù)自己的需要自己實(shí)現(xiàn)LoggerLister來再次覆蓋Springboot 原生的logger。主要原因是第二步的logger 只能有固定level,比如info 。 但是企業(yè)級可能有更靈活的需求,比如啟動的時候我希望root logger level 是info,可以看到更多的信息,但是 啟動完畢期望root logger 的level 是warn ,防止log flush。 那么第二步的logger 就不滿足需求了需要在第三步做定制。

spring-jcl

springboot啟動入口類SpringApplication有一個Logger靜態(tài)變量

private static final Log logger = LogFactory.getLog(SpringApplication.class);

此時的LogFactory 的包為import org.apache.commons.logging.LogFactory; 這個類存在于spring-jcl。spring-jcl提供了Apache Commons Logging的LogFactory API接口的最小實(shí)現(xiàn),僅提供常見的Log查詢方法。它是受JCL-over-SLF4J bridge的啟發(fā)而產(chǎn)生的, 它與Commons Logging API的所有常用方法兼容,特別是通過 LogFactory.getLog(Class/String) 進(jìn)行的字段初始化。因此,我們的項(xiàng)目中如果出現(xiàn)了spring-jcl.jar時,就不能再使用commons-logging.jar了!

此實(shí)現(xiàn)不支持Commons Logging的原始提供程序檢測。 而是僅檢查Spring Framework類路徑中Log4j 2.x API和SLF4J 1.7 API是否存在,如果兩者都不可用,則退回到j(luò)ava.util.logging。

    public static Log getLog(Class clazz) throws LogConfigurationException {
        return getFactory().getInstance(clazz);
    }

LogFactory.getInstance->LogFactoryService.getInstance->LogAdapter.createLog(name)
ogAdapter #static{}這里的LogFactoryLogAdapter都是srping-core包下面的spring-jcl包里面的類,其中LogAdapter中配置了四個變量,除了LOG4J_SPIlog4j日志系統(tǒng),其余的都是slf4j日志系統(tǒng)。

image

繼續(xù)往下看代碼
isPresent()方法就是一行Class.forName()方法,用來判定日志不同接口的具體實(shí)現(xiàn)類,然后用實(shí)現(xiàn)類創(chuàng)建日志。

1、 查找org.apache.logging.log4j.spi.ExtendedLogger;

  • 如果ExtendedLogger存在,那么繼續(xù)查找org.apache.logging.slf4j.SLF4JProviderorg.slf4j.spi.LocationAwareLogger,如果SLF4JProviderLocationAwareLogger都存在,那么就啟用SLF4J_LAL日志系統(tǒng);如果SLF4JProviderLocationAwareLogger有一個不存在,就啟用LOG4J 2.X日志系統(tǒng);

2、如果ExtendedLogger不存在,就查找org.slf4j.spi.LocationAwareLogger;

  • 如果LocationAwareLogger存在,就啟用SLF4J_LAL日志系統(tǒng);
  • 如果LocationAwareLogger不存在,就繼續(xù)查找org.slf4j.Logger;

3、如果org.slf4j.Logger存在,就啟用SLF4J日志系統(tǒng);
4、 如果以上都不存在,就啟用JUL日志系統(tǒng)。

1.2根據(jù)日志接口創(chuàng)建日志

--> LogAdapter.createLog(name)

image
image

此時的LoggerFactory 為 org.slf4j,LoggerFactory
然后就會進(jìn)入到slf4j

    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }

之后細(xì)節(jié)可以參考Logback Logger創(chuàng)建

然后進(jìn)入到LoggerContext.getLogger 方法中。

通過這樣的方式,SpringApplicaiton里的logger 就創(chuàng)建成了, 此時Root Logger level 為debug, 輸出為console。 這樣Springboot 啟動的log就可以輸出出來了。

接下來講一下,在Enviroment prepare 中進(jìn)行系統(tǒng)配置的logger 設(shè)定。

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

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

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