简体   繁体   English

如何在命令行上设置log4j级别?

[英]How do I set log4j level on the command line?

I want to add some log.debug statements to a class I'm working on, and I'd like to see that in output when running the test. 我想在我正在处理的类中添加一些log.debug语句,并且我希望在运行测试时在输出中看到它。 I'd like to override the log4j properties on the command line, with something like this: 我想在命令行上覆盖log4j属性,如下所示:

-Dlog4j.logger.com.mypackage.Thingie=DEBUG

I do this kind of thing frequently. 我经常这样做。 I am specifically only interested in a way to pass this on the command line. 我特别感兴趣的是在命令行上传递它的方法。 I know how to do it with a config file, and that doesn't suit my workflow. 我知道如何使用配置文件来完成它,这不适合我的工作流程。

As part of your jvm arguments you can set -Dlog4j.configuration=file:"<FILE_PATH>" . 作为jvm参数的一部分,您可以设置-Dlog4j.configuration=file:"<FILE_PATH>" Where FILE_PATH is the path of your log4j.properties file. 其中FILE_PATH是log4j.properties文件的路径。

Please note that as of log4j2 , the new system variable to use is log4j.configurationFile and you put in the actual path to the file (ie without the file: prefix) and it will automatically load the factory based on the extension of the configuration file: 请注意,从log4j2开始 ,要使用的新系统变量是log4j.configurationFile并且您输入了文件的实际路径(即没有file:前缀),它将根据配置文件的扩展名自动加载工厂:

-Dlog4j.configurationFile=/path/to/log4jconfig.{ext}

These answers actually dissuaded me from trying the simplest possible thing! 这些答案实际上阻止了我尝试最简单的事情! Simply specify a threshold for an appender (say, "console") in your log4j.configuration like so: 只需在log4j.configuration指定appender(例如“console”)的阈值,如下所示:

log4j.appender.console.threshold=${my.logging.threshold}

Then, on the command line, include the system property -Dlog4j.info -Dmy.logging.threshold=INFO . 然后,在命令行上,包括系统属性-Dlog4j.info -Dmy.logging.threshold=INFO I assume that any other property can be parameterized in this way, but this is the easiest way to raise or lower the logging level globally. 我假设任何其他属性都可以通过这种方式进行参数化,但这是提高或降低全局日志记录级别的最简单方法。

log4j does not support this directly. log4j不直接支持这个。

As you do not want a configuration file, you most likely use programmatic configuration. 由于您不需要配置文件,因此很可能使用编程配置。 I would suggest that you look into scanning all the system properties, and explicitly program what you want based on this. 我建议您研究扫描所有系统属性,并根据此显式编程您想要的内容。

With Log4j2, this can be achieved using the following utility method added to your code. 使用Log4j2,可以使用添加到代码中的以下实用程序方法来实现。

private static void setLogLevel() {
  if (Boolean.getBoolean("log4j.debug")) {
    Configurator.setLevel(System.getProperty("log4j.logger"), Level.DEBUG);
  }
}

You need these imports 你需要这些进口

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;

Now invoke the setLogLevel method in your main() or whereever appropriate and pass command line params -Dlog4j.logger=com.mypackage.Thingie and -Dlog4j.debug=true . 现在在main()或者适当的时候调用setLogLevel方法并传递命令行params -Dlog4j.logger=com.mypackage.Thingie-Dlog4j.debug=true

Based on Thorbjørn Ravn Andersens suggestion I wrote some code that makes this work 根据ThorbjørnRavnAndersens的建议,我写了一些使这项工作的代码

Add the following early in the main method and it is now possible to set the log level from the comand line. 在main方法的早期添加以下内容,现在可以从命令行设置日志级别。 This have been tested in a project of mine but I'm new to log4j and might have made some mistake. 这已在我的一个项目中测试过,但我是log4j的新手,可能会犯一些错误。 If so please correct me. 如果是这样,请纠正我。

    Logger.getRootLogger().setLevel(Level.WARN);
    HashMap<String,Level> logLevels=new HashMap<String,Level>();
    logLevels.put("ALL",Level.ALL);
    logLevels.put("TRACE",Level.TRACE);
    logLevels.put("DEBUG",Level.DEBUG);
    logLevels.put("INFO",Level.INFO);
    logLevels.put("WARN",Level.WARN);
    logLevels.put("ERROR",Level.ERROR);
    logLevels.put("FATAL",Level.FATAL);
    logLevels.put("OFF",Level.OFF);
    for(String name:System.getProperties().stringPropertyNames()){
        String logger="log4j.logger.";
        if(name.startsWith(logger)){
            String loggerName=name.substring(logger.length());
            String loggerValue=System.getProperty(name);
            if(logLevels.containsKey(loggerValue))
                Logger.getLogger(loggerName).setLevel(logLevels.get(loggerValue));
            else
                Logger.getRootLogger().warn("unknown log4j logg level on comand line: "+loggerValue);
        }
    }

Based on @lijat, here is a simplified implementation. 基于@lijat,这是一个简化的实现。 In my spring-based application I simply load this as a bean. 在我的基于spring的应用程序中,我只是将其作为bean加载。

public static void configureLog4jFromSystemProperties()
{
  final String LOGGER_PREFIX = "log4j.logger.";

  for(String propertyName : System.getProperties().stringPropertyNames())
  {
    if (propertyName.startsWith(LOGGER_PREFIX)) {
      String loggerName = propertyName.substring(LOGGER_PREFIX.length());
      String levelName = System.getProperty(propertyName, "");
      Level level = Level.toLevel(levelName); // defaults to DEBUG
      if (!"".equals(levelName) && !levelName.toUpperCase().equals(level.toString())) {
        logger.error("Skipping unrecognized log4j log level " + levelName + ": -D" + propertyName + "=" + levelName);
        continue;
      }
      logger.info("Setting " + loggerName + " => " + level.toString());
      Logger.getLogger(loggerName).setLevel(level);
    }
  }
}

在我非常标准的设置中,当我作为VM Option(Java中的类之前的命令行或IDE中的VM Option)传入时,我已经看到以下工作:

-Droot.log.level=TRACE

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

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