java.util.logging.Logger 的级别与其根记录器不同

java.util.logging.Logger has different Level than it's root Logger

在我的应用程序中,我曾将 java.util.logging 的根记录器及其所有处理程序设置为 Level.FINEST,如下所示:

Logger.getLogger("").setLevel(Level.FINEST);
for (Handler handler : Logger.getLogger("").getHandlers()) {
      handler.setLevel(Level.FINEST);
}

稍后我会创建一个 class 记录器,如下所示:

private static final Logger JAVA_LOG = Logger.getLogger(MyClass.class.getName());

现在这个记录器级别是 INFO(这似乎是 JUL 的默认值),而它的根记录器级别已正确设置为 FINEST。不应该为根记录器设置级别也为根记录器的所有子记录器设置级别吗?我在检索 class 记录器时做错了什么吗?

不应该为根 Logger 设置 Level 也为根 Logger 的所有子记录器设置 Level 吗?

不,显然您正在创建一个新的 Logger 对象。 Javadoc for getLogger 状态:

If a new logger is created its log level will be configured based on the LogManager configuration and it will configured to also send logging output to its parent's Handlers.

请注意,即使之前有同名的 Logger 对象,您也不能依赖 getLogger 到 return 相同的对象,因为如果存在,它可能已被垃圾回收不是对该对象的强引用。

如果您的目标是在您的项目中创建具有相同日志级别的所有 Logger 对象,您不应该以编程方式而是通过配置[=34] =].这就是 java.util.logging 派上用场的地方。总体优势是您可以 运行 您的应用程序处于不同的日志级别,甚至无需更改一行代码。

只需编辑您的配置文件(本质上就是上面提到的LogManager configuration)。它被称为 logging.properties 并且位于您的 JRE 目录中。您可以在那里编辑最后一段并配置项目范围或class-缩小的日志级别:

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

myProject.MyClass.level = FINE
myProject.MyOtherNotSoImportantClass.level = INFO
mySecondProject.MainClass.level = NONE

一个更好的解决方案是将 logging.properties 复制到您的项目目录并使用

调用您的应用程序
java -Djava.util.logging.config.file=./src/test/resources/logging.properties

接受的答案完全有效,我完全同意。

就是说,我想补充一点知识...随心所欲。

private static final Logger JAVA_LOG = Logger.getLogger(MyClass.class.getName());
static { JAVA_LOG.setLevel(null); }

这将告诉它继承其祖先的日志级别。 Logger.setLevel() javadoc

If the new level is null, it means that this node should inherit its level from its nearest ancestor with a specific (non-null) level value.