java.util.logging控制台处理程序不会记录低于 INFO 级别的消息

问题描述

以下是我的记录器的代码。记录到文件工作正常,但控制台处理程序不会打印任何低于 Level.INFO 的消息。

this.rxStompService.watch('/topic/demo').subscribe((message: Message) => {
      this.receivedMessages.push(message.body);
    });

我用 public class ServerLogger { /* * Log file size */ final private static int FILE_SIZE = 1024 * 100; /** * Creates and return server logger * * @param dir log files directory * @param consoleEnabled if set to true then logging to console is enabled * @param debugEnabled if set to true then debug level of logging is enabled * * @return sever logger * * @throws SecurityException * @throws IOException */ public static Logger getLogger(final String dir,final boolean consoleEnabled,final boolean debugEnabled) throws SecurityException,IOException { Logger logger = Logger.getLogger(Server.class.getName()); logger.setUseParentHandlers(false); /* * remove all handlers if any */ Handler[] handlers = logger.getHandlers(); if (handlers.length > 0) { for (Handler handler : handlers) logger.removeHandler(handler); } /* * create formatter */ Formatter formatter = new LineFormatter(); /* * if console logging is enabled then add console handler */ if (consoleEnabled) { ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setFormatter(formatter); logger.addHandler(consoleHandler); } /* * add file handler */ String nameTemplate = dir + "\\" + "server-log%g.txt"; FileHandler fileHandler = new FileHandler(nameTemplate,FILE_SIZE,10); fileHandler.setFormatter(formatter); logger.addHandler(fileHandler); Level level = debugEnabled ? Level.FINE : Level.INFO; logger.setLevel(level); return logger; } static private class LineFormatter extends Formatter { @Override public String format(LogRecord record) { return String.format("[%1$tF %1$tT] [%4$-7s] %5$s %n",record.getMillis(),record.getSourceMethodName(),record.getLoggerName(),record.getLevel(),record.getMessage(),record.getThrown()); } }; public static void main(String[] args) throws SecurityException,IOException { //test Logger logger = ServerLogger.getLogger("C:\\logs",true,true); logger.severe("severe"); logger.warning("warning"); logger.info("info"); logger.config("config"); logger.fine("fine"); logger.finer("finer"); logger.finest("finest"); } 替换了 ConsoleHandler 但这没有帮助。 用 StreamHandler 替换 logger.setLevel(level) 也无济于事。使用 logger.setLevel(Level.ALL) 设置处理程序级别不会改变某些内容。 控制台上的消息是:

handler.set(Level level)

你能帮忙吗。

解决方法

总是固定你的记录器,这样它就不会被垃圾收集。这是这样做的:

private static final Logger logger = Logger.getLogger(Server.class.getName());

如果记录器被垃圾收集,您的所有更改都将丢失并回退到 logging.properties。

下一个问题是,如果您以编程方式删除处理程序,您也必须关闭它们。

 if (handlers.length > 0) { //The if is not needed,just the for loop.
        for (Handler handler : handlers) {
            logger.removeHandler(handler);
            handler.close(); //Don't leak resources.
        }
 }

下一个问题是您必须将控制台处理程序级别设置为所有:

ConsoleHandler consoleHandler =  new ConsoleHandler();
consoleHandler.setFormatter(formatter);
consoleHandler.setLevel(Level.ALL);
//consoleHandler.setLevel(debugEnabled ? Level.FINE : Level.INFO); //This would work too.

这允许您的处理程序接受低于 INFO 的日志记录。

虽然使用静态方法来设置日志配置“有效”,但您实际上只想设置一次配置。在运行时更改记录器树很不方便,可能会导致您丢失消息。您应该使用 logger configuration file,a logger class,or a static initializer block 以便配置加载一次且仅一次。

小心使用 StreamHandler + System.err 或 System.out。关闭 StreamHandler 隐式或显式将关闭它正在包装的系统流,这将停止所有输出到控制台。 ConsoleHandler 不会这样做。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...