12

I have a spring-boot web application which makes use of logback's MDC context to enrich the log with custom data. I have the following implementation in place which makes available some custom data associated with "customKey" and it properly gets logged after adding %X{customKey} to the logging pattern in the logback configuration:

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;
    }
}

This works fine as long as no uncaught exceptions are being thrown. To handle these I have a controller advice in place. Sadly the MDC is not available during logging in the controller advice anymore since it has already been cleaned up. If I understand correctly spring determines the responsible ExceptionHandler by using the HandlerExceptionResolverComposite - implementation which registers itself with the lowest precedence - hence it comes last after the MDC has already been cleaned up.

My qurestion now is: How should I register my filter so that the MDC is still available during logging in the controller advice?

I think one option would be to remove the MDC.remove(...) call from the finally block of the filter and instead implement a ServletRequestListener which does the cleanup of the MDC in the requestDestroyed - method. But since the filter is used in multiple web modules I would need to make sure that the ServletRequestListener is also declared in every existing and prospective module along with the MDCFilter which seems kind of error-prone to me. Moreover I would prefer it if the filter responsible for adding data to the MDC also takes care of its removal.

jimonthebarn
  • 710
  • 9
  • 24
  • I know this is an old question, but did you get any further insight on this? I'm hitting the same problem. Furthermore, the HttpServletResponse status is always 200 in this filter when an unchecked exception is thrown. – Noky Dec 11 '18 at 21:04
  • Just create the `MDCFilter` as a `@Component` or a `@Bean` and MDC would be available in the controller advice. – Jitendra Kumar Sep 02 '22 at 15:52

0 Answers0