问题

TheJavaDocs forjava.util.logging.Levelstate:

降序的级别为:

  • 严重(最高价值)
  • 警告
  • 信息
  • CONFIG
  • 精细
  • 更好
  • 最好的(最低价值)

资源

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        logger.setLevel(Level.FINER);
        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

##输出

Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .

问题陈述

我的例子设置了LevelFINER,所以我期待每个循环看到2条消息。相反,我看到每个循环都有一条消息(缺少Level.FINE消息)。

需要更改什么才能看到2337100502(,FINERorFINEST)的输出?

##更新(解决方案)

感谢Vineet Reynolds' answer,这个版本符合我的期望。它显示3xINFO消息和3xFINE消息。

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        // LOG this level to the log
        logger.setLevel(Level.FINER);

        ConsoleHandler handler = new ConsoleHandler();
        // PUBLISH this level
        handler.setLevel(Level.FINER);
        logger.addHandler(handler);

        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

#1 热门回答(111 赞)

记录器仅记录消息,即它们创建日志记录(或记录请求)。它们不会将消息发布到目标,这由处理程序负责。设置记录器的级别只会导致它匹配该级别或更高级别的tocreatelog记录。

你可能正在使用aConsoleHandler(我无法推断你的输出是System.err或文件的位置,但我认为它是前者),默认为发布levelLevel.INFO的日志记录。你必须配置此处理程序,以发布levelLevel.FINER及更高版本的日志记录,以获得所需的结果。

我建议阅读Java Logging Overview指南,以了解底层设计。该指南涵盖了Logger和Handler概念之间的区别。
编辑处理程序级别1.使用配置文件
可以修改java.util.logging属性文件(默认情况下,这是JRE_HOME/lib中的logging.properties文件)以更改ConsoleHandler的默认级别:

java.util.logging.ConsoleHandler.level = FINER

2.在运行时创建处理程序
建议不要这样做,因为它会导致覆盖全局配置。在整个代码库中使用它将导致可能无法管理的记录器配置。

Handler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINER);
Logger.getAnonymousLogger().addHandler(consoleHandler);

#2 热门回答(23 赞)

为什么选择
java.util.logging有一个根记录器,默认为Level.INFO,并且附加到它的ConsoleHandler也默认为Level.INFO.FINE低于INFO,因此默认情况下不显示精细消息。
解决方案1 ​​
为整个应用程序创建一个记录器,例如从你的软件包名称或useLogger.getGlobal(),并将你自己的ConsoleLogger挂钩到它。然后要求root logger关闭(以避免重复输出更高级别的消息),或者请求你的记录器到not forward logs root。

public static final Logger applog = Logger.getGlobal();
...

// Create and set handler
Handler systemOut = new ConsoleHandler();
systemOut.setLevel( Level.ALL );
applog.addHandler( systemOut );
applog.setLevel( Level.ALL );

// Prevent logs from processed by default Console handler.
applog.setUseParentHandlers( false ); // Solution 1
Logger.getLogger("").setLevel( Level.OFF ); // Solution 2

解决方案2
或者,你可以降低根记录器的栏。

你可以通过代码设置它们:

Logger rootLog = Logger.getLogger("");
rootLog.setLevel( Level.FINE );
rootLog.getHandlers()[0].setLevel( Level.FINE ); // Default console handler

或者使用日志配置文件,如果你是using it

.level = FINE
java.util.logging.ConsoleHandler.level = FINE

通过降低全局级别,你可能会开始看到来自核心库的消息,例如来自某些Swing或JavaFX组件的消息。在这种情况下,你可以在根记录器上设置aFilter以过滤掉不是来自程序的消息。


#3 热门回答(4 赞)

why is my java logging not working
提供了一个jar文件,可以帮助你找出登录不按预期工作的原因。它为你提供了已安装的记录器和处理程序以及设置的级别以及日志记录层次结构中哪个级别的完整转储。


原文链接