【发布时间】:2010-12-11 06:06:23
【问题描述】:
我有一个问题,我想在运行时更改 log4j 的日志记录级别,我用 log4j.properties 文件尝试了很多东西,我还尝试编写一个代码,在特定时间后再次读取属性文件并再次配置记录器。
但问题是,我想将一个 API 调用的日志记录级别更改为 DEBUG,然后当该调用完成时,记录器应该再次更改为以前的值..
请帮忙..
【问题讨论】:
我有一个问题,我想在运行时更改 log4j 的日志记录级别,我用 log4j.properties 文件尝试了很多东西,我还尝试编写一个代码,在特定时间后再次读取属性文件并再次配置记录器。
但问题是,我想将一个 API 调用的日志记录级别更改为 DEBUG,然后当该调用完成时,记录器应该再次更改为以前的值..
请帮忙..
【问题讨论】:
使用所需的Level 调用Logger.setLevel 方法可以在运行时改变Logger 的输出级别。
以下是一个演示其用法的示例:
Logger logger = Logger.getLogger("myLogger");
logger.addAppender(new ConsoleAppender(new SimpleLayout()));
System.out.println("*** The current level will be INFO");
logger.setLevel(Level.INFO);
logger.warn("Only INFO and higher will appear");
logger.info("Only INFO and higher will appear");
logger.debug("Only INFO and higher will appear");
System.out.println("*** Changing level to DEBUG");
// remember the previous level
Level previousLevel = logger.getLevel();
logger.setLevel(Level.DEBUG);
logger.warn("DEBUG and higher will appear");
logger.info("DEBUG and higher will appear");
logger.debug("DEBUG and higher will appear");
System.out.println("*** Changing level back to previous level");
// revert to previous level
logger.setLevel(previousLevel);
logger.warn("Only INFO and higher will appear");
logger.info("Only INFO and higher will appear");
logger.debug("Only INFO and higher will appear");
以上输出:
*** The current level will be INFO
WARN - Only INFO and higher will appear
INFO - Only INFO and higher will appear
*** Changing level to DEBUG
WARN - DEBUG and higher will appear
INFO - DEBUG and higher will appear
DEBUG - DEBUG and higher will appear
*** Changing level back to previous level
WARN - Only INFO and higher will appear
INFO - Only INFO and higher will appear
上面演示了如何更改一个名为myLogger的Logger的级别,但是如果要更改当前存储库中所有记录器的级别,则根记录器上的setLevel方法 应调用Logger.getRootLogger 获得的所有子记录器的级别。
【讨论】:
如@coobird 所述,可以通过调用setLevel 来更改记录器的日志级别。但是,有一个问题!
当您调用getLogger(name) 时,日志库将尽可能返回一个现有的Logger 对象。如果两个或多个线程请求同名的记录器,它们将获得相同的对象。如果其中一个线程调用setLevel,这将更改所有其他线程的记录器级别。这可能会导致意外行为。
如果你真的需要做这种事情,更好的方法是为你想在不同级别记录的情况创建一个不同名称的记录器。
但是,我根本不相信调用setLevel 的应用程序是否明智。 setLevel 方法是关于过滤日志消息的,您不应该将日志过滤的控制权从用户/部署者手中夺走。
【讨论】:
如果服务器有“控制器”线程,我认为调用setLevel 是有意义的。这样,您可以在运行时动态更改日志记录级别以调试问题,并在完成后将其更改回来。
但我不知道从单独的线程调用它时会发生什么。
【讨论】:
setLevel 方法仅适用于 java.util.logging.Logger,不适用于 org.apache.logging.log4j.Logger
这就是我们在 apache log4j 中设置日志级别的方式
org.apache.logging.log4j.core.LoggerContext
ctx = (LoggerContext) LogManager.getContext(false);
org.apache.logging.log4j.core.config.Configuration
conf = ctx.getConfiguration();
conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(Level.DEBUG);
ctx.updateLoggers(conf);
【讨论】:
如果您使用的是 Spring Boot (1.5+),you can use logger endpoint to POST desired logging level。
【讨论】: