简体   繁体   English

动态改变 log4j 日志级别

[英]Dynamically Changing log4j log level

What are the different approaches for changing the log4j log level dynamically, so that I will not have to redeploy the application.动态更改 log4j 日志级别的不同方法是什么,这样我就不必重新部署应用程序。 Will the changes be permanent in those cases?在这些情况下,这些变化会是永久性的吗?

File Watchdog文件看门狗

Log4j is able to watch the log4j.xml file for configuration changes. Log4j 能够查看log4j.xml文件以进行配置更改。 If you change the log4j file, log4j will automatically refresh the log levels according to your changes.如果更改 log4j 文件,log4j 会根据您的更改自动刷新日志级别。 See the documentation of org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long ) for details.有关详细信息org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long请参阅org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long ) 的文档。 The default wait time between checks is 60 seconds.检查之间的默认等待时间为 60 秒。 These changes would be persistent, since you directly change the configuration file on the filesystem.这些更改将是持久的,因为您直接更改文件系统上的配置文件。 All you need to do is to invoke DOMConfigurator.configureAndWatch() once.您需要做的就是调用 DOMConfigurator.configureAndWatch() 一次。

Caution: configureAndWatch method is unsafe for use in J2EE environments due to a Thread leak注意:由于线程泄漏,configureAndWatch 方法在 J2EE 环境中使用是不安全的

JMX JMX

Another way to set the log level (or reconfiguring in general) log4j is by using JMX.设置日志级别(或一般重新配置)log4j 的另一种方法是使用 JMX。 Log4j registers its loggers as JMX MBeans. Log4j 将其记录器注册为 JMX MBean。 Using the application servers MBeanServer consoles (or JDK's jconsole.exe) you can reconfigure each individual loggers.使用应用程序服务器 MBeanServer 控制台(或 JDK 的 jconsole.exe),您可以重新配置每个单独的记录器。 These changes are not persistent and would be reset to the config as set in the configuration file after you restart your application (server).这些更改不是持久的,并且会在您重新启动应用程序(服务器)后重置为配置文件中设置的配置。

Self-Made自制

As described by Aaron, you can set the log level programmatically.正如 Aaron 所述,您可以通过编程方式设置日志级别。 You can implement it in your application in the way you would like it to happen.您可以按照您希望的方式在您的应用程序中实现它。 For example, you could have a GUI where the user or admin changes the log level and then call the setLevel() methods on the logger.例如,您可以有一个 GUI,用户或管理员可以在其中更改日志级别,然后在记录器上调用setLevel()方法。 Whether you persist the settings somewhere or not is up to you.您是否在某处保留设置取决于您。

Changing the log level is simple;更改日志级别很简单; modifying other portions of the configuration will pose a more in depth approach.修改配置的其他部分将提出更深入的方法。

LogManager.getRootLogger().setLevel(Level.DEBUG);

The changes are permanent through the life cyle of the Logger .这些更改在Logger整个生命周期中都是永久性的。 On reinitialization the configuration will be read and used as setting the level at runtime does not persist the level change.在重新初始化时,配置将被读取并用作在运行时设置级别不会持久化级别更改。

UPDATE: If you are using Log4j 2 you should remove the calls to setLevel per the documentation as this can be achieved via implementation classes.更新:如果您使用的是 Log4j 2,您应该根据文档删除对setLevel的调用,因为这可以通过实现类来实现。

Calls to logger.setLevel() or similar methods are not supported in the API. API 不支持对 logger.setLevel() 或类似方法的调用。 Applications should remove these.应用程序应该删除这些。 Equivalent functionality is provided in the Log4j 2 implementation classes but may leave the application susceptible to changes in Log4j 2 internals. Log4j 2 implementation classes 中提供了等效功能,但可能会使 application 容易受到 Log4j 2 内部变化的影响。

Log4j2 can be configured to refresh its configuration by scanning the log4j 2 .xml file (or equivalent) at given intervals. Log4j2 可以配置为通过以给定时间间隔扫描 log4j 2 .xml 文件(或等效文件)来刷新其配置。 Just add the " monitorInterval " parameter to your configuration tag.只需将“ monitorInterval ”参数添加到您的配置标签即可。 See line 2 of the sample log4j 2 .xml file, which tells log4j to to re-scan its configuration if more than 5 seconds have passed since the last log event.请参阅示例 log4j 2 .xml 文件的第 2 行,该文件告诉 log4j 如果自上次日志事件以来已过去 5 秒以上,则重新扫描其配置。

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">

    <Appenders>
        <RollingFile name="MY_TRY_IT"
                     fileName="/var/log/tryIt.log"
                     filePattern="/var/log/tryIt-%i.log.gz">
            <Policies>
                <SizeBasedTriggeringPolicy size="25 MB"/>
            </Policies>
            ...
        </RollingFile>
    </Appenders>


    <Loggers>
        <Root level="error">
            <AppenderRef ref="MY_TRY_IT"/>
        </Root>
    </Loggers>

</Configuration>

There are extra steps to make this work if you are deploying to a tomcat instance, inside an IDE, or when using spring boot.如果您要部署到 tomcat 实例、IDE 内或使用 spring boot,则需要执行额外的步骤来完成这项工作。 That seems somewhat out of scope here and probably merits a separate question.这似乎有点超出了这里的范围,可能值得单独提出一个问题。

For log4j 2 API , you can use对于 log4j 2 API,您可以使用

Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));

With log4j 1.x I find the best way is to use a DOMConfigurator to submit one of a predefined set of XML log configurations (say, one for normal use and one for debugging).对于 log4j 1.x,我发现最好的方法是使用 DOMConfigurator 提交一组预定义的 XML 日志配置之一(例如,一个用于正常使用,另一个用于调试)。

Making use of these can be done with something like this:可以通过以下方式使用这些:

  public static void reconfigurePredefined(String newLoggerConfigName) {
    String name = newLoggerConfigName.toLowerCase();
    if ("default".equals(name)) {
      name = "log4j.xml";
    } else {
      name = "log4j-" + name + ".xml";
    }

    if (Log4jReconfigurator.class.getResource("/" + name) != null) {
      String logConfigPath = Log4jReconfigurator.class.getResource("/" + name).getPath();
      logger.warn("Using log4j configuration: " + logConfigPath);
      try (InputStream defaultIs = Log4jReconfigurator.class.getResourceAsStream("/" + name)) {
        new DOMConfigurator().doConfigure(defaultIs, LogManager.getLoggerRepository());
      } catch (IOException e) {
        logger.error("Failed to reconfigure log4j configuration, could not find file " + logConfigPath + " on the classpath", e);
      } catch (FactoryConfigurationError e) {
        logger.error("Failed to reconfigure log4j configuration, could not load file " + logConfigPath, e);
      }
    } else {
      logger.error("Could not find log4j configuration file " + name + ".xml on classpath");
    }
  }

Just call this with the appropriate config name, and make sure that you put the templates on the classpath.只需使用适当的配置名称调用它,并确保将模板放在类路径上。

This answer won't help you to change the logging level dynamically, you need to restart the service, if you are fine restarting the service, please use the below solution此答案不会帮助您动态更改日志记录级别,您需要重新启动服务,如果您可以重新启动服务,请使用以下解决方案

I did this to Change log4j log level and it worked for me, I have n't referred any document.我这样做是为了更改 log4j 日志级别,它对我有用,我没有引用任何文档。 I used this system property value to set my logfile name.我使用这个系统属性值来设置我的日志文件名。 I used the same technique to set logging level as well, and it worked我也使用相同的技术来设置日志记录级别,并且有效

passed this as JVM parameter (I use Java 1.7)将此作为 JVM 参数传递(我使用 Java 1.7)

Sorry this won't dynamically change the logging level, it requires a restart of the service抱歉,这不会动态更改日志记录级别,它需要重新启动服务

java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.java

in the log4j.properties file, I added this entry在 log4j.properties 文件中,我添加了这个条目

log4j.rootLogger=${logging.level},file,stdout

I tried我试过了

 java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.java
 java -Dlogging.level=INFO-cp xxxxxx.jar  xxxxx.java
 java -Dlogging.level=OFF -cp xxxxxx.jar  xxxxx.java

It all worked.这一切都奏效了。 hope this helps!希望这有帮助!

I have these following dependencies in my pom.xml我的 pom.xml 中有以下依赖项

<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>apache-log4j-extras</artifactId>
    <version>1.2.17</version>
</dependency>

I have used this method with success to reduce the verbosity of the "org.apache.http" logs:我成功地使用了这种方法来减少“org.apache.http”日志的冗长:

ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);

LogManager can be defined using configuration or we can integrate the appropriate xml format into the code and solve this problem. LogManager 可以通过配置来定义,或者我们可以在代码中集成合适的 xml 格式来解决这个问题。

If you would want to change the logging level of all the loggers use the below method.如果您想更改所有记录器的日志记录级别,请使用以下方法。 This will enumerate over all the loggers and change the logging level to given level.这将枚举所有记录器并将日志记录级别更改为给定级别。 Please make sure that you DO NOT have log4j.appender.loggerName.Threshold=DEBUG property set in your log4j.properties file.请确保您没有log4j.properties文件中设置log4j.appender.loggerName.Threshold=DEBUG属性。

public static void changeLogLevel(Level level) {
    Enumeration<?> loggers = LogManager.getCurrentLoggers();
    while(loggers.hasMoreElements()) {
        Logger logger = (Logger) loggers.nextElement();
        logger.setLevel(level);
    }
}

您可以使用以下代码片段

((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM