Як встановити рівень log4j у командному рядку?


78

Я хочу додати деякі оператори log.debug до класу, над яким я працюю, і я хотів би бачити це у вихідних даних під час запуску тесту. Я хотів би замінити властивості log4j у командному рядку приблизно таким чином:

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

Я часто роблю подібні речі. Мене конкретно цікавить лише спосіб передачі цього в командному рядку. Я знаю, як це зробити за допомогою конфігураційного файлу, і це не відповідає моєму робочому процесу.

Відповіді:


16

log4j не підтримує це безпосередньо.

Оскільки вам не потрібен файл конфігурації, ви, швидше за все, використовуєте програмну конфігурацію. Я б запропонував вам вивчити всі властивості системи та чітко запрограмувати те, що ви хочете, виходячи з цього.


49

Як частину аргументів jvm ви можете встановити -Dlog4j.configuration=file:"<FILE_PATH>". Де FILE_PATH - шлях до вашого файлу log4j.properties.

Зверніть увагу, що починаючи з log4j2 , використовується нова системна змінна, log4j.configurationFileі ви вводите фактичний шлях до файлу (тобто без file:префікса), і він автоматично завантажить завод на основі розширення файлу конфігурації:

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

3
Файл FILE_PATH фактично шукається в CLASSPATH, включаючи файли jar.
Робін Грін

12
Вам потрібно поставити "файл:" перед шляхом, якщо це файл на диску. Іншими словами ... -Dlog4j.configuration = файл: <шлях_до_файлу> stackoverflow.com/questions/778933 / ...
crowmagnumb

2
Це працює так, як рекламується; однак я намагаюся замінити налаштування файлу властивостей у банку, і останній, здається, встановлюється після. Будь-яка порада?
John Lehmann,

34

Ці відповіді насправді переконали мене спробувати якнайпростішу річ! Просто вкажіть поріг для додатка (скажімо, "консоль") у вашому log4j.configurationподібному:

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

Потім у командному рядку включіть системну властивість -Dlog4j.info -Dmy.logging.threshold=INFO. Я припускаю, що будь-яке інше властивість можна параметризувати таким чином, але це найпростіший спосіб підвищити або знизити рівень реєстрації в усьому світі.


Я майже впевнений, що це найпростіше рішення вихідного питання!
Дрой

@Droj Можливо, так, але OP хотів зробити все це в коді. Чакун - подагра сина.
AbuNassar

У моєму випадку я теж хотів встановити його з командного рядка, але я вже мав конфігурацію. Я просто не хотів редагувати файл, щоб отримати різні журнали. Я не читав його як "все в коді", але, можливо, так ...
Дрой

1
Тільки поліпшення другорядний: YAMLLoggers:\n Logger:\n name: stuff \n level: ${sys:my.log.level:-INFO}
Ich

Мені подобається вищезазначений YAML, але IIRC Spring не буде робити змінну інтерполяцію на YAML.
AbuNassar

17

За допомогою Log4j2 цього можна досягти за допомогою наведеного нижче коду.

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

Вам потрібен цей імпорт

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

Тепер викликайте setLogLevelметод у вашому main () або де завгодно і передайте параметри командного рядка -Dlog4j.logger=com.mypackage.Thingieта -Dlog4j.debug=true.


2
Це має бути прийнятою відповіддю тепер, коли пакети оновлюються. Дякую за оновлену відповідь. Я глибоко ціную оновлені відповіді, коли справа стосується давніх питань. Ти врятував мене трохи розчарування.
Даніель Б. Чепмен

6

На основі пропозиції Торбьорна Равна Андерсенса я написав код, який робить цю роботу

Додайте наступне на початку основного методу, і тепер можна встановити рівень журналу з рядка команди. Це було перевірено у моєму проекті, але я новачок у log4j і, можливо, зробив якусь помилку. Якщо так, будь ласка, виправте мене.

    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);
        }
    }

5

У моїй досить стандартній установці я добре бачив наступну роботу, коли передавався як VM Option (командний рядок перед класом у Java або VM Option в IDE):

-Droot.log.level=TRACE

2

На основі @lijat, ось спрощена реалізація. У моїй весняній програмі я просто завантажую це як боб.

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);
    }
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.