@SpringbootTest 中缺少 /actuator/prometheus

Posted

技术标签:

【中文标题】@SpringbootTest 中缺少 /actuator/prometheus【英文标题】:/actuator/prometheus missing in @SpringbootTest 【发布时间】:2021-03-29 07:42:03 【问题描述】:

我使用的是 springboot 2.4.0,并添加了以下依赖项以启用 prometheus 指标:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

然后在我的 application.properties 我有以下属性

management.endpoints.web.exposure.include=*
management.metrics.enable.all=true

我正在尝试运行一个简单的集成测试,以查看我的自定义指标出现在 /actuator/prometheus 端点上。代码下方

package com.example.demo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import static io.restassured.RestAssured.given;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest 

  @LocalServerPort
  private int port;

  private String baseUrl;

  @BeforeEach
  public void setup() 
      baseUrl = "http://localhost:" + port;
  

  @Test
  public void metricsEndpoint() throws Exception 

    given().when().get(baseUrl + "/demo/actuator/prometheus")
            .then()
            .statusCode(200);
    

我在这里得到的错误是

java.lang.AssertionError: 1 expectation failed.
Expected status code <200> but was <404>.

如果我对 springboot 执行器提供的任何其他端点重复相同的请求,我会正确地得到响应,例如我尝试了 /actuator/health、/actuator/info、/actuator/metrics 等。

这仅在使用 @Springboot 注释的集成测试期间发生,这很奇怪,因为如果我运行我的应用程序并使用邮递员向地址 localhost:8080/actuator/prometheus 发出请求,我会正确地得到响应。

就像在测试期间没有加载 prometheus 注册表一样。

谁能帮忙?

提前致谢。

编辑:解决方案是 Johannes Klug 建议的解决方案。添加注释@AutoConfigureMetrics 解决了我的问题

【问题讨论】:

这个引用的答案也解决了我的问题!它应该被标记为接受的答案 【参考方案1】:

Spring Boot 2.4.1 也发生在我身上

我唯一能想到的是,@SpringBootTest 中包含的端点正在使用@Endpoint 注释。

例如:

@Endpoint(id = "metrics")
public class MetricsEndpoint 

@Endpoint(id = "loggers")
public class LoggersEndpoint 

prometheus 端点正在使用@WebEndpoint 注解

@WebEndpoint(id = "prometheus")
public class PrometheusScrapeEndpoint 

我没有找到它是否应该这样工作,或者是一个可能的错误

【讨论】:

【参考方案2】:

我遇到了同样的问题。通过 spring-context ConditionEvaluator 进行一些跟踪后,我发现PrometheusMetricsExportAutoConfiguration 上新引入的@ConditionalOnEnabledMetricsExport("prometheus") 条件阻止了端点加载。

这是由于 https://github.com/spring-projects/spring-boot/pull/21658 而导致的预期行为,并影响 spring-boot 2.4.x

修复: 将 @AutoConfigureMetrics 添加到您的测试中

@AutoConfigureMetrics
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IntegrationTest 

【讨论】:

非常感谢,这解决了问题! 太好了,拯救了我的星期五! 谢谢,这拯救了我的一天! 伙计,这个答案你真棒!【参考方案3】:

我在您的测试中看到,您在实际执行器路径之前附加了“演示”。

given().when().get(baseUrl + "/demo/actuator/prometheus")
        .then()
        .statusCode(200);

正确的url应该是baseUrl+"/actuator/prometheus"。

【讨论】:

以上是关于@SpringbootTest 中缺少 /actuator/prometheus的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot Test 失败说,由于缺少 ServletWebServerFactory bean,无法启动 ServletWebServerApplicationContext

使用@SpringBootTest时如何在测试类中自动装配bean

Kotlin - 如何在 springBootTest 中管理 @BeforeClass 静态方法

找不到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)

如何使用@SpringBootTest 验证作业是不是运行了另一个作业

从“@WebFluxTest”迁移到“@SpringBootTest”后,集成测试中的连接被拒绝