logback の MDC コンテキストを利用してログをカスタム データで強化するスプリング ブート Web アプリケーションがあります。「customKey」に関連付けられたカスタムデータを利用できるようにする次の実装があり、ログバック構成のログパターンに %X{customKey} を追加した後に適切にログに記録されます。
public class MDCFilter extends OncePerRequestFilter implements Ordered {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
try {
MDC.put("customKey", "someValue");
filterChain.doFilter(httpServletRequest, httpServletResponse);
} catch(Throwable t) {
LOG.error("Uncaught exception occurred", t);
throw t;
} finally {
MDC.remove("customKey");
}
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE - 4;
}
}
キャッチされない例外がスローされない限り、これは正常に機能します。これらを処理するために、コントローラーのアドバイスを用意しています。悲しいことに、MDC は既にクリーンアップされているため、コントローラーのアドバイスにログインしている間は使用できなくなりました。私が正しく理解している場合、春は HandlerExceptionResolverComposite を使用して責任のある ExceptionHandler を決定します-実装はそれ自体を最も低い優先順位で登録します-したがって、MDC が既にクリーンアップされた後に最後になります。
私の質問は次のとおりです。コントローラーのアドバイスにログインしている間も MDC を使用できるようにするには、フィルターをどのように登録すればよいですか?
1 つのオプションは、フィルターの finally ブロックから MDC.remove(...) 呼び出しを削除し、代わりに requestDestroyed メソッドで MDC のクリーンアップを行う ServletRequestListener を実装することだと思います。しかし、フィルターは複数の Web モジュールで使用されるため、ServletRequestListener が、エラーが発生しやすいと思われる MDCFilter と共に、すべての既存および将来のモジュールでも宣言されていることを確認する必要があります。さらに、MDC へのデータの追加を担当するフィルターがその削除も処理してくれるとよいと思います。