【问题标题】:add custom baggage to current span and accessed by log MDC将自定义行李添加到当前跨度并由日志 MDC 访问
【发布时间】:2021-01-02 08:08:09
【问题描述】:

我正在尝试向 HTTP 服务器上的现有跨度添加额外的 Baggage,我想向跨度添加一个路径变量,以便从日志 MDC 访问并通过线路传播到我调用的下一个服务器http 或 kafka。

我的设置:spring cloud sleuth Hoxton.SR5 和 spring boot 2.2.5

我尝试添加以下设置和配置:

spring:
  sleuth:
    propagation-keys: context-id, context-type
    log:
      slf4j:
        whitelisted-mdc-keys: context-id, context-type

并添加了 http 拦截器:

public class HttpContextInterceptor implements HandlerInterceptor {

    
    private final Tracer tracer;
    private final HttpContextSupplier httpContextSupplier;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (httpContextSupplier != null) {
            addContext(request, handler);
        }
        return true;
    }

    private void addContext(HttpServletRequest request, Object handler) {
        final Context context = httpContextSupplier.getContext(request);
        if (!StringUtils.isEmpty(context.getContextId())) {
            ExtraFieldPropagation.set(tracer.currentSpan().context(), TracingHeadersConsts.HEADER_CONTEXT_ID, context.getContextId());
        }
        if (!StringUtils.isEmpty(context.getContextType())) {
            ExtraFieldPropagation.set(tracer.currentSpan().context(), TracingHeadersConsts.HEADER_CONTEXT_TYPE, context.getContextType());
        }
    }
}

和http过滤器影响当前跨度(根据spring docs)

public class TracingFilter extends OncePerRequestFilter {

    private final Tracer tracer;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(tracer.currentSpan())){
            filterChain.doFilter(request, response);
        }
    }
}

问题是日志不包含我的自定义上下文 ID、上下文类型,尽管在跨度上下文中看到它。

我错过了什么?

【问题讨论】:

    标签: spring-cloud-sleuth


    【解决方案1】:

    官方 Sleuth 2.0 -> 3.0 migration guide 中也描述了在当前跨度中刷新 MDC 的方法

    @Configuration
    class BusinessProcessBaggageConfiguration {
      BaggageField BUSINESS_PROCESS = BaggageField.create("bp");
    
      /** {@link BaggageField#updateValue(TraceContext, String)} now flushes to MDC */
      @Bean
      CorrelationScopeCustomizer flushBusinessProcessToMDCOnUpdate() {
        return b -> b.add(
            SingleCorrelationField.newBuilder(BUSINESS_PROCESS).flushOnUpdate().build()
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      类似问题Spring cloud sleuth adding tag 并回复https://stackoverflow.com/a/66554834

      对于某些上下文:这是来自Spring Docs。

      为了自动将行李值设置为 Slf4j 的 MDC,您必须使用允许的本地或远程键列表设置 spring.sleuth.baggage.correlation-fields 属性。例如。 spring.sleuth.baggage.correlation-fields=country-code 会将 country-code 行李的值设置为 MDC。

      请注意,从下一个下游跟踪上下文开始,额外的字段被传播并添加到 MDC。要在当前跟踪上下文中立即将额外字段添加到 MDC,请将字段配置为在更新时刷新。

      // configuration
      @Bean
      BaggageField countryCodeField() {
          return BaggageField.create("country-code");
      }
      
      @Bean
      ScopeDecorator mdcScopeDecorator() {
          return MDCScopeDecorator.newBuilder()
                  .clear()
                  .add(SingleCorrelationField.newBuilder(countryCodeField())
                          .flushOnUpdate()
                          .build())
                  .build();
      }
      
      // service
      @Autowired
      BaggageField countryCodeField;
      
      countryCodeField.updateValue("new-value");
      

      【讨论】:

      • 新版本的 sleuth 支持此功能。 Hoxton.SR5 使用 sleuth 2.2.4.RELEASE
      • 如果您无法升级 Spring Sleuth 版本并且无法使其在您使用的版本中运行,您仍然可以选择手动设置和清除 MDC。例如,尝试MDC.put("context-id", context-id)。这将在当前跨度中插入上下文 ID。
      猜你喜欢
      • 2021-08-02
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 2017-10-18
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多