10

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 へのデータの追加を担当するフィルターがその削除も処理してくれるとよいと思います。

4

0 に答える 0