Closed sigriswil closed 1 month ago
I think someone from the Micrometer, Reactor or Spring Cloud team will need to help with this issue. Spring Boot isn't really involved at this level.
It looks to me like io.micrometer.context.DefaultContextSnapshotFactory.setAllThreadLocalsFrom
is clearing the MDC thread local.
@spencergibb @chemicL are you able to help identify what's causing the issue and which project can help?
I have no knowledge about Spring Cloud Gateway's lifecycle with the AbstractGatewayFilterFactory
but this situation where there is a global instance of ErrorWebExceptionHandler
sounds similar to the case encountered with Spring Framework where observability was added as a WebFilter
which was at a more internal layer than the catch-all ExceptionHandlingWebHandler
which is outside (check related discussion and fix). So MDC keys set in one AbstractGatewayFilterFactory
(FirstGatewayFilterFactory
) won't be visible to any filter that is ordered prior to it. I am certain @spencergibb is able to provide guidance :)
Regarding the comment of clearing thread locals: If these MDC entries were not cleared by the context-propagation then you'd face leaks from one request to another. The solution to the problem is proper ordering of call scopes and making sure things are properly cleared when exiting a scope and handling something unrelated.
Spring boot version: 3.3.2 Spring cloud dependencies version: 2023.0.3 sample issue spring cloud gateway repository: https://github.com/sigriswil/spring-gateway-sample
It contains a SpringBoot application that can be started locally. When reaching the endpoint /, it raises an exception which triggers the class GlobalErrorWebExceptionHandler which implements ErrorWebExceptionHandler.
In the main method,
Hooks.enableAutomaticContextPropagation()
andContextRegistry.getInstance().registerThreadLocalAccessor(...)
are called in FirstGatewayFilter.Add the MDC's trasactionId to the FirstGatewayFilter, An exception occurs in the SecondGatewayFilterFactory. transactionId is output from SecondGatewayFilterFactory and FirstGatewayFilter, but transactionId is not output from GlobalErrorWebExceptionHandler.