更改Logger实例的全局设置

时间:2011-06-10 14:19:11

标签: java logging

我正在使用java.util.logging.Logger作为我的应用程序的日志记录引擎。每个类使用它自己的记录器,即每个类都有:

private final Logger logger = Logger.getLogger(this.getClass().getName());

我想为所有类设置日志记录级别,并且能够更改它(即,将设置放在一个位置)。有没有办法做到这一点,除了使用全局Level变量并手动设置每个记录器?

5 个答案:

答案 0 :(得分:64)

一种简单的方法是使用日志属性文件,包括此VM参数:

-Djava.util.logging.config.file="logging.properties" 

其中“logging.properties”是包含日志记录配置的文件的路径。对于相对路径,进程的工作目录很重要。

在该文件中,包含如下所示的行:

.level= INFO

这将设置全局级别,可以为特定处理程序和记录器覆盖该级别。例如,可以像这样覆盖特定记录器的级别:

 com.xyz.foo.level = SEVERE

您可以从 jre6 \ lib \ logging.properties 获取日志属性文件的模板。

答案 1 :(得分:32)

作为Andy answered,在大多数情况下,您应该使用属性文件和VM参数,因此它独立于您的代码。

但是如果你想出于某种原因以编程方式进行(我自己在一个案例中有充分的理由)你也可以像这样访问处理程序:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setLevel(Level.INFO);
for (Handler h : rootLogger.getHandlers()) {
    h.setLevel(Level.INFO);
}

编辑我将setLevel添加到根记录器中,因为searchengine27在他的answer中指出。

处理程序是您通过属性或以编程方式设置的文件或控制台处理程序。

或者像这样更改过滤器:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setFilter(new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
            return "something".equals(record.getLoggerName());
    }
});

答案 2 :(得分:22)

因此,我并不完全喜欢这里的所有答案,所以我要进入。

配置文件使用

您在此处看到很多答案,告诉您使用配置文件,因为这是最佳做法。我想更好地解释如何以编程方式进行此操作,但在此之前,我想说我能看到它们的来源,并且在客观的情绪中,我会稍微启发一下(特别是因为没有人说<强>为什么它的不良做法)。我实际上想在一个单独的StackOverflow答案中分享有人所说的,这与以编程方式设置记录器级别有关(Why are the Level.FINE logging messages not showing?):

  

不推荐这样做,因为它会导致覆盖全局配置。在整个代码库中使用它将导致可能无法管理的记录器配置。

就此而言,我认为安迪·托马斯有一个很好的答案,与非编程无关。

以编程方式设置级别

话虽这么说,我想进一步详细说明以编程方式进行,因为我认为它有其用途。

想象一下,您正在使用命令行界面编写内容,并且可以选择指定执行的详细程度,甚至可以指定执行的详细程度(如在动态日志文件中)。我可能会弄错,但您可能不希望在.conf文件中静态地执行此操作。特别是如果你不想让你的用户群负责在配置文件中设置这些东西(无论出于何种原因)。然而,这是以牺牲上述报价为代价的。下面是一个示例,说明如何以编程方式执行此操作,将所有现有处理程序保持在已有的级别,并且只有FileHandler采用新级别:

public static void setDebugLevel(Level newLvl) {
    Logger rootLogger = LogManager.getLogManager().getLogger("");
    Handler[] handlers = rootLogger.getHandlers();
    rootLogger.setLevel(newLvl);
    for (Handler h : handlers) {
        if(h instanceof FileHandler)
            h.setLevel(newLvl);
    }
}

我想扩大这一点,特别是因为一个原因而接受的答案。以编程方式执行此操作时,您只需确保为记录器设置处理程序的级别。它的工作方式是,它会检查请求对于记录器是否太低,如果是,它将丢弃它。然后处理程序具有相同的检查,因此您需要确保记录器和处理程序都设置为您想要的级别。

答案 3 :(得分:3)

morja's answer的单行Java 8方法:

Arrays.stream(LogManager.getLogManager().getLogger("").getHandlers()).forEach(h -> h.setLevel(Level.INFO));

答案 4 :(得分:0)

JUL(java.util.logging)是jvm中的Java默认记录器。

Java Logging Technology--see Overview

因此您可能会发现C:\Program Files\Java\jre1.8.0_221\lib\logging.properties中已经存在一个默认配置文件

我建议您在项目下创建一个新的配置文件以覆盖默认设置,请执行以下操作:

配置文件名logging.properties,所有日志级别均可在Class Level

中找到
handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format= [%1$tF %1$tT] [%4$-7s] %5$s %n

# your specific logger level
com.xyz.foo.level = SEVERE

然后添加jvm选项以启用配置

java -Djava.util.logging.config.file="logging.properties" -Duser.country=CN -Duser.language=en

user.countryuser.language可能会影响日志消息的本地化