我正在尝试使用自定义配置的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不是一个选项,否则我会用它
此致 斯维尔
答案 0 :(得分:1)
我所期望的是第一条消息被打印到控制台,传递给“logger.warning”然后被丢弃,因为它低于记录级别。
当日志记录向上移动时,它们 传递给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;
}
}