logback.xml詳解

介紹之前博文有專門介紹過基于Log4j Appender 實現大數據平臺組件日志的采集, 本篇主要對java項目中經常會接觸到的logback.xml文件的配置做一個介紹和總結.
logback.xml 配置下面是一個logback配置demo, 常用的配置都有, 一一介紹下每個配置的作用.
<?xml version="1.0" encoding="UTF-8"?><configuration> <property name="LOG_HOME" value="d:/opt/module/logs" /> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%msg%n</pattern></encoder> </appender> <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${LOG_HOME}/app.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_HOME}/app.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy><encoder><pattern>%msg%n</pattern></encoder> </appender> <!-- 將某一個包下日志單獨打印日志 --> <logger name="com.bigdata.logger.LoggerExample" level="INFO" additivity="false"><appender-ref ref="rollingFile" /><appender-ref ref="console" /> </logger> <root level="error" additivity="false"><appender-ref ref="console" /> </root></configuration>配置說明:

  • property定義屬性,類似全局變量, 比如上面我們定義的LOG_HOME 日志寫入路徑文件路徑,下面的appender 可以直接引用
  • appender追加器,描述如何寫入到文件中(寫在哪,格式,文件的切分)ConsoleAppender--追加到控制臺RollingFileAppender--滾動追加到文件encoder: 對日志進行格式化 。rollingPolicy:當發生滾動時 , 決定RollingFileAppender的行為 , 涉及文件移動和重命名.TimeBasedRollingPolicy 是根據時間制定滾動策略,fileNamePattern:文件輸出格式
  • logger控制器,描述如何選擇追加器注意:要是單獨為某個類指定的時候,要修改類的全限定名appender-ref: 引用前面定義的appenderlevel="error": 定義輸出的日志級別, 低于此日志級別的日志不會輸出additivity="false":這個稍微不太好理解, 下面我寫個代碼, 實操下.
  • 日志級別TRACE->DEBUG ->INFO -> WARN ->ERROR -> FATAL從左到右, 由到高
  • root根級別日志
實戰code項目結構:
logback.xml詳解

文章插圖
maven 配置:
<dependencies><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.6</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.6</version></dependency></dependencies>測試代碼:
public class LoggerExample {private static final Logger logger = LoggerFactory.getLogger(LoggerExample.class);public static void main(String[] args) {logger.info("Example log from {}", LoggerExample.class.getSimpleName());logger.error("Error log");}}直接運行的結果:
logback.xml詳解

文章插圖
console和app.log文件的結果一樣
修改 additivity="true
<logger name="com.bigdata.logger.LoggerExample" level="INFO" additivity="true">再次運行結果:
logback.xml詳解

文章插圖

logback.xml詳解

文章插圖
可以看出app.log正常, 但是cosole 上打印了重復的日志, 說明命中了console appender兩次, log和root 各一次, 但是奇怪的是, 第一條info日志為什么會重復, 因為root level="ERROR", 理論上info 日志級別比ERROR級別要低, 不應該在console里出現才對.
我們看下logback相關的源碼是如何處理的.
https://github.dev/qos-ch/logback/blob/master/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java#L256
/*** Invoke all the appenders of this logger.** @param event The event to log*/public void callAppenders(ILoggingEvent event) {int writes = 0;for (Logger l = this; l != null; l = l.parent) {writes += l.appendLoopOnAppenders(event);if (!l.additive) {break;}}// No appenders in hierarchyif (writes == 0) {loggerContext.noAppenderDefinedWarning(this);}}從代碼我們可以看出, logback 的整個輸出是從logger子節點開始往上遍歷, 如果additive = false, 就直接break 循環直接結束, 如果break = true, 會繼續往上尋找父節點,直到最終 l == null. 同時會記錄writes,writes == 0,認為沒有定義appender輸出源

推薦閱讀