[英]How to make the `@Endpoint(id = “health”)` working in Spring Boot 2.0?
我已經嘗試了在Spring Boot 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>
Spring Boot配置application.properties
包含:
endpoints.health.enabled=true
endpoints.autoconfig.enabled=true
endpoints.autoconfig.web.enabled=true
新的端點ID必須是唯一的,並且不應與現有的執行器端點相同。 如果嘗試將下面顯示的示例的ID更改為health
,則會出現以下異常:
java.lang.IllegalStateException: Found two endpoints with the id 'health'
關於使用@Bean
注釋聲明端點類的@Bean
注釋是正確的。
health
端點沒有更改。 您仍然必須實現HealthIndicator
以添加自定義值。 以下是在Spring Boot 2.0中創建自定義Actuator端點所需的更改。
包含您的自定義信息的域。
@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MyHealth {
private Map<String, Object> details;
@JsonAnyGetter
public Map<String, Object> getDetails() {
return this.details;
}
}
聲明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;
}
}
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);
}
}
配置將兩個新創建的執行器類暴露為bean,
@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.yml
更改,
endpoints:
myhealth:
enabled: true
啟動應用程序后,您應該能夠訪問位於http://<host>:<port>/application/myhealth
的新執行器端點。
您應該期望類似於下面所示的響應,
{
"MyStatus": "is happy"
}
這里可以找到完整的工作示例。
提供你自己的@WebEndpoint
@Component
@WebEndpoint(id = "acmehealth")
public class AcmeHealthEndpoint {
@ReadOperation
public String hello() {
return "hello 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,而是定制現有的健康執行器”那種碰撞。 但是您可以在AcmeHealthEndpoint中使用現有的HealthEndpoint
並完成這兩項:
@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>";
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.