简体   繁体   English

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

[英]Java JUL logging propagation beside level restrictions

I'm trying to use JUL logger with a customized configuration, so that special handlers take care for different logging levels. 我正在尝试使用具有自定义配置的JUL记录器,以便特殊处理程序照顾不同的记录级别。 I want severe problems (such as failures when connecting to database or reading the properties) logged into a local file, warnings should be written into the database by my custom handler, everything else is supposed to be a debugging output and should be printed to console if debugging is enabled. 我希望将严重问题(例如连接数据库或读取属性时出现的故障)登录到本地文件中,警告应由我的自定义处理程序写入数据库,其他所有内容都应作为调试输出,并应打印到控制台如果启用了调试。 So here are my logger properties: 所以这是我的记录器属性:

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

Until now the database handler doesn't do anything but a sysout for testing: 直到现在,数据库处理程序只对系统进行了测试:

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

}

And finally here is my test code: 最后是我的测试代码:

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

What i would expect is that the first message gets printed out to the console, passsed to "logger.warning" and then discarded, as it's below the logging level. 我期望的是第一条消息被打印到控制台,传递给“ logger.warning”,然后被丢弃,因为它低于日志记录级别。 The same for the second message in "logger", so the only one printed to the file is the third message. “记录器”中的第二条消息是相同的,因此打印到文件的唯一一条消息是第三条消息。 However the console output looks like this: 但是,控制台输出如下所示:

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

Also all three messages get printed to the file. 同样,所有三个消息都将打印到文件中。 I've ran out of ideas to explain this behaviour, can anybody help please? 我已经没有足够的想法来解释这种行为,有人可以帮忙吗?

PS log4j is NOT an option, otherwise I would have used it PS log4j不是一个选项,否则我会用它

Regards, Sverre 问候,斯维尔

What i would expect is that the first message gets printed out to the console, passsed to "logger.warning" and then discarded, as it's below the logging level. 我期望的是第一条消息被打印到控制台,传递给“ logger.warning”,然后被丢弃,因为它低于日志记录级别。

From the Java Logging Overview : Java日志记录概述

By default a Logger will log any output messages to its parent's handlers , and so on recursively up the tree. 默认情况下,Logger会将所有输出消息记录到其父级的 处理程序中 ,依此类推。

When log records travel up the tree they are not passed to logger.log . 当日志记录沿树上行时,它们不会传递到logger.log Therefore, the level of the parent logger has no effect when the child logger is publishing to the parent handlers . 因此,当子记录器发布到父处理程序时,父记录器的级别无效。

I want severe problems (such as failures when connecting to database or reading the properties) logged into a local file, warnings should be written into the database by my custom handler, everything else is supposed to be a debugging output and should be printed to console if debugging is enabled. 我希望将严重问题(例如连接数据库或读取属性时出现的故障)登录到本地文件中,警告应由我的自定义处理程序写入数据库,其他所有内容都应作为调试输出,并应打印到控制台如果启用了调试。

First should set the level of FileHandler to SEVERE, set the DB handler to WARNING, and the ConsoleHandler to all. 首先应将FileHandler的级别设置为SEVERE,将DB处理程序的级别设置为WARNING,将ConsoleHandler的级别设置为all。 Then you have to install a custom filter on the ConsoleHandler and DB handler to block out the levels that are handled elsewhere: 然后,您必须在ConsoleHandler和DB处理程序上安装自定义过滤器 ,以阻止在其他位置处理的级别:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM