Apache Log4j

Apache Log4j とは、Apache Commons Loggingインタフェースに基づくJavaロギングフレームワークのひとつです。ロギングユーティリティに依存しない共通インタフェースでログを出力することができます。

インストール

Apache Log4jの公式サイトからJARファイルをダウンロードして、APIとcoreの2つのJARファイルをクラスパスに配置する。

バージョン2.16.0の場合は、次のJARファイルである。

使い方

Apache Log4jを使ってログを書き込むには、LogManagerからLoggerを取得して、このロガーを使ってメッセージを書き込む。

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class HelloWorld {
  private static final Logger logger = LogManager.getLogger("HelloWorld");
  public static void main(String[] args) {
    logger.info("Hello, World!");
  }
}

Javaのロギング

Javaのロギング(ログ出力)には次のようなものがある。

Apache Commons Logging
Javaのロギングのインタフェース
Apache Log4J
Javaのロギング実装
java.util.logging
Javaの標準ロギングAPI
SLF4J (Simple Logging Facade for Java)
Javaのロギングインタフェース

Javaにはjava.util.loggingという標準ロギングAPIがある。本来は標準APIがあるならそれを使うべきであるが、このjava.util.loggingが使いづらく評判が悪かったため、実際にはApache Log4Jなどがよく使われている。

ログレベル

log4jは、6つのログレベルを標準で提供している。このほかに利用者が任意のログレベルを追加することもできる。

ログレベル 説明
FATAL 致命的なエラー
ERROR エラー
WARN 警告
INFO 情報
DEBUG デバッグ情報
TRACE トレース情報

log4j.properties

log4jは、2つの方法で設定が可能である。ひとつはプロパティファイル、もうひとつはXMLファイルである。両社とも3つの主要なコンポーネント(ロガー、アペンダ、レイアウト)について定義することができる。ファイルにより設定を行うため、log4jを使用しているアプリケーションを変更することなく、ロギングをon/offfできる。

ロガー(Logger)は論理的なログファイルであり、Javaアプリケーションはこれらの名前を意識する。ログレベルはロガーごとに設定できる。

アペンダ(Appenders)は具体的な出力処理を行う。アペンダにはさまざまな種類があり、それぞれ内容を表す名前がついている。

レイアウト(Layouts)は1件ずつのログを成型するためのアペンダによって参照される。

Loggerの設定

Loggerの設定では、Loggerごとにログ出力レベルと使用するAppenderの名前を設定する。

log4j.logger.ロガー名=[ログ出力レベル|INHERITED],アペンダ名[,アペンダ名...]

RootLoggerで優先度を設定しておけば、それを継承することができる。

# RootLogger
log4j.rootLogger=FATAL

# Logger
log4j.logger.com.fc2web.itref=INHERITED

Appenderの設定

使用するAppenderとそのオプションの値を設定することができる。

log4j.appender.アペンダ名=アペンダのクラス名
log4j.appender.アペンダ名.オプション=値
log4j.appender.LOGFILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.LOGFILE.File=/usr/local/user1/user1.log
log4j.appender.LOGFILE.DatePattern='.'yyyy-MM-dd
log4j.appender.LOGFILE.layout=org.apche.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d [MyApp] %-5p %t %F:%L %m %n

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d %-5p %F:%L %m%n

Appenderの種類

WriterAppender
ログをライタに出力するアペンダ
ConsoleAppender
ログをコンソールに出力するアペンダ
FileAppender
ログをファイルに出力するアペンダ
RollingFileAppender
ログをファイルに出力するアペンダ
DailyRollingFileAppender
ログをファイルに出力するアペンダ
NullAppender
ログに何も出力しないアペンダ

WriterAppender

org.apache.log4j.WriterAppenderクラスは、ログをjava.io.Writerオブジェクト又はjava.io.OutputStreamオブジェクトに出力するアペンダである。

ConsoleAppender

org.apache.log4j.ConsoleAppenderクラスは、ログを標準出力ストリーム(System.out)および標準エラー出力ストリーム(System.err)に出力するアペンダである。ConsoleAppenderの設定例を次に示す。

log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target = System.out
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern = %d %-5p %F:%L %m%n
Target
ログの出力先。System.out(標準出力)又はSystem.err(標準エラー出力)を指定する。

FileAppender

org.apache.log4j.FileAppenderクラスは、ログをファイルに出力するアペンダである。FileAppenderの設定例を次に示す。

log4j.appender.FILE = org.apache.log4j.FileAppender
log4j.appender.FILE.Append = false
log4j.appender.FILE.File = log1.log
File
ログのファイル名を相対パス又は絶対パスで指定する。
Append
true(ファイルの末尾に追加する)又はfalse(ファイルに上書きする)を指定する。

RollingFileAppender

org.apache.log4j.RollingFileAppender はログをファイルに出力するアペンダである。


log4j.appender.FILE = org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File = log1.log
log4j.appender.FILE.MaxFileSize = 10MB
log4j.appender.FILE.MaxBackupIndex = 3
File
ログのファイル名を相対パス又は絶対パスで指定する。
MaxFileSize
ログファイルの最大サイズを指定する。
MaxBackupIndex
バックアップファイルの最大数を指定する。

DailyRollingFileAppender

org.apache.log4j.DailyRollingFileAppender クラスは、FileAppenderを拡張したクラスで、日付や時間により、ファイルのバックアップが作成される。

log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.File = log1.log
log4j.appender.FILE.DatePatterm = '.'yyyy-MM-dd
File
ログのファイル名を相対パス又は絶対パスで指定する。
DatePatterm
日付パターンを指定する。
DailyRollingFileAppenderクラスのDatePatterm
日付パターン ログファイル切り替えのタイミング
'.'yyyy-MM 日付が変わるとき
'.'yyyy-MM-dd-HH 1時間ごと

NullAppender

アペンダにorg.apache.log4j.varia.NullAppenderを指定すると、ログに何も出力しないようになる。

org.apache.log4jパッケージ

org.apache.log4jは、Log4jのメインパッケージである。

ConsoleAppender
ユーザが指定したレイアウトを使って、System.out又はSystem.errにログイベントを追加する。
DailyRollingFileAppender
ユーザが選択した頻度でファイルをロールオーバーするようFileAppenderを拡張したクラス。
FileAppender
ファイルにログイベントを追加する。
Logger
org.apache.log4jパッケージの中心となるクラス。
RollingFileAppender
一定のサイズに達したらログファイルをバックアップするようFileAppenderを拡張したクラス。
WriteAppender
ユーザの選択に応じてWriter又はOutputStreamにログイベントを追加する。

Maven

Apache Maven でビルドするには、pom.xml ファイルに以下の依存関係を追加する。

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.16.0</version>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.16.0</version>
  </dependency>
</dependencies>

脆弱性

Apache Log4jの一部バージョンにおいて、第三者が細工したデータを遠隔から送信することで、任意のコマンドを実行できる可能性がある。

Apache Log4j 2.15.0 より前の 2.x 系のバージョンで脆弱性が確認されている。

Log4jの脆弱性
バージョン 脆弱性
1.x なし
2.0.x あり
2.1.x あり
2.2.x あり
2.3.x あり
2.4.x あり
2.5.x あり
2.6.x あり
2.7.x あり
2.8.x あり
2.9.x あり
2.10.x あり
2.11.x あり
2.12.x あり
2.13.x あり
2.14.x あり
2.15.x なし
2.16.x なし

クラスパスに配置されているJARファイルのファイル名(log4j-api-2.16.0.jar や log4j-core-2.16.0.jar)からApache Log4jのバージョンを確認できる。

脆弱性の対応策は、Apache Log4jを最新のバージョンへ代えればよい。

Apache Log4j 2.10.x から 2.14.x までであれば、環境変数 LOG4J_FORMAT_MSG_NO_LOOKUPS を true に設定することで脆弱性を回避できる。

$ export LOG4J_FORMAT_MSG_NO_LOOKUPS=true

または、Apache Log4jを実行するJava仮想マシンを起動するときに、javaコマンドの -D オプションで下記のシステムプロパティを設定することで脆弱性を回避できる。

$ java -Dlog4j2.formatMsgNoLookups=true Example

参考文献

The Apache Software Foundation (2021) Apache Log4j 2

The Apache Software Foundation (2021) Apache Log4j Security Vulnerabilities

独立行政法人情報処理推進機構 (2021) Apache Log4j の脆弱性対策について(CVE-2021-44228)