Java 11下java.util.logging的FINE级别日志无法输出及配置疑问
问题场景
环境:Java 11 + Maven
在SLF4J过滤器中必须使用java.util.logging(无法使用SLF4J日志器),已通过命令行系统属性或logging.properties将日志级别设为FINER,但控制台仅输出SEVERE、INFO、WARNING级日志,FINE级别日志完全不显示。
代码与配置详情
- Logger实例创建代码:
private static Logger logger = Logger.getLogger("abc");
- 初始
src/main/resources/logging.properties配置:
handlers = java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter abc.level=FINER
- 日志输出代码:
logger.log(Level.FINE, "Loading security filter config file: " + fileName + " with override contents: " + overrideContents); logger.log(Level.SEVERE, "This is a test."); logger.severe("This is a test."); logger.config("This is a test."); logger.info("This is a test."); logger.warning("This is a test."); logger.fine("Loading security filter config file: " + fileName + " with override contents: " + overrideContents);
更新后的进展与疑问
调整配置后有部分进展,但希望logging.properties仅做基础配置,保留默认日志级别,通过命令行参数动态提升级别。当前配置与问题如下:
- 当前
logging.properties内容:
handlers = java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter abc.level=FINEST
- 遇到的问题:
- 无命令行参数时,无法看到FINE/FINEST级日志
- 添加
-Djava.util.logging.config.file=src/main/resources/logging.properties参数后,可输出额外日志 - 尝试不在配置文件中设置级别,仅通过命令行设置时,无任何日志输出,命令行的.level设置似乎被忽略,仅配置文件中的
java.util.logging.ConsoleHandler.level = ALL生效
- 疑问:配置文件中不带
java.util.logging前缀的handler属性是什么作用?
问题分析与解决
1. 初始配置下FINE日志不显示的核心原因
java.util.logging输出日志需要同时满足两个条件:
- Logger自身级别:必须小于等于目标日志级别(比如要输出FINE,Logger级别需设为FINER、FINEST或ALL)
- 关联Handler级别:Handler的级别也必须小于等于目标日志级别
初始配置看似正确,但Maven运行时默认加载的是JDK自带的logging.properties(路径通常为$JAVA_HOME/conf/logging.properties),而非项目中的自定义配置。默认配置里ConsoleHandler的级别一般是INFO,直接过滤了FINE级日志。
2. 命令行级别设置不生效的原因
当不指定-Djava.util.logging.config.file时,JVM加载默认配置,根Logger级别为INFO,未命名的abc Logger会继承根Logger级别。java.util.logging默认不会自动读取命令行中的Logger级别属性,所以仅通过-Dabc.level=FINER无法生效,必须结合配置文件或代码手动加载。
3. 配置文件中无前缀属性的说明
配置文件中不带java.util.logging前缀的属性属于**根Logger("")**的配置,比如handlers、level等。带前缀的属性则对应具体的Logger或Handler:
handlers = java.util.logging.ConsoleHandler:为根Logger绑定ConsoleHandlerjava.util.logging.ConsoleHandler.level:单独设置ConsoleHandler的级别abc.level:设置名为abc的Logger的级别
4. 满足需求的配置方案
要实现“配置文件做基础配置,命令行动态提升级别”,可采用以下两种方案:
方案一:代码读取系统属性动态设置级别
保留基础logging.properties:
handlers = java.util.logging.ConsoleHandler .level=INFO java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
在代码中读取系统属性并设置Logger级别:
String levelStr = System.getProperty("abc.level", "INFO"); Level level = Level.parse(levelStr); logger.setLevel(level);
启动命令:
java -Dabc.level=FINER -jar your-app.jar
方案二:配置文件引用系统属性
修改logging.properties,让abc.level引用系统属性:
handlers = java.util.logging.ConsoleHandler .level=INFO java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter # 引用系统属性,默认值为INFO abc.level=${abc.level:INFO}
启动命令:
java -Dabc.level=FINER -Djava.util.logging.config.file=src/main/resources/logging.properties -jar your-app.jar
内容的提问来源于stack exchange,提问作者David M. Karr

