目前業界日誌標配slf4j
+ logback
,當咱們調用slf4j的Logger.error()的時候到底發生了什麼?貼一張Logger執行流程圖
這裏出現了一個關鍵對象AppenderAttachableImpl
,若是Logger
的局部變量值爲null
,就調用父Logger
進行日誌打印,結合實際場景解釋一下app
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="TEST" class="ch.qos.logback.core.rolling.RollingFileAppender"> ..... </appender> <appender name="BIZ_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> ..... </appender> <logger name="bizLogger" level="INFO" additivity="false"> <appender-ref ref="BIZ_LOG"/> </logger> <root level="INFO"> <appender-ref ref="TEST"/> </root> </configuration>
上述是某個工程的logback.xml
的配置文件,AppenderAttachableImpl
就是配置中的appender
元素節點的抽象,那麼對若是Logger
局部變量AppenderAttachableImpl
爲null
,則調用父Logger
,這裏的父Logger
就是表明ROOT
節點的Logger
實例 spa
接下來關注另一個問題Logger
局部變量AppenderAttachableImpl
什麼才爲null
,來看下Logger
的建立過程,根據Logger logger = LoggerFactory.getLogger("name");
定位到類ch.qos.logback.classic.LoggerContext
構造方法
在構造方法中建立了ROOT Logger
實例,接下來看下實際建立Logger
實例代碼
若是loggerCache
存在對應實例則直接返回,若是ROOT-Logger.getChildByName
找不到對應name
的Logger
,就建立一個Logger
這裏能夠看出建立的Logger
實例的父Logger
就是ROOT-Logger
,可是在建立的時候並無涉及到AppenderAttachableImpl
的賦值.接下來再探索一下,AppenderAttachableImpl
的賦值過程(基於SpringBoot
)
直接定位到初始化類ch.qos.logback.classic.joran.action.LoggerAction
ch.qos.logback.core.joran.action.AppenderRefAction
在解析logback.xml
在解析到<logger>
元素的時候會建立相應Logger
實例,而且若是有<appender-ref>
子元素,就給實例的AppenderAttachableImpl
賦值日誌