【问题标题】:Set Level for all java.util.logging Loggers programmatically以编程方式为所有 java.util.logging 记录器设置级别
【发布时间】:2019-02-20 15:01:46
【问题描述】:

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

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

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

我已尝试将 JULs 根记录器及其处理程序级别设置为 ALL,正如在 SO 上的多个帖子中所描述的那样,但这似乎并没有达到目的 as seen here。看来我必须相应地配置 JUL LogManager,我想知道是否可以在不引入新日志文件的情况下以编程方式进行配置?

【问题讨论】:

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


    【解决方案1】:

    从代码中,您可以使用如下代码重置所有记录器:

    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 文件中删除任何现有配置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      • 2014-02-17
      • 2019-05-30
      • 2010-10-17
      • 2012-02-16
      • 1970-01-01
      相关资源
      最近更新 更多