(更新:我的问题似乎与this one https://stackoverflow.com/q/55146885/4506703,但没有有效的答案。)
我正在尝试登录 Spring BootErrorController
,但它的日志没有 MDC 值。
@Controller
@RequestMapping("/error")
@RequiredArgsConstructor
@Slf4j
public class MyErrorController implements ErrorController {
private final ErrorAttributes errorAttributes;
@Override
public String getErrorPath() {
return null;
}
@RequestMapping
@ResponseBody
public Map<String, String> error(final HttpServletRequest request) {
final ServletWebRequest webRequest = new ServletWebRequest(request);
final Throwable th = errorAttributes.getError(webRequest);
if (th != null) {
// **Logged without "requestId" value**
log.error("MyErrorController", th);
}
return Map.of("result", "error");
}
}
// http://logback.qos.ch/manual/mdc.html#autoMDC
public class MDCFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain)
throws ServletException, IOException {
final String requestId = UUID.randomUUID().toString();
MDC.put("requestId", requestId);
try {
filterChain.doFilter(request, response);
} finally {
MDC.remove("requestId");
}
}
}
@Configuration
public class MyConfig {
@Bean
public FilterRegistrationBean<MDCFilter> mdcFilter() {
final FilterRegistrationBean<MDCFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new MDCFilter());
bean.addUrlPatterns("/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}
logback-spring.xml
:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] requestId:%X{requestId} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
result(requestId
值不出现):
18:15:13.705 [http-nio-8080-exec-1] requestId: ERROR c.e.l.MyErrorController - MyErrorController
java.lang.RuntimeException: Error occured.
...
这是完整的代码 https://github.com/yukihane/logging-with-mdc-demo.
我认为我需要适应MDCFilter
before DispatcherServlet
,但我不知道该怎么做。