Javaロギングの基礎とベストプラクティス:標準APIから実践まで
Javaロギングの基礎
Javaロギングの仕組みと主要コンポーネントを例を交えて解説します。
Javaではロギングのプロセスを通じて、ログメッセージやファイルの作成・取得が可能です。
JavaでのロギングにはフレームワークとAPIが必要です。Javaにはjava.util.loggingパッケージに組み込みのロギングフレームワークがあります。
Log4j、Logbackなどのサードパーティフレームワークも利用できます。
Javaロギングのコンポーネント
下図はJava Logging API(java.util.logging)のコアコンポーネントと制御フローを表しています。

1. Logger
Loggerクラスはロギング用のメソッドを提供します。Loggerオブジェクトをインスタンス化し、そのメソッドを呼び出してロギングを行います。
例を見てみましょう:
Logger logger = Logger.getLogger("newLoggerName");
LoggerクラスのgetLogger()メソッドは、指定名のLoggerを検索または新規作成します。文字列引数がロガー名になります。
これにより、同名の既存Loggerが返されるか、新しいLoggerが作成されます。
慣習として、現在のクラス名を使ってLoggerを定義します:
Logger logger = Logger.getLogger(MyClass.class.getName());
注意:渡された名前がnullの場合、NullPointerExceptionがスローされます。
各Loggerにはレベルがあり、ログメッセージの重要度を決定します。基本のログレベルは7つあります:
| ログレベル(重要度降順) | 用途 |
|---|---|
| SEVERE | 重大な失敗 |
| WARNING | 警告メッセージ、潜在的な問題 |
| INFO | 一般的な実行時情報 |
| CONFIG | 設定情報 |
| FINE | 開発者向け一般情報(トレースメッセージ) |
| FINER | 開発者向け詳細情報(トレースメッセージ) |
| FINEST | 開発者向け極めて詳細な情報(トレースメッセージ) |
| OFF | すべてのレベルでロギングを無効化(何も取得しない) |
| ALL | すべてのレベルでロギングを有効化(すべて取得) |
各ログレベルには重要度を表す整数値がありますが、特別なレベルOFFとALLを除きます。
ログメッセージの出力
デフォルトでは上位3レベル(SEVERE、WARNING、INFO)が常にログ出力されます。別のレベルを設定するには:
logger.setLevel(Level.LogLevel); // 例 logger.setLevel(Level.FINE);
この例では、FINEレベルとそれより上のレベルのみがログ出力され、それ以外は破棄されます。
メッセージをログ出力するにはlog()メソッドを使います:
logger.log(Level.LogLevel, "log message"); // 例 logger.log(Level.INFO, "This is INFO log level message");
各レベル用のショートハンドメソッドも用意されています:
logger.info("This is INFO log level message"); logger.warning("This is WARNING log level message");
設定されたログレベルを通過したすべてのログリクエストはLogRecordに転送されます。
注意:ロガーのレベルがnullの場合、親から継承され、ツリーの上方向へと継承されます。
2. フィルタ
フィルタ(存在する場合)は、LogRecordを転送すべきかどうかを判断します。名前の通り、特定の基準に従ってログメッセージをフィルタリングします。
LogRecordは、ロガーからログハンドラへ、さらにハンドラから外部システムへと、指定基準をパスした場合のみ渡されます。
// フィルタの設定 logger.setFilter(filter); // フィルタの取得 Filter filter = logger.getFilter();
3. ハンドラ(アペンダ)
ログハンドラまたはアペンダはLogRecordを受け取り、さまざまなターゲットに出力します。
Java SEには5つの組み込みハンドラがあります:
| ハンドラ | 用途 |
|---|---|
StreamHandler | OutputStreamに書き込み |
ConsoleHandler | コンソールに書き込み |
FileHandler | ファイルに書き込み |
SocketHandler | リモートTCPポートに書き込み |
MemoryHandler | メモリに書き込み |
ハンドラはLogRecordをフィルタに渡し、外部システムへ転送すべきか再判断できます。
ハンドラを追加するには:
logger.addHandler(handler); // 例 Handler handler = new ConsoleHandler(); logger.addHandler(handler);
ハンドラを削除するには:
logger.removeHandler(handler); // 例 Handler handler = new ConsoleHandler(); logger.addHandler(handler); logger.removeHandler(handler);
ロガーは複数のハンドラを持てます。すべてのハンドラを取得するには:
Handler[] handlers = logger.getHandlers();
4. フォーマッタ
ハンドラはFormatterを使ってLogRecordオブジェクトを文字列にフォーマットしてから外部システムに出力できます。
Java SEには2つの組み込みフォーマッタがあります:
| フォーマッタ | 用途 |
|---|---|
SimpleFormatter | LogRecordを文字列にフォーマット |
XMLFormatter | LogRecordをXML形式にフォーマット |
ハンドラをフォーマットするには:
// 文字列形式にフォーマット handler.setFormatter(new SimpleFormatter()); // XML形式にフォーマット handler.setFormatter(new XMLFormatter());
LogManager
LogManagerオブジェクトはグローバルなロギング情報を管理します。ロギング設定とロガーインスタンスを読み取り、維持します。
ログマネージャはシングルトンであり、インスタンスは1つだけ存在します。
ログマネージャインスタンスを取得するには:
LogManager manager = LogManager.getLogManager();
ロギングの利点
Javaにおけるロギングの主な利点:
- プログラムの実行フローの監視に役立つ
- 発生しうるエラーの取得に役立つ
- 問題診断とデバッグをサポート
Java
- Javaロギングのマスターガイド:信頼性の高いコードのための必須ベストプラクティス
- Java演算子をマスター:種類、構文、実践例
- Javaコメント:種類、使い方、ベストプラクティス
- Java拡張forループをマスター:構文、例、ベストプラクティス
- Java文字列をマスター:生成、メソッド、ベストプラクティス
- Javaインターフェース完全ガイド:概念、実装、ベストプラクティス
- Java無名インナークラス完全ガイド:定義、構文、実践例
- Javaのtry-with-resourcesをマスターする:自動リソース管理の仕組みと活用法
- Javaアノテーション完全ガイド:種類、配置場所、実践例
- Javaアサーション完全ガイド:バグ早期発見とコード信頼性の向上
- Java Vectorの理解:使い方、特徴、ArrayListとの比較