Java 我们可以在运行时更改 log4j 的日志记录级别吗

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4415467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:13:26  来源:igfitidea点击:

can we change the logging level of log4j at runtime

javalogginglog4j

提问by M.J.

i have an issue, i want to change the logging level of log4j at runtime, i have tried many things with log4j.properties file, i have also tried to written a code which after particular time again reads the properties file and again configure the logger.

我有一个问题,我想在运行时更改 log4j 的日志记录级别,我用 log4j.properties 文件尝试了很多东西,我还尝试编写了一个代码,在特定时间后再次读取属性文件并再次配置记录器.

but the problem is, i want to change the logging level to DEBUG for one API call, and then when that call is completed, the logger should again change to the previous value..

但问题是,我想将一个 API 调用的日志记录级别更改为 DEBUG,然后当该调用完成时,记录器应该再次更改为以前的值。

please help..

请帮忙..

采纳答案by coobird

Calling the Logger.setLevelmethod with the desired Levelcan alter a Logger's output level at runtime.

Logger.setLevel使用所需的方法调用该方法Level可以Logger在运行时改变 a的输出级别。

The following is an example which demonstrates its usage:

以下是演示其用法的示例:

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 above outputs:

以上输出:

*** 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

The above demonstrates how to change the level of one Loggernamed myLogger, but if the levels of all the loggers in the current repository should be changed, then the setLevelmethod on the root loggerobtained by Logger.getRootLoggershould be called to change the levels on all the child loggers.

上面演示了如何更改Loggernamed的级别myLogger,但是如果要更改当前存储库中所有记录器的级别,则应调用通过获取setLevel根记录器上的方法Logger.getRootLogger来更改所有子记录器的级别。

回答by Stephen C

The log level of a logger can be changed by calling setLevelas described by @coobird. However, there is a catch!

记录器的日志级别可以通过调用setLevel@coobird 的描述来更改。然而,有一个问题!

When you call getLogger(name), the logging library will return you an existing Loggerobject if possible. If two or more threads request a logger with the same name, they will get the same object. If one of the threads calls setLevel, this will change the logger level for all of the others. That can lead to unexpected behavior.

当您调用 时getLogger(name)Logger如果可能,日志库将返回一个现有对象。如果两个或多个线程请求同名的记录器,它们将获得相同的对象。如果其中一个线程调用setLevel,这将更改所有其他线程的记录器级别。这可能会导致意外行为。

If you really need to do this kind of thing, a better approach would be to create a logger with a different name for the case where you want to logging at a different level.

如果你真的需要做这种事情,更好的方法是为你想要在不同级别进行日志记录的情况创建一个具有不同名称的记录器。

However, I'm not convinced of the wisdom of the application calling setLevelat all. The setLevelmethod is about filtering the log messages, and you should not be wresting control of logging filtering away from the user / deployer.

但是,我根本不相信应用程序调用的智慧setLevel。该setLevel方法是关于过滤日志消息,您不应该从用户/部署者手中夺取对日志过滤的控制权。

回答by Prasad

I think it makes sense to call setLevelif a server has a "Controller" thread. That way, you can dynamically change logging level at runtime to debug an issue, and change it back when you are done.

我认为调用setLevel服务器是否有“控制器”线程是有意义的。这样,您可以在运行时动态更改日志记录级别以调试问题,并在完成后将其更改回来。

But I don't know what happens when it is called from a separate thread.

但是我不知道从单独的线程调用它时会发生什么。

回答by Nisar Adappadathil

setLevel method is there only for java.util.logging.Logger and not for org.apache.logging.log4j.Logger

setLevel 方法仅适用于 java.util.logging.Logger 而不适用于 org.apache.logging.log4j.Logger

This is how we set log level in apache log4j

这就是我们在 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);

回答by luboskrnac

If you are using Spring Boot (1.5+), you can use logger endpoint to POST desired logging level.

如果您使用的是 Spring Boot (1.5+),您可以使用 logger 端点来 POST 所需的日志级别