J'ai référencé avec le billet de blog Journalisation contextuelle avec Reactor Context et MDC mais je ne sais pas comment accéder au contexte du réacteur dans WebFilter.
@Component
public class RequestIdFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
List<String> myHeader = exchange.getRequest().getHeaders().get("X-My-Header");
if (myHeader != null && !myHeader.isEmpty()) {
MDC.put("myHeader", myHeader.get(0));
}
return chain.filter(exchange);
}
}
Vous pouvez faire quelque chose de similaire à ci-dessous, vous pouvez définir le context
avec n'importe quelle classe que vous aimez, pour cet exemple, je viens d'utiliser des en-têtes - mais une classe personnalisée fera très bien l'affaire. Si vous le définissez ici, alors toute journalisation avec des gestionnaires, etc. aura également accès à context
.
Le logWithContext
ci-dessous, définit le MDC et l'efface ensuite. Évidemment, cela peut être remplacé par tout ce que vous aimez.
public class RequestIdFilter implements WebFilter {
private Logger LOG = LoggerFactory.getLogger(RequestIdFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
HttpHeaders headers = exchange.getRequest().getHeaders();
return chain.filter(exchange)
.doAfterSuccessOrError((r, t) -> logWithContext(headers, httpHeaders -> LOG.info("Some message with MDC set")))
.subscriberContext(Context.of(HttpHeaders.class, headers));
}
static void logWithContext(HttpHeaders headers, Consumer<HttpHeaders> logAction) {
try {
headers.forEach((name, values) -> MDC.put(name, values.get(0)));
logAction.accept(headers);
} finally {
headers.keySet().forEach(MDC::remove);
}
}
}