PR

Log4jとは何か?初心者向けにわかりやすく3分で解説

Java

Log4j(ログ・フォー・ジェイ)は、Javaアプリケーションでログを出力しやすく管理しやすくするためのライブラリ(機能の塊)です。元々はApache Software Foundationが開発を進めてきたもので、「ログを取る」という行為を便利にするための道具のようなものだと思ってもらえればOK。

このページでは、よく聞く「Log4j」って実際何なの?という疑問に対して諸々の前提知識を含め、新入社員を想定した0 to 1解説を行います。

スポンサーリンク

前提知識として知っておきたい「ログ」とは?

まずはLog4jの話に入る前に、「ログって何?」というところを簡単におさえておきましょう。

  • ログ(Log) とは、システムやアプリケーションが動いた記録や出来事をテキストなどで残しておくもの。
    • 例)「アプリケーションが起動した」「ユーザーがログインした」「エラーが起きた」など。

もし不具合やエラーが起きたときには、ログが残っていると

  • 「いつ、どんなエラーが起きたのか」
  • 「どんな原因が考えられるのか」

を調べる手がかりになります。Javaでプログラムを書いているときに、デバッグ用にSystem.out.println("何かのメッセージ");を使うことは多いと思います。しかし、これだけだと出力先を分けたいときや、「重要度」に応じてログの扱いを変えたいときなどに対応しづらいのが弱点です。

そこで登場するのがLog4jのような「ログ管理用のライブラリ」です。

Log4jとは何か?

いきなりコードをお見せする前に・・・まずはlog4jって何?という基本概念から解説します。

log4j(ログフォージェイ)は、Javaでログを出力するためのライブラリです。プログラムの動作状況やエラーを記録するのに使われます。ざっくりlog4jは「いつ・どこで・何が起きたか」を記録できるツールだと理解してください。

🔍log4jのポイント

項目説明
主な役割ログ(情報・警告・エラーなど)を出力
出力先コンソール、ファイル、リモートサーバーなど
出力レベルDEBUG, INFO, WARN, ERROR, FATAL
設定方法log4j2.xmllog4j.properties に記述
利用方法Javaコード内で Logger を使って出力

Log4jを使うメリット

  1. ログの重要度(レベル)を簡単に設定できる
    • たとえば「開発時は細かいデバッグ情報をたくさん出す」「本番稼働では必要最低限の重要な情報だけに絞る」といった切り替えが容易。
  2. 出力先を自由に設定できる
    • コンソール(標準出力)やファイル、データベースなど、いろいろな出力先に対応している。
  3. ログの形式を統一して読みやすくできる
    • 「日付や時刻、ログレベル、スレッド名、メッセージ」などを好みのフォーマットで出力できる。
  4. ログファイルが大きくなりすぎないようにローテーションができる
    • ログが大きくなりすぎるとサーバーのディスクを圧迫してしまうので、自動で古いログを圧縮・削除したりできる。

こういったメリットから、Javaでのログ出力にはLog4jや同様のライブラリが広く使われています。要するにログに関するあれこれはLog4jに任せておけばOKだね!といえるぐらい、なんでもやってくれるライブラリです。

ログの出力機能は、アプリケーションそのものの開発に比べてどうしても優先度が低くなりがちですが、Log4jを利用することで面倒な諸々を片付けることができる!というのが多くの現場で利用される理由の1つです。

Log4jのバージョン:1.xと2.xの違い

  • Log4j 1.x
    昔から広く使われていたバージョン。今はサポート終了となっており、セキュリティ面のリスクがあるため、新規開発にはおすすめできない。
  • Log4j 2.x
    1.xの後継として、「大量ログに対応できるパフォーマンス」「柔軟な設定」「非同期処理で高速化」などが大幅に強化されています。
    ただし、2.xでも一部バージョンに深刻な脆弱性(Log4Shell)がありました。すでに修正されているので、最新のアップデート版(2.17以降など)を使用することが重要です。

初心者がLog4jを使う場合は、Log4j 2.xの最新バージョンを導入しましょう。

Log4jの基本概念

ここからはlog4jを理解し、実際に利用するうえで大事なキーワードと詳細な実装方法をご説明します。

1. Logger(ロガー)

  • ログを出力するときに使うオブジェクト参考 オブジェクトとは?)です。
  • プログラムのクラスごとに1つずつLoggerを用意するのが一般的。
  • 使い方のイメージ:
// クラス名を使ってLoggerを取得
private static final Logger logger = LogManager.getLogger(クラス名.class);

public void sampleMethod() {
    logger.info("これはINFOレベルのログメッセージです");
    logger.debug("これはDEBUGレベルのログメッセージです");
}

LogManager.getLogger(クラス名.class) は、LogManager クラスの static メソッド getLogger() を使って Logger インスタンスを取得しているコードです。

ポイント内容
LogManagerlog4jが提供するクラス。ロガーを作成・管理する役割
getLogger()staticメソッド。Loggerのインスタンスを返す
クラス名.classロガーの識別子として使うクラス情報。ログに「どのクラスから出力されたか」が自動で含まれるようになる

例えば↓のように書くと、logger.info("Hello"); とログを出力したときに、
ログに「MyAppクラスから出力された」という情報が自動で付きます。

private static final Logger logger = LogManager.getLogger(MyApp.class);

2. Log Level(ログレベル)

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

public class LogLevelSample {
    private static final Logger logger = LogManager.getLogger(LogLevelSample.class);

    public static void main(String[] args) {
        logger.trace("これはTRACEレベルのログです");
        logger.debug("これはDEBUGレベルのログです");
        logger.info("これはINFOレベルのログです");
        logger.warn("これはWARNレベルのログです");
        logger.error("これはERRORレベルのログです");
        logger.fatal("これはFATALレベルのログです");
    }
}
  • ログの重要度や詳細度を表すもの。代表的なのは以下の6種類です。
    1. TRACE:もっとも詳細なログ。大抵の場合は使わないか、デバッグ専用。
    2. DEBUG:デバッグ用で詳細度高め。
    3. INFO:一般的な情報。アプリの起動・停止、操作イベントの通知など。
    4. WARN:警告。エラーには至らないがリスクのある事象。
    5. ERROR:エラーが起きた場合。
    6. FATAL:アプリが続行不能な重大エラー。

ログが出力されるかどうかは設定ファイルのログレベルによります。たとえば、設定でINFOにしていた場合INFO以上(WARN、ERROR、FATAL)のログだけが実際に出力されます。DEBUGTRACEは出力されません。

後程設定ファイルの詳細について解説します。

3. Appender(アペンダー)

こちらも設定ファイルで指定する項目です。

  • ログの出力先を決めるための仕組みです。
  • 例:コンソール(標準出力)、ファイル(指定したフォルダに保存)、データベースやネットワーク経由の送信など。
  • たとえば「開発環境ではコンソールに表示」「本番環境ではファイルに出力」といった使い分けも可能です。
Appender名出力先
ConsoleAppenderコンソール(標準出力)
FileAppender単一のファイル
RollingFileAppender日付やサイズでファイルを分割
JDBCAppenderデータベース
SocketAppenderネットワーク経由で送信

4. Layout(レイアウト)

こちらも設定ファイルの中で定義する内容です。

  • ログをどんなフォーマット(形式)で出力するかを決める設定です。
    • 例)[%d{yyyy-MM-dd HH:mm:ss}] [%p] %c - %m%n
      • ここでは
        • %d{...}:日時を指定したフォーマットで表示
        • %p:ログレベル(INFOやDEBUGなど)
        • %c:ロガー名(通常はクラス名)
        • %m:ログメッセージ
        • %n:改行

LoggerAppenderへログを渡し、AppenderLayoutに従って文字列を整形して最終的に出力する、というイメージです。

Log4jの動作の流れ

  1. コードでLoggerを呼び出す
    • logger.info("ユーザーがログインしました");
  2. 現在のログレベル設定を確認し、出力して良いかどうかを判定。
    • 例:INFOレベルにしてあるなら、INFO以上は出力OK。DEBUGはスキップされる。
  3. Appendersにログメッセージを渡す
    • どのAppenderを使うかは設定ファイルで決まる(コンソールやファイルなど)。
  4. AppenderがLayoutに従ってメッセージを整形し、出力先に書き込む

このような仕組みのおかげで、コードに「logger.debug」などと書いておけば、設定ファイルでレベルを変えるだけで一括でログ出力をON/OFFできるというわけです。

よって、Log4jを利用するには設定ファイルの内容が重要になってきます。次に設定ファイルの記載方法について解説します。

Log4jの設定ファイル

Log4jを使う上で、設定ファイル(たとえば log4j2.xmllog4j2.properties)を用意するのが一般的です。ここでは最もよく使われる log4j2.xml の例を示します。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <!-- コンソールに出力するAppender -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%p] %c - %m%n"/>
        </Console>

        <!-- ログファイルに出力するAppender -->
        <RollingFile name="File" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%p] %c - %m%n"/>
            <Policies>
                <!-- ログファイルのサイズが5MBを超えたらローテーションする例 -->
                <SizeBasedTriggeringPolicy size="5MB"/>
            </Policies>
            <!-- ローテーションで最大何世代(何ファイル)分を保持するか設定 -->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- ルートロガー:全てのクラスでのログ出力に適用するデフォルト設定 -->
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="File"/>
        </Root>
    </Loggers>
</Configuration>

この例では、

  • コンソール(標準出力)とRollingFile(ファイル)の2種類のAppenderを定義。
  • Root(全体)のログレベルをinfoに設定しているので、info以上(warn, error, fatal)は出力。
  • ファイルについてはサイズが5MB超えたら自動でファイルを切り替え(ローテーション)し、古いログは最大10世代分を保存します。

こうした設定を変えるだけで、ログの出力先やフォーマット、保存ルールを簡単に切り替えできます。コードはそのままで設定ファイルを差し替えるだけで運用方法を変更できるのが大きな利点です。

詳細な設定内容は公式リファレンス等を確認して行いましょう

実際のコード例

以下は、JavaコードでLog4jを使うときの簡単な例です。MavenなどのビルドツールでLog4jの依存関係を追加している前提とします。

package com.example;

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

public class SampleApp {
    // クラスごとにLoggerを作る。staticかつfinalにするのが定番
    private static final Logger logger = LogManager.getLogger(SampleApp.class);

    public static void main(String[] args) {
        // INFOレベルのログ
        logger.info("アプリケーションが起動しました");

        try {
            int result = 10 / 0;  // 故意にエラーを起こす
        } catch (Exception e) {
            // ERRORレベルのログ
            logger.error("エラーが発生しました", e);
        }

        logger.info("アプリケーションを終了します");
    }
}

設定ファイルで Root レベルが info なので、logger.debug("~") をもし呼び出していたとしても、実行しても出力されません(抑制されます)。

使うときに気をつけたいこと

  1. ログレベルの使い分け
    • 開発時:DEBUGTRACE を使って細かい情報を出す。
    • 本番環境:INFO以上に抑えて、余計なログを出力しないようにする。
    • これを守ると、余計なログがたまりすぎて分析が大変になるのを防ぐことができます。
  2. ログファイルのローテーション
    • ログファイルが延々と大きくなると、ディスクを圧迫したり読み込みが遅くなったりします。
    • 定期的に古いものを圧縮・削除し、ファイルを分割しておくのが大切です。
  3. 脆弱性への注意
    • 過去にLog4j 2.xで「Log4Shell」という大きな脆弱性が見つかりました。
    • すでに最新版(2.17以降など)では修正されていますが、常に最新のバージョンを使うようにしましょう
    • 定期的にアップデート情報をチェックし、セキュリティアップデートを怠らないようにすることが重要です。
  4. クラウドやコンテナ環境
    • Dockerなどのコンテナを使う場合は、ファイルではなく**標準出力(ConsoleAppender)**に書き出して、コンテナホストやクラウドのログ収集機能で管理するのが一般的です。

ログはシステム開発・運用の「事件の記録」。不具合調査や監査などにも必須の情報源です。Log4j はJavaでのログ管理を「より便利に、柔軟に」するためのライブラリです。

  • Loggerを使ってコードからログを送出し、
  • AppenderLayoutを設定ファイルで指定して出力先や形式を制御します。
  • Log Levelによって詳しさを切り替えられるのが大きなメリットです。

Log4j 2.xの最新バージョンを使用し、ログレベルやローテーションなどの設定をしっかり整えて運用すれば、システムの保守性・障害対応力が格段に高まります。

タイトルとURLをコピーしました