HttpClient SendAsync теряет информацию о протоколировании MDC

#java #completable-future #mdc #java-http-client

#java #завершаемый-будущее #mdc #java-http-клиент

Вопрос:

Я использую MDC Logger, который работает корректно везде, кроме случаев, когда я отправляю запрос с использованием HttpClient async. Данные MDC не передаются в следующий поток, и это означает, что их нет в наших журналах. Как я могу заставить новый поток иметь заголовки MDC?

  java.net.http.HttpClient.newHttpClient()
                .sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(restLogging::logResponse)
                .thenApply(response -> handleResponse(url, responseTypeClass, objectMapper, response));
 

Комментарии:

1. Скопируйте его в новый поток. Как вы заметили, MDC привязан к потоку, поэтому вам нужно будет его скопировать.

2. Как вы копируете ее в новый поток? Я видел примеры, когда у вас есть оболочка withMdc и вы используете ее как CompletableFuture.supplyAsync(withMdc(() -> , но в этом случае HttpClient.SendAsync — это тот, который создает CompletableFuture?

Ответ №1:

Контекст MDC необходимо распространить на метод async, поскольку он будет выполняться в разных потоках.

назовите это как

 java.net.http.HttpClient.newHttpClient()
            .sendAsync(request, HttpResponse.BodyHandlers.ofString())
            .thenApply(restLogging::logResponse)
            .thenApply(response -> handleResponse(url, responseTypeClass, objectMapper, response, MDC.getCopyOfContextMap()));
 

ниже приведена реализация:

 handleResponse(url, responseTypeClass, objectMapper, response, Map<String,String> mdcContextMap){
MDC.setContextMap(mdcContextMap);
//your business logic
MDC.clear(); }