(Multipost with Stack Overflow)
We would like to give you a unique value for Spring Boot log output on a per-request basis.
For this purpose, we implemented the Logback MDC with reference to Example 7.5 in as described below.
I think one of the countermeasures is to leave it alone without remove
.
It's certainly not very well behaved to keep information that's no longer valid, but in fact, the thread that processed this user request will be reused in the near future to process another user request.
It will be overwritten with valid information at that time, so it is unlikely that any actual damage will occur.
I was asked if I had to clear the MDC every time I requested it.It may be helpful for your consideration:
We followed up and found that the ErrorController
was running from Tomcat's StandardHostValve#invoke()
.
Called by throwable(request, response, t);
in the following quote:
final class StandardHostValve extensionsValveBase{
...
@ Override
public final void invoke (Request request, Response response)
US>throws IOException, ServletException{
...
// Look for (and render if found) an application level error page
if(response.isErrorReportRequired()){
// If an error has occurred that events further I/O, don't waste time
// producing an error report that will never be read
AtomicBoolean result=new AtomicBoolean(false);
response.getCoyoteResponse().action(ActionCode.IS_IO_ALLOWED, result);
if(result.get()){
if(t!=null){
throwable(request, response, t); // **This is where ErrorController is called**
} else{
status(request, response);
}
}
}
if(!request.isAsync()&&!asyncAtStart){
context.fireRequestDestroyEvent(request.getRequest());
}
...
}
...
}
After that, you can see that context.fireRequestDestroyEvent(request.getRequest());
is called.
I think I should just pick up this event and clear the MDC.
To receive this event, implement and register ServletRequestListener
:
public class MDCClearListener implements ServletRequestListener{
@ Override
public void requestDestroyed(final ServletRequestEventsre) {
MDC.remove("requestId");
}
}
@Bean
public servletListenerRegistrationBean<MDCClearListener>mdcClearListener(){
final ServletListenerRegistrationBean<MDCClearListener>bean=new ServletListenerRegistrationBean<();
bean.setListener(new MDCClearListener());
bean.setOrder (ordered.HIGHEST_PRECEDENCE);
return bean;
}
After performing the above implementation, we were able to get the desired result ("requestId:
" followed by the UUID):
22:09:19.294 [http-nio-8080-exec-1] requestId: 82debc7b-5834-49d1-aba7-738c8b50d581 ERROR c.e.l.MyErrorController-MyErrorController
java.lang.RuntimeException: Error occurred.
...
(The full code can be found in the solution
branch in the same repository.)
I would like to evaluate this as a similar question with new answers.
In conclusion, I don't think it's a very appropriate method.
The first method is to handle errors by @ExceptionHandler
instead of ErrorController
.
This is available for error handling of Spring MVC; otherwise, for example, Spring Security cannot be handled.
You can try behavior with the answer/exceptionhandler-with-springsecurity
branch.
Also, there are people who explain the mechanism of error handling around here:
The second method is to use an interceptor.
This method overrides the MDC each Controller call.In other words, the ID printed by MyErrorController
is no longer the "Request ID" (even if the request is the same, a different UUID will be dumped).
You can try with answer/interceptor
branch.
© 2024 OneMinuteCode. All rights reserved.