Why Custom Health Indicators?
Spring Boot provides several built-in health checks (e.g., diskSpace
, db
, ping
), but what if:
- Your system depends on a third-party API, and if that service is down, your app is practically unusable?
- You need to verify if a certain table in your database has expected values?
- You want to check if a certificate is valid or a cache is filled?
This is where custom health indicators come into play.
How to Create a Custom Health Indicator?
You can create a custom health indicator by doing one of the following:
Option 1: Implement HealthIndicator
Interface
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Component public class MyApiHealthIndicator implements HealthIndicator { @Override public Health health() { // Simulate a failing check boolean apiIsDown = true; if (apiIsDown) { return Health.down() .withDetail("API Status", "External API is down") .withDetail("Reason", "SSL Certificate expired") .build(); } return Health.up() .withDetail("API Status", "Running smoothly") .build(); } }
Option 2: Extend AbstractHealthIndicator
import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import org.springframework.stereotype.Component; @Component public class ExternalServiceHealthIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { // Custom logic boolean serviceIsOk = true; if (serviceIsOk) { builder.up().withDetail("External Service", "Available"); } else { builder.down().withDetail("External Service", "Unavailable"); } } }
Both classes must be annotated with @Component
so Spring can detect and register them as beans.
What Happens Internally?
When Spring Boot sees a bean of type HealthIndicator
, it automatically aggregates it into the /actuator/health
endpoint.
By default, the overall health status is composite, meaning:
- If all indicators return
UP
, the status isUP
. - If any returns
DOWN
, the overall status isDOWN
. - Some statuses like
UNKNOWN
do not affect the overall health.
Testing the Custom Indicator
Once your custom indicator is added, start your app and hit:
GET http://localhost:8080/actuator/health
Example Response
{ "status": "DOWN", "components": { "db": { "status": "UP" }, "diskSpace": { "status": "UP" }, "ping": { "status": "UP" }, "myApiHealthIndicator": { "status": "DOWN", "details": { "API Status": "External API is down", "Reason": "SSL Certificate expired" } } } }
As you can see, one failing component (myApiHealthIndicator
) caused the overall health to become DOWN
.