将自定义行李添加到当前范围,并通过日志MDC访问

问题描述

我正在尝试向HTTP服务器上的现有范围中添加其他行李,我想向该范围中添加路径变量,以从日志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,FilterChain filterChain) throws servletexception,IOException {
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(tracer.currentSpan())){
            filterChain.doFilter(request,response);
        }
    }
}

问题,尽管日志在span上下文中可以看到,但日志中不包含我的自定义context-id,context-type。

我想念什么?

解决方法

类似问题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 会将国家代码行李的值设置为 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");