Java日志框架打印应用程序日志代码的执行情况分析
作者:千千寰宇
在配置INFO日志级别时,日志器(logger)中debug级的日志代码仍会被执行,只是是否输出取决于配置的日志级别,本文基于Java 1.8、SLF4J 1.7.25和Log4j 2.20.0进行实验,详述了日志框架处理日志代码的机制,感兴趣的朋友一起看看吧
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() ); } }
到此这篇关于Java日志框架打印应用程序日志代码的执行情况的文章就介绍到这了,更多相关Java日志框架打印应用程序日志代码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!