logback.xml詳解
- 2022 年 10 月 16 日
- 筆記
- [Java/Scala], log
介紹
之前博文有專門介紹過基於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: 引用前面定義的appender
level=”error”: 定義輸出的日誌級別, 低於此日誌級別的日誌不會輸出
additivity=”false”: 這個稍微不太好理解, 下面我寫個代碼, 實操下. -
日誌級別
TRACE->DEBUG ->INFO -> WARN -> ERROR -> FATAL
從左到右, 由到高 -
root
根級別日誌
實戰code
項目結構:
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");
}
}
直接運行的結果:
console和app.log文件的結果一樣
修改 additivity=”true
<logger name="com.bigdata.logger.LoggerExample" level="INFO" additivity="true">
再次運行結果:
可以看出app.log正常, 但是cosole 上打印了重複的日誌, 說明命中了console appender兩次, log和root 各一次, 但是奇怪的是, 第一條info日誌為什麼會重複, 因為root level=”ERROR”, 理論上info 日誌級別比ERROR級別要低, 不應該在console里出現才對.
我們看下logback相關的源碼是如何處理的.
/**
* 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 hierarchy
if (writes == 0) {
loggerContext.noAppenderDefinedWarning(this);
}
}
從代碼我們可以看出, logback 的整個輸出是從logger子節點開始往上遍歷, 如果additive = false, 就直接break 循環直接結束, 如果break = true, 會繼續往上尋找父節點,直到最終 l == null. 同時會記錄writes, writes == 0,認為沒有定義appender輸出源
代碼沒有關於日誌級別的控制. 所以以後如果只希望打印日誌到子節點的appeder, 父節點的appender忽略, 就設置additivity = false, 默認值為true, 這樣日誌就不會重複了.
總結
主要對logback.xml 常用配置的作用介紹, 通過logback 的相關源碼對additivity參數有了更深的認識. additivity 默認值為true, 如果不希望在某些場景下打印重複的日誌, 可以設置為false, additivity 配置不受level配置的影響.