Reputation: 11467
Using Spring web a simple OncePerRequestFilter
(see below) can maintain a request id for the span of the request.
Storing the generated request id in a request attribute, adding it to the logging MDC, and returning in a response header.
I understand the reactive webflux stack is completely different, so how should one tackle this?
I found https://github.com/spring-projects/spring-framework/issues/20239 but it is not clear what is now supported or not.
@Component
public class RequestIdFilter extends OncePerRequestFilter implements Ordered {
private static final String MDC_KEY = "requestId";
private static final String REQUEST_ATTRIBUTE_NAME = "requestId";
private static final String RESPONSE_HEADER_NAME = "X-Request-Id";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
var requestId = UUID.randomUUID().toString();
MDC.put(MDC_KEY, requestId);
request.setAttribute(REQUEST_ATTRIBUTE_NAME, requestId);
response.setHeader(RESPONSE_HEADER_NAME, requestId);
try {
filterChain.doFilter(request, response);
} finally {
MDC.remove(MDC_KEY);
}
}
@Override
public int getOrder() {
return requestIdProperties.getServerFilterOrder();
}
}
Upvotes: 7
Views: 8000
Reputation: 59141
You don't need a OncePerRequestFilter
implementation in WebFlux, as Filters are executed only once because request forwarding (like in Servlet) is not supported in WebFlux.
Now you can implement a WebFilter
that adds a requestId as a request attribute, pretty much like the version you're showing.
There are several things to pay attention to:
UUID.randomUUID()
is blockingThreadLocal
. See this blog post for now and keep an eye on this issue for more guidanceUpvotes: 5