Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免在使用带有Spring Cloud Sleuth和MDC的baggage时进行手动清理?_Java_Spring_Spring Boot_Slf4j_Spring Cloud Sleuth - Fatal编程技术网

Java 如何避免在使用带有Spring Cloud Sleuth和MDC的baggage时进行手动清理?

Java 如何避免在使用带有Spring Cloud Sleuth和MDC的baggage时进行手动清理?,java,spring,spring-boot,slf4j,spring-cloud-sleuth,Java,Spring,Spring Boot,Slf4j,Spring Cloud Sleuth,我有几个基于SpringBoot+Sleuth2.1的微服务(A、B和C),它们从一个服务向另一个服务(A->B->C)发出HTTP请求。我正在使用Sleuth在应用程序之间传递附加参数“x-session-id”(baggage),作为HTTP请求头,并使用SLF4J将参数值记录在日志语句中。为此,我在application.yml中配置了: spring.sleuth: propagation-keys: - x-session-id log: slf4j:

我有几个基于SpringBoot+Sleuth2.1的微服务(A、B和C),它们从一个服务向另一个服务(A->B->C)发出HTTP请求。我正在使用Sleuth在应用程序之间传递附加参数“x-session-id”(baggage),作为HTTP请求头,并使用SLF4J将参数值记录在日志语句中。为此,我在application.yml中配置了:

spring.sleuth:
  propagation-keys:
    - x-session-id
  log:
    slf4j:
      whitelisted-mdc-keys: x-session-id 
在logback-spring.xml中,模式值为:

%d{HH:mm:ss.SSS} %-5level [xSessionId=%X{x-session-id:-},traceId=%X{X-B3-TraceId:-}] [%thread] %logger : %m%n
当我在外部设置HTTP头“x-session-id”时,一切都正常(因此我使用头x-session-id向A发出请求,并且该值自动从A传递到B,从B传递到C)。因此,该值在应用程序之间移动,并出现在每个应用程序的日志语句中

但是,当我在应用程序中生成x-session-id的值(比如在A中)并以编程方式将该值设置为Sleuth(而不是将其作为HTTP请求头传递)时,通常会将该头添加到传出请求中,但SLF4J不知道该值,日志语句也不会显示该值。这就是我如何让侦探意识到(I@Autowire tracer):

但是,当我像这样显式地将值传递给MDC时:

org.slf4.MDC.put("x-session-id", "mySession123");
然后,即使在请求完成之后,它仍然保留在线程中,我必须手动清理它。为此,我创建了单独的拦截器:

@Component
public class CleanupBaggageInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(CleanupBaggageInterceptor.class);

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) {
        logger.debug("Cleaning up any baggage that has manually been set to MDC");
        MDC.clear();
    }

}
并在应用程序中注册了拦截器:

@Configuration
public class MidGatewayConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CleanupBaggageInterceptor());
    }
}

是否有任何方法可以将行李值设置为Sleuth,而Sleuth本身会将其设置为MDC(并在请求后以与清除traceId相同的方式将其清除)?

由于您已将MDC添加为白名单密钥,因此每当范围关闭时,我们都会自动从MDC中删除条目。您是否调试了Slf4jScopeDecorator以确认正在发生这种情况?一般来说,答案是这样的:每当范围关闭时,我们都会清除所有mdc上下文,包括来自白名单键的条目

谢谢提示!Slf4jScopeDecorator调试表明,在请求开始时,whitelistedBaggageKeysWithValue和WhiteListedPagationKeysWithValue被存储(到以前的MDC列表中),在请求之后,只有那些(具有值的)被从MDC中删除。因为我没有将行李作为请求头传递(我在处理请求时设置了它),所以它最终不会被移除。我想知道我是否应该打开一个功能请求,以便在处理请求的过程中添加行李,从而在处理请求后将其清理干净。是的,为什么不呢。请创建一个问题,并用您的分析和预期结果描述您的问题。让我们在那里讨论:)太棒了。我提出了这个问题:让我们继续讨论。
@Configuration
public class MidGatewayConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CleanupBaggageInterceptor());
    }
}