以编程方式为所有java.util.logging记录器设置级别

时间:2019-02-20 15:01:47

标签: java logging slf4j java.util.logging jul-to-slf4j

我在使用slf4j和log4j2作为底层日志记录框架的应用程序上工作。该应用程序根据应用程序的当前用户提供自定义日志记录筛选器。一些第三方库在内部使用java.util.logging(JUL)。我希望这些日志也提交给基于用户的过滤器。即虽然默认日志级别可能是ERROR,但是我可以将应用程序配置为在特定用户正在使用时登录级别DEBUG

因此,我集成了jul-to-slf4j网桥,以便将JUL日志记录重定向到slf4j。我还创建了一个自定义java.util.logging.Filter as described here,它实现了基于用户的过滤器逻辑。

现在我的问题是,JUL中的默认日志级别似乎是INFO,并且还有一种逻辑,该逻辑首先检查要记录的消息的级别是否小于记录器的级别,在这种情况下消息将立即被拒绝,而不会通过过滤器(在本例中为我的自定义过滤器)。因此,我希望所有JUL Logger(以及第三方库中使用的默认)都具有级别ALL,以便所有JUL log语句都将通过我的过滤器,在此处确定是否记录消息或丢弃它。

我已经尝试将JUL的根记录器设置为ALL,这在SO上的多篇文章中都有介绍,但这似乎并不能解决问题as seen here。看来我必须相应地配置JUL LogManager,并且我想知道是否可以以编程方式进行配置而不引入新的日志文件吗?

1 个答案:

答案 0 :(得分:0)

通过代码,您可以使用以下代码重置所有记录器:

private static void resetLoggersToRoot() {
    Logger root = Logger.getLogger("");
    LogManager lm = LogManager.getLogManager();
    synchronized (lm) {
        Enumeration<String> e = lm.getLoggerNames();
        while (e.hasMoreElements()) {
            Logger l = lm.getLogger(e.nextElement());
            if (l != null && l != root) {
                l.setLevel(root.getLevel());
                l.setFilter(root.getFilter());
                l.setUseParentHandlers(root.getUseParentHandlers());
                for(Handler h : l.getHandlers()) {
                    l.removeHandler(h);
                }
            }
        }
    }
}

但是,存在按需创建记录器的问题。因此,您可能必须调用LogManager.getLogManager().reset();才能从logging.properties文件中删除任何现有配置。