I am looking to build a robust and detailed health check endpoint (/health
) on my Spring Boot REST service. I just read this excellent Baeldung article on the subject but still have a few concerns.
Ideally my /health
endpoint would be able to take into account the individual health of ALL my subsystems (10+ of them) including the health of the host (CPU, disk utilization, available memory, etc.).
I can't tell whether Spring Boot expects you to build one-and-only one HealthIndicator
impl. Or if the idea is to build one HealthIndicator
impl for each major subsystem (each of which can be independently "up" or "down" respectively.
Also, in that Baeldung example, what is the difference between the top-level status
and the myHealthCheck.status
and where do each of them come from (in the code)?
{
"status" : "DOWN",
"myHealthCheck" : {
"status" : "DOWN",
"Error Code" : 1,
"Description" : "You custom MyHealthCheck endpoint is down"
},
"diskSpace" : {
"status" : "UP",
"free" : 209047318528,
"threshold" : 10485760
}
}
And where does diskSpace
come from?!
You can implement several HealthIndicator
s and they will all contribute to the final overall value of UP or DOWN. The final value is an aggregate of all other values (determined by a StatusAggregator
).
Example 1 (Healthy)
@Component
public class ExampleOneHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// do something to check health
// inspect the return
// healthy
return Health.up().build();
}
}
Example 2 (Unhealthy)
@Component
public class ExampleTwoHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// do something to check health
// inspect the return
// unhealthy
return Health.down().build();
}
}
Example 3 (Unhealthy with details)
@Component
public class ExampleThreeHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// do something to check health
// inspect the return
// unhealthy with details
return Health.down()
.withDetail("reason", "details about why it failed")
.build();
}
}
With the above three examples and the management.endpoint.health.show-details
set to always
(in the application.properties
), you'd get the following result when calling /actuator/health
.
{
"status": "DOWN",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 1000240963584,
"free": 880857858048,
"threshold": 10485760
}
},
"exampleOne": {
"status": "UP"
},
"exampleThree": {
"status": "DOWN",
"details": {
"reason": "details about why it failed"
}
},
"exampleTwo": {
"status": "DOWN"
},
"ping": {
"status": "UP"
}
}
}
The names in the response are the class name (camel-cased) before HealthIndicator
(e.g. ExampleOneHealthIndicator
--> exampleOne
)
The other names (such as diskSpace
or ping
) come from the built in health checks and the class names are named just as you'd expect (DiskSpaceHealthIndicator
& PingHealthIndicator
)
Note that the top-level status
is DOWN
. This is determined by the StatusAggregator
. The default one is https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/actuate/health/SimpleStatusAggregator.html
Example code
https://github.com/dustinschultz/spring-boot-actuator-custom-health-checks