如何使`@Endpoint(ID =“健康”)`春季启动2.0的工作?

问题描述 投票:4回答:2

我曾尝试定制春季启动2.0.0.M5健康器的新方法,如下所述:https://spring.io/blog/2017/08/22/introducing-actuator-endpoints-in-spring-boot-2-0

@Endpoint(id = "health")
public class HealthEndpoint {
    @ReadOperation
    public Health health() {
        return new Health.Builder()
            .up()
            .withDetail("MyStatus", "is happy")
            .build();
    }
}

然而,当我运行HTTP GET到localhost:port/application/health,我仍然得到标准的默认健康信息。我的代码被完全忽略。

当我使用通过实施HealthIndicator的定制健康信息的“传统方式”,它将按预期工作,健康信息装饰用给定的细节:

@Component
public class MyHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        return new Health.Builder()
            .up()
            .withDetail("MyStatus 1.1", "is happy")
            .withDetail("MyStatus 1.2", "is also happy")
            .build();
    }
}

问:还有什么要我配置和/或执行,以使@Endpoint(id = "health")解决方案的工作?

我的目的不是创建一个自定义驱动器myhealth,但定制现有health器。基于文档我预计达到相同的结果通过实施HealthIndicator。我错在这样的假设?


Maven配置pom.xml包含:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.M5</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

春季引导配置application.properties包含:

endpoints.health.enabled=true
endpoints.autoconfig.enabled=true
endpoints.autoconfig.web.enabled=true
java spring spring-boot spring-boot-actuator
2个回答
5
投票

更新

  • 在新的弹簧操动端点documentation也不是很清晰。它试图解释与现有的端点健康,例如新的端点的基础设施。
  • 新的端点ID必须是唯一的,不应该与现有的驱动器的端点。如果一个人试图改变下面的例子中的ID health,一会出现以下情况例外: java.lang.IllegalStateException: Found two endpoints with the id 'health'
  • 上述关于与@Bean注释声明端点类的评论是正确的。
  • 定制health终点在春季启动2.0并没有改变。你还必须实现HealthIndicator添加自定义值。

自选启动器端点

下面是在春季启动2.0创建自定义的执行机构端点所需要的变化。

Model

包含自定义信息的域。

@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MyHealth {

    private Map<String, Object> details;

    @JsonAnyGetter
    public Map<String, Object> getDetails() {
        return this.details;
    }
}

My Health Endpoint

声明myhealth端点,

@Endpoint(id = "myhealth")
public class MyHealthEndpoint {

    @ReadOperation
    public MyHealth health() {
        Map<String, Object> details = new LinkedHashMap<>();
        details.put("MyStatus", "is happy");
        MyHealth health = new MyHealth();
        health.setDetails(details);

        return health;
    }
}

My Health Extension

扩展为myhealth端点,

@WebEndpointExtension(endpoint = MyHealthEndpoint.class)
public class MyHealthWebEndpointExtension {

    private final MyHealthEndpoint delegate;

    public MyHealthWebEndpointExtension(MyHealthEndpoint delegate) {
        this.delegate = delegate;
    }

    @ReadOperation
    public WebEndpointResponse<MyHealth> getHealth() {
        MyHealth health = delegate.health();
        return new WebEndpointResponse<>(health, 200);
    }
}

Actuator Configuration

配置揭露两个新创建的驱动器类如豆类,

@Configuration
public class ActuatorConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    public MyHealthEndpoint myHealthEndpoint() {
        return new MyHealthEndpoint();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    @ConditionalOnBean({MyHealthEndpoint.class})
    public MyHealthWebEndpointExtension myHealthWebEndpointExtension(
            MyHealthEndpoint delegate) {
        return new MyHealthWebEndpointExtension(delegate);
    }
}

Application Properties

更改application.yml

endpoints:
  myhealth:
    enabled: true

一旦你开始你的应用程序,你应该能够在http://<host>:<port>/application/myhealth访问新执行器终点。

您应该会类似于下图之一的响应,

{
  "MyStatus": "is happy"
}

一个完整的工作的例子可以发现here


-2
投票

提供自己的@WebEndpoint

@Component
@WebEndpoint(id = "acmehealth")
public class AcmeHealthEndpoint {

    @ReadOperation
    public String hello() {
      return "hello health";
    }
}

  1. 包括它
  2. 地图原来/health,比方说,/internal/health
  3. 地图自定义端点/health

通过application.properties

management.endpoints.web.exposure.include=acmehealth
management.endpoints.web.path-mapping.health=internal/health
management.endpoints.web.path-mapping.acmehealth=/health

这将覆盖/health彻底,不只是将信息添加到现有的/health,为自定义HealthIndicator会。问题是,你想要什么,因为@Endpoint(id = "health")和“我的目的不是创建一个自定义驱动器myhealth,但定制现有的医疗器”之类的碰撞中。但是你可以使用现有的HealthEndpoint在AcmeHealthEndpoint,完成两个:

@Component
@WebEndpoint(id = "prettyhealth")
public class PrettyHealthEndpoint {

    private final HealthEndpoint healthEndpoint;
    private final ObjectMapper objectMapper;

    @Autowired
    public PrettyHealthEndpoint(HealthEndpoint healthEndpoint, ObjectMapper objectMapper) {
        this.healthEndpoint = healthEndpoint;
        this.objectMapper = objectMapper;
    }

    @ReadOperation(produces = "application/json")
    public String getHealthJson() throws JsonProcessingException {
        Health health = healthEndpoint.health();
        ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
        return writer.writeValueAsString(health);
    }

    @ReadOperation
    public String prettyHealth() throws JsonProcessingException {
        return "<html><body><pre>" + getHealthJson() + "</pre></body></html>";
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.