0Pricing
Java Academy · レッスン

構造化ログを使う理由

System.out.println の先を学びます。

「構造化ログを使う理由」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

println の問題点

System.out.printlnは簡単な実験には適していますが、実際のアプリケーションにおけるロギングツールとしては不十分です。

  • タイムスタンプ、レベル、スレッド名がありません。
  • 本番環境で無効にする方法がありません。
  • stdout にしか書き込めず、出力先を振り分けられません。
public class Main {
    public static void main(String[] args) {
        // Crude: no level, no timestamp, always on
        System.out.println("User logged in");
    }
}

ロギングフレームワークが提供するもの

ロギングフレームワークを使うと、次の機能を利用できます。

  • ノイズを絞り込むためのレベル(TRACE、DEBUG、INFO、WARN、ERROR)。
  • タイムスタンプ、スレッド名、ロガー名の自動付加。
  • ファイル、コンソール、リモートシステムへの出力先の振り分け。
  • 再コンパイルせずに実行時設定を変更する機能。
public class Main {
    public static void main(String[] args) {
        // A framework would render: time, level, logger, thread, message
        String simulated = "2026-01-01 10:00:00 INFO  c.e.App [main] - User logged in";
        System.out.println(simulated);
    }
}

ログレベルの説明

レベルは、メッセージを重要度で分類します。

  • TRACE:非常に細かな情報。
  • DEBUG:開発時の診断情報。
  • INFO:通常の進捗や節目。
  • WARN:予期しないものの、復旧可能な状態。
  • ERROR:対処が必要な障害。
public class Main {
    enum Level { TRACE, DEBUG, INFO, WARN, ERROR }
    public static void main(String[] args) {
        Level threshold = Level.INFO;
        for (Level l : Level.values()) {
            boolean shown = l.ordinal() >= threshold.ordinal();
            System.out.println(l + " visible? " + shown);
        }
    }
}

しきい値によるフィルタリング

ロガーにはしきい値があります。しきい値より低いレベルのメッセージは、低コストで破棄されます。

本番環境では INFO に設定して DEBUG と TRACE を無効にすれば、コードを変更せずにノイズとコストを削減できます。

public class Main {
    enum Level { TRACE, DEBUG, INFO, WARN, ERROR }
    static void log(Level threshold, Level level, String msg) {
        if (level.ordinal() >= threshold.ordinal()) {
            System.out.println(level + " - " + msg);
        }
    }
    public static void main(String[] args) {
        Level t = Level.WARN;
        log(t, Level.DEBUG, "hidden detail");
        log(t, Level.ERROR, "shown error");
    }
}

構造化ログと非構造化ログ

非構造化ログは通常の文章です。構造化ログは、機械で解析できるキーと値のコンテキスト(ユーザー ID、リクエスト ID など)を付加します。

構造化ログは、Elasticsearch や Loki などのツールで検索や集計を行えます。

import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // Structured context as key-value pairs
        Map<String, Object> fields = Map.of("event", "login", "userId", 42, "ok", true);
        System.out.println(fields);
    }
}

ファサードという考え方

コードを特定のロギングライブラリに依存させるべきではありません。SLF4J のようなファサードを使えば、1つの API に対してコードを書き、後からバックエンド(Logback、Log4j2)を交換できます。

これにより、アプリケーションをロギング実装の選択から切り離せます。

public class Main {
    public static void main(String[] args) {
        // Concept: your code calls a facade interface, not a concrete logger
        System.out.println("App -> SLF4J facade -> Logback backend");
    }
}

ブール値のフラグだけではいけない理由

if (DEBUG) System.out.println(...)のようなコードを使うこともできます。しかし、これはコードベース全体に処理を散在させ、パッケージごとの制御もできません。

ロギングフレームワークなら設定を一元化できるため、あるパッケージでは DEBUG を有効にし、それ以外では ERROR に設定できます。

public class Main {
    static final boolean DEBUG = false;
    public static void main(String[] args) {
        // Inflexible: one global switch, scattered checks
        if (DEBUG) System.out.println("diagnostic");
        System.out.println("A framework controls this per logger instead");
    }
}

パフォーマンスに関する注意点

ロギングは無効なときに低コストであるべきです。フレームワークはフィルタリングされたレベルの処理を省略し、パラメーター化されたメッセージによって、破棄する文字列の生成を避けます。

println は、出力を誰も読まない場合でも、引数を常に評価します。

public class Main {
    static String expensive() {
        System.out.println("(building expensive string)");
        return "big report";
    }
    public static void main(String[] args) {
        boolean debugEnabled = false;
        // Only build the message if it will actually be logged
        if (debugEnabled) System.out.println(expensive());
        System.out.println("skipped expensive work");
    }
}

出力先の一元的な振り分け

フレームワークは、1つ以上のアペンダーにログを送ります。アペンダーには、コンソール、ローテーションするファイル、syslog、ネットワークコレクターなどがあります。

出力先は一度設定すればよく、アプリケーションコードはそのまま維持できます。

public class Main {
    public static void main(String[] args) {
        String[] appenders = {"CONSOLE", "ROLLING_FILE", "JSON_HTTP"};
        for (String a : appenders) System.out.println("route logs to: " + a);
    }
}

相関とコンテキスト

実際のシステムでは、リクエスト内のすべてのログ行にリクエスト IDを追加します。これにより、スレッドやサービスをまたいで、1人のユーザーの処理の流れを追跡できます。

SLF4J では、MDC(Mapped Diagnostic Context)を通じてこの機能をサポートしています。

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, String> mdc = new HashMap<>();
        mdc.put("requestId", "req-1234");
        System.out.println("All logs in this request tagged with " + mdc);
    }
}

計画

このコースでは、次のことを学びます。

  • SLF4J ファサードを使ってロガーを取得します。
  • 適切なレベルでログを記録します。
  • 効率的なパラメーター化メッセージを使います。
  • アペンダーとパターンを使ってLogbackを設定します。
public class Main {
    public static void main(String[] args) {
        System.out.println("Next: SLF4J facade and loggers");
    }
}

クイックチェック

構造化ロギングについての理解度を確認します。

振り返り

構造化ロギングが重要である理由を学びました。

  • printlnにはレベル、メタデータ、ルーティングがありません。
  • フレームワークによってレベル、フィルタリング、アペンダーが追加されます。
  • ファサードによって、コードとバックエンドを分離できます。
  • 構造化コンテキストとMDCによって、相関付けが可能になります。

次は、SLF4Jファサードとロガーの作成です。

public class Main {
    public static void main(String[] args) {
        System.out.println("Structured logging recap complete");
    }
}

よくある質問

「構造化ログを使う理由」レッスンは無料ですか?

はい。「構造化ログを使う理由」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「構造化ログを使う理由」で何を学びますか?

System.out.println の先を学びます。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「構造化ログを使う理由」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 構造化ログを使う理由
  2. SLF4J ファサードとロガー
  3. パラメータ化ロギング
  4. Logback の設定
← Java Academyに戻る