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 .