如何测试traceId传播与WebTestClient +微米跟踪器?



迁移到Spring Boot 3并从Sleuth重构到Micrometer后,我不再能够使用WebTestClient + Tracer测试traceId传播。

我在这里的测试是有一个简单的@RestController,我希望traceId通过跟踪器传播:

@RestController
class MyTraceIdController(@Autowired private val tracer: Tracer) {

@GetMapping("/trace")
fun info(): ResponseEntity<String> {
val traceKey = "x-b3-traceid"
// Using tracer the traceId is retrieved at runtime but not during test
val responseHeaders = HttpHeaders()
responseHeaders.set(traceKey, tracer.currentSpan()?.context()?.traceId().toString())
return ResponseEntity
.ok()
.headers(responseHeaders)
.body("OK")
}
}

我们的目标是通过WebTestClient来测试它:

@AutoConfigureWebTestClient
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class MyTraceIdTests(@Autowired private val webTestClient: WebTestClient) {
@Test
fun `Assert info endpoint works as expected with webTestClient`() {
val traceKey = "x-b3-traceid"
val traceValue = "463ac35c9f6413ad48485a3953bb6124"
val spanKey = "x-b3-spanid"
val spanValue = "a2fb4a1d1a96d312"
webTestClient.get()
.uri("http://localhost:9080/trace")
.header(traceKey, traceValue)
.header(spanKey, spanValue)
.exchange()
.expectStatus().isOk
.expectHeader().valueEquals(traceKey, traceValue)
.expectBody<String>().isEqualTo("OK")
}
}

对于Sleuth,在运行测试时,注入的BraveTracer完美地完成了传播traceId的工作。

与Micrometer,我不能再有一个正确的示踪剂注入做这项工作。

为了测试这个案例,我创建了以下示例: https://github.com/bvoglevette/trace-id-sample

两个行为是可观察的:

在<<ul>
  • strong>运行时,在端点上执行boorun + curl,使用BraveAutoconfiguration并注入一个正确的BraveTracer =>按预期工作
  • 测试时间,我无法得到一个正确的BraveTracer bean注入=>traceId总是null
  • 我尝试过的不同方法都没有成功

    • 使用SimpleTracer()
    • 要实现我自己的Tracer bean,请遵循Micrometer文档
    • 在我的测试中使用BraveAutoconfiguration或基于它实例化bean

    这些实现都不能产生一个传播traceId的bean。

    我更希望找到一种方法来简单地注入来自BraveAutoconfiguration的工作bean。我错过了什么?我应该改变我的测试方式吗?

    您需要在您的测试类中添加@AutoConfigureObservability。默认情况下,测试中的可观察性是禁用的。

    我还将我的spring-web和spring-integration应用程序从spring boot 2 sleuth迁移到spring boot 3 with micrometer,也遇到了问题。我想手动配置跟踪,而且我没有访问所有模块中的执行器)。

    为了手动配置跟踪,除了普通的微米依赖,我需要添加这两个:微米跟踪-测试和微米跟踪-集成测试(注意:在大多数情况下,您可能只需要微米跟踪-测试):

    <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bom</artifactId>
    <version>${micrometer.version}</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>context-propagation</artifactId>
    <version>${micrometer.version}</version>
    </dependency>
    <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-test</artifactId>
    <version>${micrometer.version}</version>
    <scope>test</scope> (!)
    <exclusions>
    <exclusion>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-jre8-standalone</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-integration-test</artifactId>
    <version>${micrometer.version}</version>
    <scope>test</scope> (!)
    <exclusions>
    <exclusion>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-jre8-standalone</artifactId>
    </exclusion>
    <exclusion>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    </exclusion>
    </exclusions>
    </dependency>     
    

    之后,我提供了SimpleTracer bean来测试上下文(这是用于测试的Tracer实现)并手动设置观察注册表(TestObservationRegistry)。我用观察处理程序DefaultTracingObservationHandler配置了注册表,它委托给这个测试SimpleTracer:

    @Bean
    SimpleTracer simpleTracer() {
    return new SimpleTracer();
    }
    @Bean
    TestObservationRegistry observationRegistry(SimpleTracer tracer) {
    final TestObservationRegistry testObservationRegistry = TestObservationRegistry.create();
    testObservationRegistry.observationConfig().observationHandler(new DefaultTracingObservationHandler(tracer));
    
    return testObservationRegistry;
    }
    

    注意:如果在您的测试中,您得到如下的异常,那么您没有配置观察处理程序,即您的观察注册表不包含跟踪观察处理程序。在这种情况下,请尝试手动添加观察处理程序(参见上面的示例)。

    java.lang.IllegalArgumentException: Context does not have an entry for key [class io.micrometer.tracing.handler.TracingObservationHandler$TracingContext]
    at io.micrometer.observation.Observation$Context.getRequired(Observation.java:928)
    at micrometer.tracing@1.0.2/io.micrometer.tracing.handler.TracingAwareMeterObservationHandler.onStop(TracingAwareMeterObservationHandler.java:79)
    at io.micrometer.observation.ObservationHandler$FirstMatchingCompositeObservationHandler.lambda$onStop$7(ObservationHandler.java:173) 
    

    相关内容

    • 没有找到相关文章

    最新更新