Java JUL日志传播除了级别限制之外

时间:2015-07-03 06:20:53

标签: java logging

我正在尝试使用自定义配置的JUL记录器,以便特殊处理程序可以处理不同的日志记录级别。我想要记录到本地文件中的严重问题(例如连接数据库时失败或读取属性),警告应该由我的自定义处理程序写入数据库,其他一切应该是一个调试输出,应该打印到控制台如果启用了调试。所以这是我的记录器属性:

logger.level = SEVERE
logger.handlers = java.util.logging.FileHandler

logger.warning.level = WARNING
logger.warning.handlers = controller.database.DatabaseHandler

logger.warning.severe.level = ALL
logger.warning.severe.handlers = java.util.logging.ConsoleHandler

java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.append = false
java.util.logging.FileHandler.pattern = %h/app.log

controller.database.DatabaseHandler.level = WARNING

java.util.logging.ConsoleHandler.filter = controller.properties.DebugFilter
java.util.logging.ConsoleHandler.level = ALL

到目前为止,数据库处理程序除了用于测试的sysout外没有做任何事情:

@Override
public void publish(LogRecord arg0) {
    System.out.println("DatabaseHandler here! - Level="  + arg0.getLevel() + " - From=" + arg0.getLoggerName());

}

最后这是我的测试代码:

LogManager.getLogManager().readConfiguration(new FileInputStream("logProps.properties"));
Logger logger = Logger.getLogger("logger.warning.severe");
logger.log(Level.FINE, "A fine message", new Object());
logger.log(Level.WARNING, "A warning message", new Object());
logger.log(Level.SEVERE, "A severe message", new Object());

我所期望的是第一条消息被打印到控制台,传递给“logger.warning”然后被丢弃,因为它低于日志记录级别。 “logger”中的第二条消息也是如此,因此打印到文件的唯一消息是第三条消息。但是控制台输出如下所示:

DatabaseHandler here! - Level=FINE - From=logger.warning.severe
03.07.2015 07:54:55 controller.LoggerTest main
FEIN: A fine message
03.07.2015 07:54:55 controller.LoggerTest main
WARNUNG: A warning message
DatabaseHandler here! - Level=WARNING - From=logger.warning.severe
03.07.2015 07:54:55 controller.LoggerTest main
SCHWERWIEGEND: A severe message
DatabaseHandler here! - Level=SEVERE - From=logger.warning.severe

此外,所有三条消息都会打印到文件中。 我已经没有想法来解释这种行为了,有人可以帮忙吗?

P.S。 log4j不是一个选项,否则我会用它

此致 斯维尔

1 个答案:

答案 0 :(得分:1)

  

我所期望的是第一条消息被打印到控制台,传递给“logger.warning”然后被丢弃,因为它低于记录级别。

来自Java Logging Overview

  

默认情况下,Logger会将任何输出消息记录到其parent's handlers,依此向上递送到树上。

当日志记录向上移动时,它们 传递给logger.log。因此,当子记录器发布到parent handlers时,父记录器的级别无效。

  

我想要记录到本地文件中的严重问题(例如连接到数据库时失败或读取属性),警告应该由我的自定义处理程序写入数据库,其他一切应该是调试输出,应该是如果启用了调试,则打印到控制台。

首先应将FileHandler的级别设置为SEVERE,将数据库处理程序设置为WARNING,将ConsoleHandler设置为all。然后,您必须在ConsoleHandler和DB处理程序上安装自定义filter以阻止在其他地方处理的级别:

    public class LessThanLevelFilter implements Filter {

        private final int lvl;

        public LessThanLevelFilter() {
            String p = getClass().getName();
            String v = LogManager.getLogManager().getProperty(p + ".level");
            if (v != null) {
                lvl = Level.parse(v).intValue();
            } else {
                lvl = Level.WARNING.intValue();
            }
        }

        public LessThanLevelFilter(Level l) {
            lvl = l.intValue();
        }

        @Override
        public boolean isLoggable(LogRecord record) {
            return record.getLevel().intValue() < lvl;
        }
    }