ログ管理(SLF4J / Logback / Log4j2)
ログ管理とは
ログ管理とは、アプリケーションの実行中に発生したイベント(処理の開始・終了、エラー、ユーザーの操作など)を記録し、障害調査やシステム監視に活用する仕組みのことである。Java のアプリケーションでは、SLF4J をファサード(窓口)とし、Logback または Log4j2 を実装として組み合わせるのが現在の標準的な構成である。
なぜ SIer で重要か
SIer が手がける業務システムでは、ログは「障害時の原因調査」「運用監視」「監査証跡(いつ誰が何をしたかの記録)」として極めて重要な役割を担う。特に金融や官公庁のシステムでは、ログの出力ルールが厳密に定められていることが多く、適切なログ設計はシステムの品質を左右する。新入社員が最初に任される開発タスクでも、ログ出力の実装は頻繁に登場する。
基本概念
SLF4J(ファサード)+ 実装のアーキテクチャ
Java のロギングは「ファサード(API)」と「実装」を分離するアーキテクチャが標準となっている。
アプリケーションコード
↓ 呼び出す
SLF4J(ファサード / API)
↓ 委譲する
Logback or Log4j2(実装)
↓ 出力する
ログファイル / コンソール / 外部システム
SLF4J(Simple Logging Facade for Java) はログ出力の API(インターフェース)だけを提供するライブラリである。実際のログ出力処理は行わず、背後にある実装ライブラリに処理を委譲する。
この分離により、アプリケーションコードは SLF4J の API だけに依存し、ログの実装を Logback から Log4j2 に切り替える場合でも、アプリケーションコードの変更は不要になる。
ログレベル
ログには重要度に応じたレベルが定義されている。上から順に重要度が高い。
| レベル | 用途 | 出力例 |
|---|---|---|
| ERROR | システムの異常・回復不能なエラー | データベース接続失敗、外部 API のタイムアウト |
| WARN | 想定外だが処理は継続できる状況 | 古い API の使用、リトライ発生 |
| INFO | 正常な処理の重要なイベント | アプリケーション起動完了、バッチ処理の開始・終了 |
| DEBUG | 開発時のデバッグ情報 | メソッドの引数・戻り値、SQL のパラメータ |
| TRACE | 最も詳細なデバッグ情報 | ループの各反復、低レベルの通信内容 |
本番環境では INFO 以上を出力し、開発環境では DEBUG 以上を出力するのが一般的である。ログレベルの設定は設定ファイルで環境ごとに変更できる。
使い方の基本
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
public void createOrder(Order order) {
logger.info("注文処理を開始します。注文ID: {}", order.getId());
try {
// 業務処理
logger.debug("注文明細数: {}", order.getItems().size());
} catch (Exception e) {
logger.error("注文処理でエラーが発生しました。注文ID: {}", order.getId(), e);
throw e;
}
logger.info("注文処理が完了しました。注文ID: {}", order.getId());
}
}
{} はプレースホルダーで、SLF4J が自動的に引数の値を埋め込む。文字列結合("注文ID: " + order.getId())よりも効率的で、ログレベルが無効の場合に不要な文字列結合が発生しない。
Logback と Log4j2
| 項目 | Logback | Log4j2 |
|---|---|---|
| 開発元 | SLF4J と同じ作者(Ceki Gulcu) | Apache Software Foundation |
| 設定ファイル | logback.xml | log4j2.xml |
| 特徴 | SLF4J とのネイティブ統合、Spring Boot のデフォルト | 高性能な非同期ロギング、プラグイン拡張 |
| SIer での採用 | Spring Boot プロジェクトで多い | 既存システムや非 Spring プロジェクトで多い |
Spring Boot はデフォルトで SLF4J + Logback の構成を採用しているため、新規の Spring Boot プロジェクトでは自然と Logback が使われることになる。
Log4j と Log4j2 の違い
Log4j(バージョン 1.x)と Log4j2(バージョン 2.x)は名前が似ているが別のライブラリである。Log4j 1.x は 2015 年に EOL(End of Life)となっており、セキュリティアップデートも提供されない。新規プロジェクトでは絶対に使ってはならない。
Log4Shell 脆弱性の教訓
2021 年 12 月に発見された Log4Shell(CVE-2021-44228) は、Log4j2 の JNDI Lookup 機能を悪用した重大な脆弱性である。攻撃者がログに特定の文字列を記録させるだけでリモートコード実行が可能となり、世界中のシステムに影響を及ぼした。
この事件は以下の教訓を残した。
- 依存ライブラリの脆弱性管理は常に重要である: たとえ直接使っていなくても、推移的依存関係に含まれるライブラリの脆弱性に注意する必要がある
- SBOM(Software Bill of Materials)の重要性: プロジェクトが依存するすべてのライブラリとバージョンを把握しておくことが、脆弱性発生時の迅速な対応につながる
- 迅速なアップデート体制の構築: 脆弱性が公表された際に素早くライブラリを更新できる体制を整えておくことが求められる
SIer のプロジェクトでも、Log4Shell を契機に依存ライブラリの脆弱性スキャンを CI/CD パイプラインに組み込む動きが広がった。
SIer での使われ方
ログ設計書
SIer の大規模プロジェクトでは「ログ設計書」を作成し、以下のような項目を事前に定義することが多い。
- ログの出力フォーマット(日時、ログレベル、スレッド名、クラス名、メッセージ)
- ログファイルのローテーション方針(日次、サイズベース)
- 各業務処理で出力すべきログの内容とログレベル
- 個人情報のマスキングルール
障害調査の手順
本番環境で障害が発生した際、まず確認するのがログファイルである。ERROR レベルのログとスタックトレースを起点に、同一トランザクション内の INFO / DEBUG ログを時系列で追跡して原因を特定する。ログ出力が不十分だと原因究明に時間がかかるため、適切なログ設計は開発品質に直結する。
まとめ
- Java のログ出力は SLF4J(ファサード)+ Logback または Log4j2(実装)の組み合わせが標準
- ログレベル(ERROR, WARN, INFO, DEBUG, TRACE)を適切に使い分け、環境に応じて出力レベルを制御する
- SIer の現場ではログは障害調査・運用監視・監査証跡として極めて重要な位置づけにある
- Log4Shell の脆弱性を教訓に、依存ライブラリの脆弱性管理の重要性が再認識された
- 適切なログ設計(フォーマット、レベル、ローテーション)は開発品質に直結する