[JAVA] Il semble que MDC peut être propagé entre les applications en utilisant le contexte avec Spring WebFlux.

Préface

Pour utiliser MDC avec Spring WebFlux, utilisez le contexte J'ai écrit sur l'histoire de la propagation de MDC entre les applications. Je vais. La connaissance de l'article ci-dessus est requise en termes de contenu.

L'histoire du pionnier

Sujet principal

Les microservices qui sont populaires de nos jours présentent diverses complications, dont l'une est le journal. Il existe une demande naturelle pour que la communication qui coule d'un système -> système B -> système C soit transformée en un seul journal plus tard, et diverses méthodes ont été utilisées pour résoudre ce problème. (Spring Sleuth, etc.)

De la même manière, il y avait une demande pour nous laisser prendre en charge diverses informations de débogage ensemble, et notre système était juste pris dedans.

Cette fois, je reprendrai l'une des méthodes introduites dans Passing Context with Spring Web Flux.

Code spécifique

Pour écrire brièvement ce que fait WebFilter, que je présenterai à partir de maintenant

--Pour la demande, j'ai obtenu tous les HttpHeaders avec le préfixe X-MDC-, j'ai enlevé le préfixe et l'ai mis dans le contexte. La valeur clé du contexte est la constante CONTEXT_MAP. --Pour la réponse, la valeur tirée de la constante CONTEXT_MAP est renvoyée avec le préfixe X-MDC-.

MdcHeaderFilter.java


import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;

import java.util.Map;

import static java.util.stream.Collectors.toMap;
import static jp.co.example.helper.LogHelper.*;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MdcHeaderFilter implements WebFilter {
  private static final String MDC_HEADER_PREFIX = "X-MDC-";

  @Override
  public Mono<Void> filter(
    ServerWebExchange ex,
    WebFilterChain chain) {
    ex.getResponse().beforeCommit(
      () -> addContextToHttpResponseHeaders(ex.getResponse())
    );

    return chain.filter(ex)
      .subscriberContext(
        ctx -> addRequestHeadersToContext(ex.getRequest(), ctx)
      );
  }

  private Context addRequestHeadersToContext(
    final ServerHttpRequest request,
    final Context context) {

    final Map<String, String> contextMap = request
      .getHeaders().toSingleValueMap().entrySet()
      .stream()
      .filter(x -> x.getKey().startsWith(MDC_HEADER_PREFIX))
      .collect(
        toMap(v -> v.getKey().substring(MDC_HEADER_PREFIX.length()),
          Map.Entry::getValue
        )
      );

    //Par exemple, si vous souhaitez mettre un cookie, vous pouvez le faire
    String cookie = request.getCookies().containsKey("EXAMPLE") ?
      request.getCookies().getFirst("EXAMPLE").getValue() : "none";
    contextMap.put("example-cookie", cookie);

    return context.put(CONTEXT_MAP, contextMap);
  }

  private Mono<Void> addContextToHttpResponseHeaders(
    final ServerHttpResponse res) {

    return Mono.subscriberContext().doOnNext(ctx -> {
      if (!ctx.hasKey(CONTEXT_MAP)) return;

      final HttpHeaders headers = res.getHeaders();
      ctx.<Map<String, String>>get(CONTEXT_MAP).forEach(
        (key, value) -> headers.add(MDC_HEADER_PREFIX + key, value)
      );
    }).then();
  }
}

C'est très simple à faire, mais c'est polyvalent. Il peut également être utilisé lorsque vous devez utiliser un certain cookie comme information utilisateur pour le débogage, comme notre système ~~ F ● ck ~~.

fin

Ne vous laissez pas prendre par la réponse que vous donnez à vos clients!

Recommended Posts

Il semble que MDC peut être propagé entre les applications en utilisant le contexte avec Spring WebFlux.
Vous utilisez le contexte pour utiliser MDC avec Spring WebFlux
Orienté objet qui peut être compris par les fées