0 引言
- 我常以為 配置 INFO 日誌級別時, 應用程式程式碼中日誌器(logger) debug 級的日誌程式碼,不會被執行(比如,實驗1中的
printTestLog
函式)。但今天線上的問題,證實了這個思路是錯的。
1 驗證實驗
- 版本資訊
- jdk : 1.8
- 日誌元件
slf4j.version
: 1.7.25log4j.version
: 2.20.0
<!-- log [start] -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<!--<version>2.13.3</version>-->
<version>${log4j.version}</version>
<scope>compile</scope>
</dependency>
<!-- log [end] -->
實驗1:日誌框架列印應用程式日誌程式碼的執行情況
日誌配置策略: log4j2.properties
log4j2.properties
## 日誌的等級(自定義配置項)
##property.log.level=ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF
property.log.level=DEBUG
# ------------------- [1.1] 定義 RootLogger 等 全域性性配置(不可隨意修改) ------------------- #
## rootLogger, 根記錄器,所有記錄器的父輩
## 指定根日誌的級別 | All < Trace < Debug < Info < Warn < Error < Fatal < OFF
rootLogger.level=${log.level}
... //略
應用程式程式碼: LogTest
LogTest
package test.java.lang;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LogTest {
public static String printTestLog(){
return "HelloWorld";//關鍵程式碼行
}
public static void main(String[] args) {
log.debug( "log:{}", printTestLog() );
}
}
實驗結果
log.level=INFO
時
關鍵程式碼行 : 被執行
日誌輸出結果: 空
log.level=DEBUG
時
關鍵程式碼行 : 被執行
日誌輸出結果:
[20XX/10/16 16:01:28.585] [TID: N/A] [DEBUG] [main] [LogTest.java:12 main] log:HelloWorld
最終結論
-
無論 應用程式日誌程式碼 logger 使用何種日誌級別列印日誌,程式碼行中的程式均會被執行,只是最終輸出時由日誌框架根據配置logger所屬class的日誌級別決定是否輸出(appender)
-
解決方法1:應用程式中,如無必要,刪除這類日誌程式碼。
-
解決方法2:
log.isDebugEnabled(...)/isInfoEnabled(...)/isWarnEnabled(...)/isErrorEnabled(...)/...
public static void main(String[] args) {
if(log.isDebugEnabled()){//將會根據 使用者所配置的日誌級別(log.level),決定是否執行 IF 內的程式碼
log.debug( "log:{}", printTestLog() );
}
}
X 參考文獻
- 無