Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么不显示Level.FINE日志消息?_Java_Logging_Java.util.logging - Fatal编程技术网

Java 为什么不显示Level.FINE日志消息?

Java 为什么不显示Level.FINE日志消息?,java,logging,java.util.logging,Java,Logging,Java.util.logging,国家: 按降序排列的级别为: 严重(最高值) 警告 INFO CONFIG FINE FINER FINEST(最低值) 来源 问题陈述 我的示例将级别设置为更精细,因此我希望每个循环看到2条消息。相反,我看到每个循环都有一条消息(缺少级别。FINE消息) 问题: 要查看FINE(,FINER或FINEST)输出,需要更改哪些内容 更新(解决方案) 多亏了,这个版本符合我的期望。它显示3条INFO消息和3条FINE消息 import java.util.logging.*; class

国家:


按降序排列的级别为:

  • 严重
    (最高值)
  • 警告
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST
    (最低值)

来源 问题陈述 我的示例将
级别
设置为
更精细
,因此我希望每个循环看到2条消息。相反,我看到每个循环都有一条消息(缺少
级别。FINE
消息)

问题: 要查看
FINE
(,
FINER
FINEST
)输出,需要更改哪些内容

更新(解决方案) 多亏了,这个版本符合我的期望。它显示3条
INFO
消息和3条
FINE
消息

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));
        }
    }
}
import java.util.logging.*;
类LoggingLevelsBlunder{
公共静态void main(字符串[]args){
Logger=Logger.getAnonymousLogger();
//将此级别记录到日志中
logger.setLevel(Level.FINER);
ConsoleHandler handler=新的ConsoleHandler();
//发布此级别
handler.setLevel(Level.FINER);
addHandler(handler);
System.out.println(“日志记录级别为:“+logger.getLevel());

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

您可能正在使用一个(我无法推断您的输出是System.err还是一个文件,但我假设它是前者),它默认为发布
level.INFO
级别的日志记录。您必须配置此处理程序,才能发布
level.FINER
或更高级别的日志记录,以获得所需的结果

为了理解底层设计,我建议阅读本指南。本指南涵盖了记录器和处理程序概念之间的区别

编辑处理程序级别

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);

提供一个jar文件,该文件将帮助您了解为什么您的登录无法按预期工作。
它为您提供安装了哪些记录器和处理程序、设置了哪些级别以及日志层次结构中的哪个级别的完整转储信息。

原因

java.util.logging有一个默认为
Level.INFO
的根记录器,以及一个连接到它的控制台句柄,该控制台句柄也默认为
Level.INFO
FINE
低于
INFO
,因此默认情况下不显示FINE消息


解决方案1

为您的整个应用程序创建一个记录器,例如,根据您的软件包名称或用途,并将您自己的ConsoleLogger挂接到该记录器上。 然后要求根日志记录器关闭(以避免重复输出更高级别的消息),或者要求日志记录器关闭根日志记录器

公共静态最终记录器applog=Logger.getGlobal(); ... //创建并设置处理程序 Handler systemOut=新控制台Handler(); systemOut.setLevel(Level.ALL); addHandler(systemOut); applog.setLevel(Level.ALL); //阻止默认控制台处理程序处理日志。 setUseParentHandlers(false);//解决方案1 Logger.getLogger(“”.setLevel(Level.OFF);//解决方案2

解决方案2

或者,您可以降低根记录器的栏

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

Logger rootLog=Logger.getLogger(“”);
rootLog.setLevel(Level.FINE);
rootLog.getHandlers()[0].setLevel(Level.FINE);//默认控制台处理程序
或使用日志记录配置文件,如果您是:

.level=FINE
java.util.logging.ConsoleHandler.level=FINE
通过降低全局级别,您可能开始看到来自核心库的消息,例如来自某些Swing或JavaFX组件的消息。
在这种情况下,您可以在根记录器上设置一个,以过滤掉不来自您程序的消息。

我发现了实际的问题,但在任何回答中都没有提到:我的一些单元测试导致在同一测试套件中多次运行日志初始化代码,扰乱了后续测试的日志记录。

尝试了其他变体s、 这可能是适当的

    Logger logger = Logger.getLogger(MyClass.class.getName());        
    Level level = Level.ALL;
    for(Handler h : java.util.logging.Logger.getLogger("").getHandlers())    
        h.setLevel(level);
    logger.setLevel(level);
// this must be shown
    logger.fine("fine");
    logger.info("info");
为什么

正如@Sheepy所提到的,它不起作用的原因是
java.util.logging.Logger
有一个默认为
Level.INFO
的根记录器,并且附加到该根记录器的
ConsoleHandler
也默认为
Level.INFO
。因此,为了查看
FINE
(,
FINER
FINEST
)输出,您需要将根记录器及其
控制台句柄的默认值设置为
级别。FINE
如下所示:

Logger.getLogger("").setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);

您的更新问题(解决方案)

正如@mins所提到的,您将在控制台上为
INFO
和更高版本打印两次消息:首先由匿名记录器打印,然后由其父级打印,根记录器的
ConsoleHandler
默认设置为
INFO
。要禁用根记录器,您需要添加以下代码行:
logger.setUseParEnhandlers(假);

还有其他方法可以防止默认控制台句柄处理日志
    Logger logger = Logger.getLogger(MyClass.class.getName());        
    Level level = Level.ALL;
    for(Handler h : java.util.logging.Logger.getLogger("").getHandlers())    
        h.setLevel(level);
    logger.setLevel(level);
// this must be shown
    logger.fine("fine");
    logger.info("info");
Logger.getLogger("").setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel( Level.OFF );
# Logging
handlers = java.util.logging.ConsoleHandler
.level = ALL

# Console Logging
java.util.logging.ConsoleHandler.level = ALL
public static java.net.URL retrieveURLOfJarResource(String resourceName) {
   return Thread.currentThread().getContextClassLoader().getResource(resourceName);
}

public synchronized void initializeLogger() {
   try (InputStream is = retrieveURLOfJarResource("logging.properties").openStream()) {
      LogManager.getLogManager().readConfiguration(is);
   } catch (IOException e) {
      // ...
   }
}