RequestContextHolder for Reactive Web [SPR-15680]
See original GitHub issueDoron Gold opened SPR-15680 and commented
It is necessary to have a way to associate attributes with the current request and be able to fetch these attributes during the request lifetime.
The ability to set and get such attributes is essential for use-cases such as:
- Having a unique trace-id per request, which can be included in all log messages.
- Identifying the currently logged in user (the user associated with the request).
- In a micro-service architecture: receiving contextual data via request headers, then when calling other micro-services, pass the same contextual data that came with the original request.
In webmvc this is possible by calling a static methods on org.springframework.web.context.request.RequestContextHolder
. A developer could implement HandlerInterceptor which intercepts all incoming requests and sets contextual attributes on RequestContextHolder. These attributes are then accessible from anywhere in the code (via a static method) during the request lifetime.
Since in Reactive Web a request is not bound to a single processing thread, a simple use of ThreadLocal (what RequestContextHolder does) is not enough. The Spring framework should offer a more sophisticated solution.
A simple but extremely intrusive workaround would be to pass in ServerWebExchange to all methods in all components - starting from controller endpoints down to all services. But even if this is done, there is no good way to have a logger take attributes form the request (for the purpose of including trace/correlation ID) without implementing a wrapper around the logger class that receives an extra parameter.
Reference URL: https://stackoverflow.com/questions/43975761/how-to-get-the-context-of-the-current-request-in-spring-webflux
Issue Links:
- #21746 Create a WebFilter for ServerWebExchange Reactor Context
- #20108 Upgrade to Reactor 3.1 RC1 (including Reactive Streams 1.0.1)
19 votes, 34 watchers
Issue Analytics
- State:
- Created 6 years ago
- Comments:40 (1 by maintainers)
@scottjohnson @archie-swif please be aware that the context should remain as small as possible. Instead of adding a new key-value entry, you should simply add a new key that references a map. That is what is recommended in the JavaDocs of the Context.
So you need to do something like this:
Hi @ankitp-kr ,
I’m also trying to use
MdcContextLifter
proposed by @archie-swif , since unfortunately the approach recommended in https://projectreactor.io/docs/core/release/reference/#faq.mdc is not sufficient for my use case ( I need to produce some logging that come from internal libraries invoked within each operator, and I would like to have this libraries log the MDC variables as well)So I’ve opted for a similar approach as the one @archie-swif used, but using a closeable MDC for adding my correlationId, could you maybe try this to see if you get rid of the problem in where simultaneous invocations, one with correlation ID and one without it, would print same value?