【log4j】ログの先頭へユニークなIDを付ける方法(NDC編)

java

複数リクエストを同時に処理するWebアプリケーションでは、jog4j等のログにリクエスト単位でユニークとなる固有IDのようなものを出力しないと、どれがどのログか迷子になってしまいます。

[スポンサーリンク]

今回は、log4jのNDCを使って、ログへリクエスト単位でユニークとなるIDを出力する方法を紹介します。
セッション単位でユニークとすることも可能ですが、リクエスト単位の方が実用的だと思います。

ログへユニークなIDを付けるメリット

検索エンジンからこのページへ来た人には必要ない説明だと思います。
が、念のため残しておきます。
(読み飛ばしてもOKです。)

複数リクエストがほぼ同時に処理された時のログ(サンプル)です。
識別するものがないので、どのリクエストがどのログに対応しているかなんて分かりません。

INFO : jp.co.sample.AAA - start
INFO : jp.co.sample.BBB - クラスをまたいでもUIDは引き継がれます
INFO : jp.co.sample.AAA - start
INFO : jp.co.sample.AAA - end
INFO : jp.co.sample.BBB - クラスをまたいでもUIDは引き継がれます
INFO : jp.co.sample.AAA - end

これも同じく、複数リクエストがほぼ同時に処理された時のログ(サンプル)です。
リクエストを識別するためのIDを入れてみましょう。
これであれば、どのリクエストがどのログか対応させることが可能になりました。
今回は、この[UID:111]を付ける方法を紹介します。

[UID:111] INFO : jp.co.sample.AAA - start
[UID:111] INFO : jp.co.sample.BBB - クラスをまたいでもUIDは引き継がれます
[UID:222] INFO : jp.co.sample.AAA - start
[UID:111] INFO : jp.co.sample.AAA - end
[UID:222] INFO : jp.co.sample.BBB - クラスをまたいでもUIDは引き継がれます
[UID:222] INFO : jp.co.sample.AAA - end

NDCへユニークなIDをセットする方法

javaソース側と、log4j設定ファイル、2箇所へ仕組みを仕込む必要があります。
まずは、javaソース側から見ていきましょう。

javaソース

3行目で、ユニークなIDを生成しています。(ここではミリ秒をユニークIDとしています。)
4行目で、NDCへプッシュしています。
java側はこれでOKです。

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
    long uid = System.currentTimeMillis();
    NDC.push(String.valueOf(uid));
    
    logger.info("start");
    logger.info("クラスをまたいでもUIDは引き継がれます");
    logger.info("end");
}

log4j設定ファイル

では、続いてlog4j設定ファイルへ仕込みを入れていきましょう。
log4jの設定は、ユニークなIDを出力したい箇所へ%xを入れるだけです。

<layout class="org.apache.log4j.PatternLayout">
	<param name="ConversionPattern" value="%-5p: %c - %m%n &#91;UID:%x&#93;" />
</layout>

実行結果

Webアプリへアクセスするたび、リクエスト単位でユニークなIDがログの先頭に付くようになります。

>実行結果
[UID:111] INFO : jp.co.sample.AAA - start
[UID:111] INFO : jp.co.sample.BBB - クラスをまたいでもUIDは引き継がれます
[UID:111] INFO : jp.co.sample.AAA - end

さいごに

NDCへのプッシュは、filterクラスのような、全てのリクエストが必ず通過する共通クラスに記述するようにしましょう。

エラー発生時にアラートメールを飛ばすようなシステムであれば、ログに出力するユニークIDをアラートメールの一部に入れておくのも便利かと思います。
それでは!