Reputation: 2942
I need to have Mapped Diagnostic Context data in logs. Application build with:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
To get MDC in logs I put in application.properties file:
logging.pattern.level=%X{mdcData}%5p
and create a class
@Component
public class RequestFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
// Setup MDC data:
String mdcData = String.format("[userId:%s | requestId:%s] ", "hello", "hello");
MDC.put("mdcData", mdcData); //Variable 'mdcData' is referenced in Spring Boot's logging.pattern.level property
chain.doFilter(request, response);
} finally {
// Tear down MDC data:
// ( Important! Cleans up the ThreadLocal data again )
MDC.clear();
}
}
...
}
The MDC data appears in logs when I use method call like log.info("message here")
. I tried with levels INFO, WARN, ERROR - it is fine. But when I get RuntimeException in my controller, I see the stack trace in logs with ERROR level, but no MDC data provided.
What should I do to get MDC data in logs on exception thrown?
Upvotes: 5
Views: 4854
Reputation: 351
You may write a block catching
Exception before MDC.clear()
in order to log in doFilter
like below.
try {
// Setup MDC data:
String mdcData = String.format("[userId:%s | requestId:%s] ", "hello", "hello");
MDC.put("mdcData", mdcData); //Variable 'mdcData' is referenced in Spring Boot's logging.pattern.level property
chain.doFilter(request, response);
} catch (Exception e) {
log.error("", e);
} finally {
// Tear down MDC data:
// ( Important! Cleans up the ThreadLocal data again )
MDC.clear();
}
It changes logger from DirectJDKLog to RequestFilter.
Upvotes: 2