Log4j

**Apache Log4j** 是一個基於 Java 的紀錄檔記錄工具。它是由瑞士程式設計師 Ceki Gülcü 於 2001 年開發的，現在則是 Apache 軟體基金會的一個專案。 Log4j 是幾種 Java 紀錄檔框架之一。

Gülcü 此後開創了 SLF4J 和 Logback 專案，想使其成為 Log4j 的繼任者。

Log4j 團隊建立了 Log4j 的繼任者，版本號為 2.0 的新版本。Log4j 2.0 著重於 Log4j 1.2、1.3、java.util.logging 和 logback 中的問題，並解決這些框架中的架構問題。此外，Log4j 2.0 提供了一個外掛程式架構，這使得其更可延伸。Log4j 2.0 不是與 1.x 向下相容的版本，雖然有一個「配接器」可用。

2021 年 12 月 9 日，Log4j 2.0 的一個零日遠端代碼執行漏洞被報告，其被稱為「Log4Shell」，公共漏洞和暴露編號為 CVE-2021-44228。它被定性為「過去十年來最大、最關鍵的漏洞」。

## log4j 1 的紀錄檔等級

下表中定義的 log4j 1 的紀錄檔級別和訊息，以嚴重性遞減排序。左欄列出了 log4j 的紀錄檔級別定義，右列提供了每個紀錄檔級別的簡要說明。

## 組態 Log4j 1.2

有三種方法來組態 log4j：通過.properties 檔案，通過 XML 檔案，通過 Java 代碼。通過上述任意方法，你可以定義 log4j 的三個主要組件：Logger、Appender 和 Layout。通過檔案組態 log4j，具有無需修改應用即可打開或關閉紀錄檔的好處。例如，應用程式可以在紀錄檔關閉的情況下執行，直到問題出現後，再紀錄檔功能可以簡單地通過修改設定檔重新打開。

**Logger**（記錄器）是紀錄檔的邏輯檔名。其使用已知的 Java 應用程式的名稱。每個記錄器當前以什麼紀錄檔記錄級別（FATAL、ERROR 等）記錄是獨立組態的。在 log4j 的早期版本中，這些被稱為類別（category）和優先級（priority），但現在他們分別被稱為 logger（記錄器）和 level（級別）。

實際的輸出是通過 **Appender**（輸出源）。有許多可用的 Appender，比如 FileAppender、ConsoleAppender、SocketAppender、SyslogAppender、NTEventLogAppender，甚至 SMTPAppender。多個 Appender 可以被關聯到任何 Logger 上，所以可以到多個輸出檔案上記錄相同的資訊，例如同時到一個本地檔案和通過通訊端監聽器到另一台電腦上。

Appender 使用 **Layout**（布局）格式化紀錄檔條目。常用的格式化為「一次一行」式紀錄檔檔案的布局是 PatternLayout，其使用一個模式字串，就像 C/C++ 函式 printf 那樣。此外還有 HTMLLayout 和 XMLLayout，使用 HTML 或 XML 格式的時候會更方便。

要除錯一個表現異常的設定檔，使用 Java VM 參數 `-Dlog4j.debug` 通過標準輸出輸出 Log4j 自身的資訊。要獲知 log4j.propeties 的路徑，檢查 `getClass().getResource("/log4j.properties")` 或 `getClass().getResource("/log4j.xml")`。

log4j 還有一個隱含的「未組態」組態，即一個缺乏 log4j 的組態但使用了 log4j 的 Java 應用程式。這將把一個警告（該程式未組態 log4j）列印到標準輸出，並提供 log4j 網站的 URL，在那裡可以找到警告和組態的詳細資訊。除了列印此警告，未組態的 log4j 的應用程式不會列印 INFO、DEBUG 或 TRACE 級別的訊息，而且還可能不輸出更進階別的訊息。

### log4j 1.2 組態範例

## TTCC

TTCC 是 log4j 使用的訊息格式。TTCC 是 _Time Thread Category Component_（時間、執行緒、類別、組件）的縮寫。例如，採用以下模式（pattern）：

```
 %r [%t] %-5p %c %x - %m%n
```

模式轉換表為：

**範例輸出** 

467 [main] INFO org.apache.log4j.examples.Sort - Exiting main method.

## 移植

* _log4c_—— 一個 C 語言下的移植。最新的版本為 2013 年發布的 1.2.4 版。該專案已不再活躍。
* _log4js_—— 一個 JavaScript 下的移植。最新的版本為 2008 年發布的 1.1 版。
* log4javascript （頁面存檔備份，存於網際網路檔案館）——JavaScript 下的另一個移植。最新的版本為 2014 年 5 月發布的 1.4.6 版。
* JSNLog （頁面存檔備份，存於網際網路檔案館）——JavaScript 下的另一移植。在 2014 年 7 月，最新的版本為 2.7.1，並且定期更新。
* Apache Log4net—— 微軟.NET Framework 下的移植。最新的版本為 2013 年發布的 1.2.13。
* log4perl （頁面存檔備份，存於網際網路檔案館）——log4j 紀錄檔軟體套件在一個 Perl 下的移植。最新的版本為 2014 年 5 月發布的 1.44。
* log4r—— 一個 Ruby 下的「移植」。
* PL-SQL-Logging-Utility （頁面存檔備份，存於網際網路檔案館）——log4j 在 PL/SQL 下的一種實現。
* Log4db2 （頁面存檔備份，存於網際網路檔案館）—— 一個為使用 SQL 命令和 SQL PL 代碼的 DB2 LUW 的紀錄檔記錄工具

## Apache Log4j 2

Apache Log4j 2 是 Log4j 1 的繼任者，2014 年 7 月其 GA 版本（正式發布版）發布。該框架被從頭重寫，並從現有的紀錄檔解決方案中獲得靈感（包括 Log4j 1 和 JUL）。該版本與 Log4j 1 的主要差異是：

* 改進的組態語法
* 支援 XML 和 JSON 組態
* 改進的過濾器
* 屬性（Property）支援
* 標記
* 提高速度
* 模組化：Log4j 2 支援外掛程式系統
* 提高了可靠性
* 組態自動重新安裝

Log4j 2 的最被認可的特點之一是「非同步記錄器」的效能。Log4j 2 利用了 LMAX Disruptor （頁面存檔備份，存於網際網路檔案館）。例如，在相同的環境下，Log4j 2 可以寫每秒超過 18,000,000 條資訊，而其他框架（像 Logback 和 Log4j 1）每秒只能寫 < 2,000,000 條訊息。

Log4j 2 提供對 SLF4J、Commons Logging、Apache Flume 和 Log4j 1 的支援。

## Log4Shell 漏洞

阿里巴巴集團於 2021 年 11 月 24 日發現並報告給 Apache ，並於 12 月 9 日在推文中發布了一個涉及 Log4j 2 中遠端代碼執行的零日漏洞，其描述符為「Log4Shell」（CVE -2021-44228 （頁面存檔備份，存於網際網路檔案館）），受影響的服務包括 Cloudflare、iCloud、我的世界：Java 版、 Steam、騰訊 QQ 和推特。 Apache 軟體基金會分配了最大 CVSS Log4Shell 的嚴重等級為 10，因為數百萬台伺服器可能容易受到該漏洞的攻擊。網路安全公司 Tenable 將該漏洞描述為「過去十年中最大、最關鍵的漏洞」 ，Lunasec 的 Free Wortley 將其描述為「災難性的設計失敗」。

在美國，網路安全和基礎設施安全域主任 Jen Easterly 稱該漏洞利用「至關重要」，並建議供應商優先考慮軟體更新，和德國機構聯邦資訊安全辦公室 (BSI) 將該漏洞指定為處於最高威脅級別，稱其為「極其嚴重的威脅情況」（翻譯）。加拿大網路安全中心呼籲各組織立即採取行動。

可以通過組態設定禁用導致漏洞的功能，該設定已在 Log4j 版本 2.15.0-rc1（2021 年 12 月 6 日正式發布，漏洞發布前三天）中刪除 ，並替換為各種設定限制遠端尋找，從而減輕漏洞。為提高安全性，此漏洞所基於的所有使用 JNDI 的功能將預設禁用，並且從版本 2.16.0 開始刪除對訊息尋找的支援。

官方的 Minecraft：Java 版啟動器已修補此漏洞。使用自訂啟動器或自訂 Java 版本可能意味著客戶端尚未打修補程式。在沒有修補此漏洞的伺服器上玩遊戲將允許伺服器上的任何玩家在另一個客戶端的電腦上執行潛在的惡意代碼。在 1.18.1 以上的版本上玩單人遊戲或多人遊戲將防止此漏洞。低於 1.7 的版本不受影響。如果遊戲伺服器主機執行的是 1.7-1.18 版本，則必須專門修補其伺服器，如果不這樣做，任何玩家都可以使用此漏洞。

## 參考文獻

## 延展閱讀

## 參閱

* Chainsaw

## 外部連結

* log4j 官方首頁 （頁面存檔備份，存於網際網路檔案館）