Log4j 警告:“無法為 Logger 找到 Appender”

1. 概述

在本教程中,我們將展示如何修復警告, “log4j: WARN 找不到記錄器的附加程序” 。 我們將解釋 appender 是什麼以及如何定義它。此外,我們將展示如何以不同的方式解決警告。

2. Appender 定義

我們先來解釋一下什麼是appender。 Log4j 允許我們將日誌放入多個目的地。它打印輸出的每個目的地稱為 appender 。我們有用於控制台、文件、JMS、GUI 組件等的附加程序。

log4j 中沒有定義默認的appender。此外,記錄器可以有多個appender,在這種情況下,記錄器將輸出打印到所有appender中。

3. 警告信息說明

現在我們知道了 appender 是什麼,讓我們了解手頭的問題。警告消息說找不到記錄器的附加程序。

讓我們創建一個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.baeldung.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>

我們定義了root記錄器,它位於記錄器層次結構的頂部。所有應用程序記錄器都是它的子項並覆蓋其配置。我們用一個 appender 定義了root記錄器,它將日誌放入控制台。

讓我們NoAppenderExample類並檢查控制台輸出。結果,日誌包含我們的語句:

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

4.1. Appender 可加性

不必為每個記錄器定義一個 appender。給定記錄器的日誌記錄請求將日誌發送到為其定義的附加程序以及為層次結構中更高的記錄器指定的所有附加程序。讓我們用一個例子來展示它。

如果記錄A定義控制台的appender和記錄器B是一個孩子A ,記錄B打印其記錄到控制台了。僅當中間祖先中的可加性標誌設置為true時,記錄器才會從其祖先繼承 appender。如果 additivity 標誌設置為false ,則不會繼承來自層次結構中更高記錄器的 appender。

為了證明logger從祖先那裡繼承了 appender,讓我們在log4j.xml文件中為NoAppenderExample logger

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
 <log4j:configuration debug="false">
 ...
 <logger name="org.1ju.log4j.NoAppenderExample" />
 ...
 </log4j:configuration>

讓我們NoAppenderExample類。這一次,日誌語句出現在控制台中。儘管NoAppenderExample logger 沒有明確定義 appender,但它從root logger繼承了 appender。

5. 配置文件不在類路徑上

現在讓我們考慮在應用程序類路徑之外定義配置文件的情況。我們有兩個選擇:

  • java命令行選項指定文件路徑-Dlog4j.configuration=<path to log4j configuration file>
  • 在代碼中定義路徑: PropertyConfigurator.configure(“<path to log4j properties file>”);

在下一節中,我們將看到如何在我們的 Java 代碼中實現這一點。

6. 解決代碼問題

假設我們不需要配置文件。我們把log4.xml文件去掉,修改main方法:

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

我們從BasicConfigurator類調用靜態configure它將ConsoleAppender添加到root記錄器。我們看一下configure方法的源碼:

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

因為root logger 一直存在,我們可以通過編程方式向其添加控制台 appender。

7. 結論

關於如何解決有關缺少 appender 的 log4j 警告的簡短教程到此結束。我們解釋了 appender 是什麼以及如何使用配置文件解決警告問題。然後,我們解釋了 appender 可加性是如何工作的。最後,我們展示瞭如何解決代碼中的警告。