使用 SpringBootTest 时如何在控制器中使用 span 初始化默认跟踪上下文
Posted
技术标签:
【中文标题】使用 SpringBootTest 时如何在控制器中使用 span 初始化默认跟踪上下文【英文标题】:How to init a default trace context with span in controller when using SpringBootTest 【发布时间】:2020-09-22 02:47:02 【问题描述】:我正在从 Spring Boot 1.5.21 迁移到 2.2.5,并在此过程中从 spring-boot-cloud 版本 Edgware.SR6 迁移到 Hoxton.SR3。这一举动迫使我放弃了侦探自己的跟踪器/跨度模型实现,并接受了勇敢的新模型。但是,我的控制器集成测试存在问题。
我有一个名为 Edge
的微服务和一个名为 EdgeApplication
的主类,并且我使用 Spock 作为测试框架。
我的代码包括以下测试类:
@ContextConfiguration(classes = EdgeApplication.class)
@SpringBootTest(classes = EdgeApplication.class)
@ActiveProfiles(profiles = ["test"])
@AutoConfigureMockMvc
class VerificationCodeControllerSpecIT extends Specification
@Autowired
MockMvc mockMvc
def setup()
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build()
def "Generate change password verification code"()
// Some code calling a PrincipalController via mockMvc.perform()
之前,在 Spring Boot 1.5.21 中,当调用到达 PrincipalController
时,初始化了一个带有 span 的默认跟踪上下文。现在,在 Spring Boot 2 中,情况并非如此。我必须强调,PrincipalController
中缺少上下文只发生在测试代码中,而不是在微服务的实际运行中。
为什么这种行为发生了变化,我怎样才能恢复旧的行为,即当控制器被调用时有一个带有 span 的默认跟踪上下文?
我添加了一个演示项目:
Demo
您将能够运行集成测试并在调试中看到控制器中的tracer.currentSpan()
为空(同时包含正常项目运行的值)
【问题讨论】:
【参考方案1】:在 Spring Boot 1.5.21 中,spring-cloud-sleuth 支持的最新版本是 1.3.6.RELEASE。
在旧版本中,Sleuth 曾经有拦截器:'TraceHandlerInterceptor',用于在 Servlet 调度程序触发此拦截器时创建一个 span。
在 1.5.21 版运行 Spring Boot 测试时,触发上述拦截器的 MockMvc init TestDispatcherServlet。
作为与 Brave 对齐的 HTTP 检测的一部分,此拦截器已被删除。
使用 MockMvc 时,需要显式配置您的过滤器链。 您的 MockMvc 缺少 TracingFilter
【讨论】:
我尝试添加 TracingFilter 但显然我有另一个问题掩盖了(抛出相同的异常)过滤器问题。一旦我解决了屏蔽问题,当 TracingFilter 添加到 MockMvc 时,我就能够获取跟踪上下文。 将TracingFilter
显式添加到我的 MockMvc 对我来说是缺失的部分。谢谢@Tzachi ...你摇滚!【参考方案2】:
如果它与 Spring Security 相关,也许你应该使用 https://github.com/spring-projects/spring-security/blob/5.3.2.RELEASE/test/src/main/java/org/springframework/security/test/web/servlet/setup/SecurityMockMvcConfigurers.java 。示例:
MockMvcBuilders.webAppContextSetup(this.wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
【讨论】:
不幸的是这没有帮助,tracer.currentSpan()
仍然返回 null
我想我们需要一个样品然后检查一下
在原始问题中添加了演示项目。 10 倍。以上是关于使用 SpringBootTest 时如何在控制器中使用 span 初始化默认跟踪上下文的主要内容,如果未能解决你的问题,请参考以下文章
SpringBootTest - 如何在测试级别断言上下文不加载和更改属性?
如何模拟@springboottest 的应用程序配置或上下文?
使用 SpringBootTest 和 Autowired 注解时 LogCaptor 无法捕获