Як встановити рівень 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.