Перейти к основному содержимому

Предупреждение Log4j: «Для Logger не найдены приложения»

· 4 мин. чтения

1. Обзор

В этом руководстве мы покажем, как исправить предупреждение «log4j: WARN Не удалось найти приложения для регистратора» . `` Мы объясним, что такое аппендер и как его определить. Кроме того, мы покажем, как решить предупреждение различными способами.

2. Определение добавления

Давайте сначала объясним, что такое аппендер. Log4j позволяет нам помещать журналы в несколько мест назначения. Каждый пункт назначения, в который он выводит вывод, называется appender . У нас есть приложения для консоли, файлов, компонентов JMS, GUI и других.

В log4j не определено приложение по умолчанию. Кроме того, регистратор может иметь несколько приложений для добавления , и в этом случае регистратор печатает вывод во все из них.

3. Объяснение предупреждающего сообщения

Теперь, когда мы знаем, что такое аппендер, давайте разберемся в рассматриваемой проблеме. В предупреждающем сообщении говорится, что для регистратора не удалось найти приложение.

Давайте создадим класс NoAppenderExample для воспроизведения предупреждения:

public class NoAppenderExample {
private final static Logger logger = Logger.getLogger(NoAppenderExample.class);

public static void main(String[] args) {
logger.info("Info log message");
}
}

Мы запускаем наш класс без какой-либо конфигурации log4j. После этого мы можем увидеть предупреждение вместе с более подробной информацией в выводе консоли:

log4j:WARN No appenders could be found for logger (com.foreach.log4j.NoAppenderExample).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

4. Решение проблемы с конфигурацией

Log4j по умолчанию ищет в ресурсах приложения файл конфигурации , который может быть в формате свойств XML или Java. Давайте теперь определим файл log4j.xml в каталоге ресурсов:

<log4j:configuration debug="false">
<!--Console appender -->
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %p %m%n"/>
</layout>
</appender>

<root>
<level value="DEBUG"/>
<appender-ref ref="stdout"/>
</root>
</log4j:configuration>

Мы определили корневой регистратор, который находится на вершине иерархии регистраторов. Все регистраторы приложений являются его дочерними элементами и переопределяют его конфигурацию. Мы определили корневой логгер с одним аппендером, который выводит логи в консоль.

Давайте снова запустим класс NoAppenderExample и проверим вывод консоли. В итоге в логе наш оператор:

2021-05-23 12:59:10 INFO Info log message

4.1. Аддитивность аппендера

Приложение не обязательно должно быть определено для каждого регистратора. Запрос на регистрацию для данного регистратора отправляет журналы в приложения, определенные для него, и во все приложения, указанные для регистраторов выше в иерархии. Покажем это на примере.

Если регистратор A определил приложение для консоли, а регистратор B является дочерним по отношению к A , регистратор B также выводит свои журналы на консоль. Регистратор наследует приложения от своего предка только в том случае, если флаги аддитивности в промежуточных предках установлены в значение true . Если для флага аддитивности установлено значение false , аппендеры от логгеров выше в иерархии не наследуются.

Чтобы доказать, что логгер наследует аппендеры от предков, давайте добавим логгер для NoAppenderExample в наш файл log4j.xml :

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="false">
...
<logger name="com.foreach.log4j.NoAppenderExample" />
...
</log4j:configuration>

Давайте снова запустим класс NoAppenderExample . На этот раз оператор журнала появится в консоли. Хотя у логгера NoAppenderExample нет явно определенного аппендера, он наследует аппендер от корневого логгера .

5. Файл конфигурации не находится в пути к классам

Давайте теперь рассмотрим случай, когда мы хотим определить файл конфигурации вне пути к классам приложения. У нас есть два варианта:

  • Укажите путь к файлу с параметром командной строки java : -Dlog4j.configuration=<путь к файлу конфигурации log4j>
  • Определите путь в коде: PropertyConfigurator.configure(“<путь к файлу свойств log4j>”);

В следующем разделе мы увидим, как добиться этого в нашем Java-коде.

6. Решение проблемы в коде

Допустим, нам не нужен файл конфигурации. Удалим файл log4.xml и изменим основной метод:

public class NoAppenderExample {
private final static Logger logger = Logger.getLogger(NoAppenderExample.class);

public static void main(String[] args) {
BasicConfigurator.configure();
logger.info("Info log message");
}
}

Мы вызываем статический метод configure из класса BasicConfigurator . Он добавляет ConsoleAppender в корневой регистратор. Давайте посмотрим на исходный код метода configure :

public static void configure() {
Logger root = Logger.getRootLogger();
root.addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));
}

Поскольку корневой регистратор в log4j существует всегда, мы можем программно добавить к нему приложение консоли.

7. Заключение

На этом мы завершаем это краткое руководство о том, как устранить предупреждение log4j об отсутствующем приложении. Мы объяснили, что такое приложение и как решить проблему с предупреждением с помощью файла конфигурации. Затем мы объяснили, как работает аддитивность добавления. Наконец, мы показали, как решить предупреждение в коде.

Как всегда, исходный код примера доступен на GitHub .