使用屬性檔的 Log4j 2 配置
一、簡介
Log4j 2 是一個用 Java 寫的流行的開源日誌框架。引入它是為了克服 Log4j 的各種架構缺陷。它是線程安全的、快速的,並且比其前身提供了各種改進。它根據開源 Apache 軟體許可證分發。
Log4j 2 是經典 Log4j 框架的最新改進版本,該框架已於 2015 年 8 月 5 日結束其生命週期。但是,Log4j 仍然作為日誌記錄框架在許多 Java 企業應用程式中廣泛使用。
在本教學中,我們將了解 Log4j 2、它相對於 Log4j 的優勢,以及如何使用 Java 中的log4j2.properties
檔案來配置其核心元件。
2.Maven設定
我們需要pom.xml
中的log4j-core
依賴項來開始:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
我們可以在 Maven 儲存庫中找到最新版本的log4j-core
和log4j-api
。
3.Log4j 2 Logger
與 Log4j 中我們使用Logger.getLogger()
來取得具有特定名稱的Logger
實例不同,在 Log4j 2 中我們使用LogManager.getLogger()
:
private static final Logger logger = LogManager.getLogger(Log4j2Example.class);
LogManager
從設定檔或設定檔類別中讀取初始設定參數。 Logger
與LoggerConfig
關聯,後者與實際傳遞日誌事件的Appender
關聯。
如果我們透過傳遞相同的(類別)名稱來呼叫LogManager.getLogger()
,我們將始終獲得相同記錄器實例的參考。
Logger
和LoggerConfig
都是命名實體。每個Logger
引用一個LoggerConfig,
可以引用其父Logger,從而達到相同的效果。
Logger
遵循命名的層次結構。這意味著名為「 com.baeldung
」的LoggerConfig
是名為「 com.baeldung.foo
」的LoggerConfig
的父級。
4.Log4j 2配置
與僅支援透過屬性和 XML 格式進行配置的 Log4j 不同,我們可以使用JSON、XML、YAML 或屬性格式**定義 Log4j 2 配置**。所有這些格式在功能上都是等效的。因此,我們可以輕鬆地將以一種格式完成的配置轉換為任何其他格式。
此外,Logj2支援自動配置,這意味著它能夠在初始化期間自動配置自身。
它會在開始時掃描並找到所有ConfigurationFactory
插件,並按從高到低的加權順序排列它們 - 屬性檔案的優先級最高,值為8
,其次是 YAML、JSON 和 XML。
這意味著如果我們同時以屬性檔案和 XML 檔案的形式進行日誌記錄配置,則屬性檔案將優先。
5. log4j2.properties
文件
當Log4j 2發佈時,它不支援透過屬性檔進行配置。從2.4版本發布開始支援properties檔案。
預設屬性設定檔始終是log4j2.properties
。 Logger
從CLASSPATH
取得此文件的引用。
但是,如果我們需要使用不同的設定檔名,我們可以使用系統屬性log4j.configurationFile
來設定它。
系統屬性可以指本機檔案系統或可以包含URL。如果 Log4j 2 找不到設定文件,則它會提供DefaultConfiguration
。在這種情況下,我們將日誌輸出重新導向到控制台,並將root logger
等級設為ERROR
。
6. log4j2.properties
檔案的語法
log4j2.properties
檔案的語法與log4j.properties
的語法不同。在log4j.properties
檔案中,每個配置都以「 log4j
」開頭,而在log4j2.properties
配置中已省略。
讓我們來看看一般log4j2.properties
檔案的語法:
# The root logger with appender name
rootLogger = DEBUG, STDOUT
# Assign STDOUT a valid appender & define its layout
appender.console.name = STDOUT
appender.console.type = Console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %msg%n
這裡, STDOUT
是Appender
的名稱。如同前面所討論的,我們可以將多個appender
附加到一個logger
上,以將日誌定向到不同的目的地。
此外,我們應該在每個 Log4j 2 配置中定義一個根記錄器。否則,將使用具有ERROR
等級和ConsoleAppender
預設root LoggerConfig
。
7. 例子
現在,讓我們透過一些範例來了解不同appender
的log4j2.properties
檔案配置。
7.1.範例程式
讓我們從記錄一些訊息的範例應用程式開始:
public class Log4j2ConsoleAndFile {
private static final Logger logger = LogManager.getLogger(Log4j2ConsoleAndFile.class);
public static void main(String[] args) {
logger.info(<span class="hljs-string">"Hello World!"</span>);
logger.debug(<span class="hljs-string">"Hello World!"</span>);
}
}
7.2.控制台日誌記錄
如果未找到設定文件,則控制台是記錄訊息的預設位置。讓我們使用root logger
為控制台Appender
建立一個log4j2.properties
配置,並為其定義日誌記錄等級:
# Root Logger
rootLogger=DEBUG, <span class="hljs-string">STDOUT</span>
# Direct log messages to stdout
<span class="hljs-attr">appender.console.type</span> = <span class="hljs-string">Console
</span><span class="hljs-attr">appender.console.name</span> = <span class="hljs-string">STDOUT
</span><span class="hljs-attr">appender.console.layout.type</span> = <span class="hljs-string">PatternLayout
</span><span class="hljs-attr">appender.console.layout.pattern</span> = <span class="hljs-string">[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</span>
在這裡,我們定義了一個具有以下規範的log4j2.properties
檔案:
- 我們將
root logger
的層級定義為DEBUG
。這表示我們將取得等級為DEBUG
及以上的所有日誌事件。我們也將appender
的名稱定義為STDOUT
。 - 由於我們希望將日誌導向到控制台,因此我們將
Appender type
指定為Console
。我們應該注意,鍵名中的console
一詞只是一個約定,而不是強制性的。 - 然後,我們指定要列印日誌訊息的模式。
讓我們也了解我們使用的layout
模式中每個轉換字元的含義:
-
%-5level
將日誌等級資訊加入到每個日誌語句中。它表示日誌記錄事件的優先權左對齊到五個字元的寬度。 -
%d
以定義的格式新增時間戳記。 -
%t
將執行緒名稱加入到日誌語句中 -
%c{1}
列印限定的類別名,可選地後接套件名稱(精確度限定符),
用於記錄特定的日誌語句。 -
%msg
列印實際的日誌訊息。 -
%n
在每個日誌語句後面都會新增一行。
因此,當我們運行範例應用程式時,我們會在控制台上列印以下幾行:
[INFO ] 2023-08-05 23:04:03.255 [main] Log4j2ConsoleAndFile - Hello World!
[DEBUG] 2023-08-05 23:04:03.255 [main] Log4j2ConsoleAndFile - Hello World!
PatternLayout
類別解釋了更多關於我們可以根據需要使用的轉換字元的資訊。
7.3.多個目的地
如前所述,我們可以將日誌事件重新導向到多個目的地:
# Root Logger
rootLogger=INFO, STDOUT, <span class="hljs-string">LOGFILE</span>
# Direct log messages to STDOUT
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
# Direct to a file
<span class="hljs-attr">appender.file.type</span> = <span class="hljs-string">File
</span><span class="hljs-attr">appender.file.name</span> = <span class="hljs-string">LOGFILE
</span><span class="hljs-attr">appender.file.fileName </span>= baeldung/<span class="hljs-string">logs/log4j2.log
</span><span class="hljs-attr">appender.file.layout.type </span>= <span class="hljs-string">PatternLayout
</span><span class="hljs-attr">appender.file.layout.pattern </span>= <span class="hljs-string">[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</span><span class="hljs-attr">appender.file.filter.threshold.type</span> = <span class="hljs-string">ThresholdFilter
</span><span class="hljs-attr">appender.file.filter.threshold.level</span> = <span class="hljs-string">info</span>
在這裡,我們使用了兩個appender
將日誌訊息重新導向到檔案和控制台。我們將它們命名為STDOUT
和LOGFILE
。此外,我們已將兩個appender
新增至root logger
。
要將日誌訊息重新導向到文件,我們需要指定文件名稱及其位置。
我們也使用了ThresholdFilter,
它可以過濾掉具有特定日誌等級及以上等級的日誌訊息。最後,我們將threshold.level
指定為INFO. Thus,
所有等級為INFO
或以上的日誌訊息都會列印到該檔案中。
當我們執行範例應用程式時,我們僅在控制台以及log4j2.log
檔案上列印以下行:
[INFO ] 2023-08-05 23:04:03.255 [main] Log4j2ConsoleAndFile - Hello World!
八、結論
在本文中,我們探討了 Log4j 2 及其相對於 Log4j 的優點。我們也了解了log4j2.properties
檔案的語法以及配置log4j2.properties
檔案的一些簡單範例。
與往常一樣,本文附帶的範例可以在 GitHub 上找到。