In last post, I talked about configuring and leveraging spring boot actuators to configure your boot application to have production ready features.
In this Post, let's customise Health endpoint, which is one of the important actuator endpoint, It helps in:
- Monitoring Application Health: The Health endpoint provides a simple and standardized way to monitor the health of your application. It allows you to quickly check whether your application is running correctly or encountering any issues. Monitoring the health status of your application helps you identify and respond to potential problems early, reducing downtime and ensuring a better user experience.
- Proactive Issue Detection: By regularly polling the Health endpoint, monitoring tools and systems can proactively detect any degradation or failure in your application's health. This enables your operations team to take immediate action before issues escalate and impact users.
- Integration with Orchestration Tools: In modern production environments, applications are often managed and orchestrated by tools like Kubernetes, Docker Swarm, or cloud platforms.
- Operational Insights: The Health endpoint provides essential information about your application's internals. You can customize the endpoint to include details about database connections, external service status, resource availability, and more. These details are valuable for troubleshooting and gaining insights into your application's behavior during runtime.
Spring Actuators provide rich API support to customize health endpoint response.
Let's first enable health endpoint from the configurations and allow it to show details:
management.endpoints.web.exposure.include=health
management.endpoint.health.show-details=always
By default, it exposes ping status and disk details:
{
"status": "UP",
"components": {
"diskSpace": {
...
...
...
},
"ping": {
"status": "UP"
}
}
}
We can disable this default response by setting management.health.defaults.enabled
property to false
Customising Health endpoint by implementing HealthIndicator
Implementing the HealthIndicator interface allows you to create custom health indicators to monitor specific aspects of your application.
The HealthIndicator
(package: org.springframework.boot.actuate.health) interface is part of the Spring Boot Actuator module, and it provides a single method, health()
, that returns a Health
object representing the health status of your custom indicator. It provides several static methods to create instances of Health, as well as to add additional details and contextual information about the health check.
Here are some commonly used static methods of the Health
class:
up(): Creates a Health instance with an
UP
status, indicating that the application is in a healthy state.down(): Creates a Health instance with a
DOWN
status.unknown(): Creates a Health instance with an
UNKNOWN
status.status(Status status): Creates a Health instance with a custom status. The Status enum represents the health status, and it can be
UP, DOWN, or UNKNOWN
.withDetail(String key, Object value): Adds additional details to the Health instance. These details provide more information about the health status and can be useful for troubleshooting and monitoring.
withDetails(Map details): Adds multiple details to the Health instance at once, using a Map of key-value pairs.
Let's now write an implementation of the HealthIndicator
interface i.e. ExternalServiceHealthIndicator.class
. It's a typical example, where I am returning a Health object based on HTTP statusCode received from external service call.
@Component
public class ExternalServiceHealthIndicator implements HealthIndicator {
private final Random randomizer = new Random();
private final List<Integer> statusCodes = List.of(200, 204, 401, 404, 503);
@Override
public Health health() {
int randomStatusCode = statusCodes.get(randomizer.nextInt(statusCodes.size()));
Health.Builder healthBuilder = new Health.Builder();
return (switch(randomStatusCode) {
case 200, 204 -> healthBuilder.up()
.withDetail("External_Service", "Service is Up and Running ✅")
.withDetail("url", "https://example.com");
case 503 -> healthBuilder.down()
.withDetail("External_Service", "Service is Down 🔻")
.withDetail("alternative_url", "https://alt-example.com");
default -> healthBuilder.unknown().withException(new RuntimeException("Received status: " + randomStatusCode));
}).build();
}
}
@ConditionalOnEnabledHealthIndicator annotation
@ConditionalOnEnabledHealthIndicator is a meta-annotation in org.springframework.boot.actuate.autoconfigure.health
package to conditionally enable or disable the health check provided by that specific indicator and requires indicatorName
as a mandatory String argument which can be enabled with the externalised application configuration. Let's see an example in action.
@Component
@ConditionalOnEnabledHealthIndicator("external_service_health")
public class ExternalServiceHealthIndicator implements HealthIndicator {
@Override
public Health health() {
...
}
}
The Custom indicator can be enabled/disabled by setting management.health.<custom-indicator>.enabled
property true/false in the application's configuration. If the property is not present or set to false, the indicator will not be enabled.
management.health.external_service_health.enabled: true
Final Words
Health Endpoint is a really useful endpoint to Monitor your Application health, get Operational insights, health check your deployments. Please share your thoughts/opinions in the comments.
Top comments (1)
Amazing Article @manojshr
Very descriptive and on point as always