直接访问 Spring 引导执行器运行状况 beans/data?
Direct access to Spring Boot Actuator Health beans/data?
是否可以从 Sprig Boot 应用程序直接访问 actuator/health 数据而不进行 rest 调用和解析结果?
理想情况下,我可以自动装配一个 bean,然后能够通过方法调用获取健康数据的对象表示。
例如,如果我的健康端点显示如下内容:
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"database": "PostgreSQL",
"result": 1,
"validationQuery": "SELECT 1"
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 499963174912,
"free": 389081399296,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
},
"redis": {
"status": "UP",
"details": {
"version": "3.2.12"
}
}
}
}
那么我可以自动装配哪些组件来找出这些信息中的每一个?
当然可以注入Endpoint
。例如,如果您对 HealthEndpoint
感兴趣,您可以这样做:
@RestController
public class ActuatorController {
private final HealthEndpoint healthEndpoint;
public ActuatorController(HealthEndpoint healthEndpoint) {
this.healthEndpoint = healthEndpoint;
}
@GetMapping("health")
public String health() {
return healthEndpoint.health().getStatus().getCode();
}
}
此外,默认情况下,信息和健康点在执行器中启用,您无需手动公开它们。当您将依赖项添加到 pom.xml 时,它将被启用,您可以访问 url 端点而不公开它们
可能有更好的方法来获取健康数据,但这对我有用。
@RestController
public class HealthController {
@Autowired
HealthContributor[] healthContributors;
@GetMapping("/health")
public Map<String, String> health() {
Map<String, String> components = new HashMap<String, String>();
for(HealthContributor healthContributor : healthContributors) {
String componentName = healthContributor.getClass().getSimpleName().replace("HealthIndicator", "").replace("HealthCheckIndicator", "");
String status = ((HealthIndicator)(healthContributor)).health().getStatus().toString();
//To get details
//Map<String,Object> details = ((HealthIndicator)(healthContributor)).health().getDetails();
components.put(componentName, status);
}
return components;
}
}
示例输出:
{
"Mail":"UP",
"Ping":"UP",
"Camel":"UP",
"DiskSpace":"UP"
}
要模拟 HealthContributor[],您可以尝试像下面这样使用 Mockito:
@Profile("test")
@Configuration
public class HealthContributorsMockConfig {
@Primary
@Bean(name = "healthContributors")
public HealthContributor[] healthContributors() {
HealthContributor[] healthContributors = new HealthContributor[2];
HealthContributor healthContributorA = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// TODO Auto-generated method stub
Health health = Health.up().build();
return health;
}
});
HealthContributor healthContributorB = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// TODO Auto-generated method stub
Health health = Health.down().build();
return health;
}
});
healthContributors[0] = healthContributorA;
healthContributors[1] = healthContributorB;
return healthContributors;
}
}
是否可以从 Sprig Boot 应用程序直接访问 actuator/health 数据而不进行 rest 调用和解析结果?
理想情况下,我可以自动装配一个 bean,然后能够通过方法调用获取健康数据的对象表示。
例如,如果我的健康端点显示如下内容:
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"database": "PostgreSQL",
"result": 1,
"validationQuery": "SELECT 1"
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 499963174912,
"free": 389081399296,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
},
"redis": {
"status": "UP",
"details": {
"version": "3.2.12"
}
}
}
}
那么我可以自动装配哪些组件来找出这些信息中的每一个?
当然可以注入Endpoint
。例如,如果您对 HealthEndpoint
感兴趣,您可以这样做:
@RestController
public class ActuatorController {
private final HealthEndpoint healthEndpoint;
public ActuatorController(HealthEndpoint healthEndpoint) {
this.healthEndpoint = healthEndpoint;
}
@GetMapping("health")
public String health() {
return healthEndpoint.health().getStatus().getCode();
}
}
此外,默认情况下,信息和健康点在执行器中启用,您无需手动公开它们。当您将依赖项添加到 pom.xml 时,它将被启用,您可以访问 url 端点而不公开它们
可能有更好的方法来获取健康数据,但这对我有用。
@RestController
public class HealthController {
@Autowired
HealthContributor[] healthContributors;
@GetMapping("/health")
public Map<String, String> health() {
Map<String, String> components = new HashMap<String, String>();
for(HealthContributor healthContributor : healthContributors) {
String componentName = healthContributor.getClass().getSimpleName().replace("HealthIndicator", "").replace("HealthCheckIndicator", "");
String status = ((HealthIndicator)(healthContributor)).health().getStatus().toString();
//To get details
//Map<String,Object> details = ((HealthIndicator)(healthContributor)).health().getDetails();
components.put(componentName, status);
}
return components;
}
}
示例输出:
{
"Mail":"UP",
"Ping":"UP",
"Camel":"UP",
"DiskSpace":"UP"
}
要模拟 HealthContributor[],您可以尝试像下面这样使用 Mockito:
@Profile("test")
@Configuration
public class HealthContributorsMockConfig {
@Primary
@Bean(name = "healthContributors")
public HealthContributor[] healthContributors() {
HealthContributor[] healthContributors = new HealthContributor[2];
HealthContributor healthContributorA = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// TODO Auto-generated method stub
Health health = Health.up().build();
return health;
}
});
HealthContributor healthContributorB = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
// TODO Auto-generated method stub
Health health = Health.down().build();
return health;
}
});
healthContributors[0] = healthContributorA;
healthContributors[1] = healthContributorB;
return healthContributors;
}
}