Spring Boot Health Endpoint
In this post, We will learn about Health check indicators of Spring Boot. Spring boot makes health checks easier for us by providing opinionated /actuator/health endpoint.
Spring Boot Health actuator
The HealthEndpoint of spring-boot-starter-actuator module collects Health
information for any beans that are defined as HealthIndicator
.
For a simple web application, there are two HealthIndicator
beans Auto-Configured by default. And they are for Ping health check and Disk Space health check. However, More health indicators comes into place when we start adding starters.
For example, I have a sample spring boot project with the following setup.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springhow.examples</groupId>
<artifactId>health-check</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>health-check</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Code language: HTML, XML (xml)
The Above example starts the application in port 8080. As a result, hitting the http://localhost:8080/actuator/health URL responds with the following.
$ curl -s -i -X GET http://localhost:8080/actuator/health
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 11:36:37 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP"
}
Code language: JavaScript (javascript)
By interpreting the results, It’s a 200 OK response. Above all, the response says that the status is UP.
But we want to see more information about these health checks. So in the application.properties, lets change management.endpoint.health.show-details to always. Now the response would look like below.
$ curl -s -i -X GET http://localhost:8080/actuator/health
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 11:33:40 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP",
"components": {
"diskSpace": {
"status": "UP",
"details": {
"total": 254971625472,
"free": 63426338816,
"threshold": 10485760,
"exists": true
}
},
"ping": {
"status": "UP"
}
}
}
Code language: JavaScript (javascript)
The response contains two components objects which are diskSpace and ping These two health information come from DiskSpaceHealthIndicator and PingHealthIndicator respectively.
Health Check from Starters
Usually, starters comes with their own health indicator auto-configurations. For Example, adding spring-boot-starter-jdbc adds a database Health check. Lets try this out by adding following dependencies to the above spring boot project and restart the application.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Code language: HTML, XML (xml)
This time hitting the health check endpoint return’s information about database as well.
$ curl -s -i -X GET http://localhost:8080/actuator/health
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 12:41:29 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"database": "H2",
"validationQuery": "isValid()"
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 254971625472,
"free": 63485485056,
"threshold": 10485760,
"exists": true
}
},
"ping": {
"status": "UP"
}
}
}
Code language: JavaScript (javascript)
Most importantly, You can lookup for a specific health check by its name. For instance, The following provides only the results for database status.
$ curl -s -i -X GET http://localhost:8080/actuator/health/db
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 12:55:13 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP",
"details": {
"database": "H2",
"validationQuery": "isValid()"
}
}
Code language: JavaScript (javascript)
Default Health Indicator beans
To summarize, Here is the list of default Health indicators that contribute to the actuator health endpoint.
Health Indicator | Endpoint Path |
---|---|
CassandraHealthIndicator | /actuator/health/cassandra |
CouchbaseHealthIndicator | /actuator/health/couchbase |
DataSourceHealthIndicator | /actuator/health/db |
DiskSpaceHealthIndicator | /actuator/health/diskSpace |
ElasticsearchRestHealthIndicator | /actuator/health/elasticsearch |
HazelcastHealthIndicator | /actuator/health/hazelcast |
InfluxDbHealthIndicator | /actuator/health/influx |
JmsHealthIndicator | /actuator/health/jms |
LdapHealthIndicator | /actuator/health/ldap |
LivenessStateHealthIndicator | /actuator/health/liveliness |
MailHealthIndicator | /actuator/health/mail |
MongoHealthIndicator | /actuator/health/mongo |
Neo4jHealthIndicator | /actuator/health/neo4j |
PingHealthIndicator | /actuator/health/ping |
RabbitHealthIndicator | /actuator/health/rabbit |
ReadinessStateHealthIndicator | /actuator/health/readiness |
RedisHealthIndicator | /actuator/health/readiness |
SolrHealthIndicator | /actuator/health/solr |
Health check groups
We can group health check components for various reasons. For example, let’s say our application use Mail, Database and RabbitMQ for some of its business logic. But there might be cases that some client requests only use database and email functionality. Here the client faces the following inconveniences.
- With this default arrangement, health-check happens for all components. Thus, the API for health check takes more time.
- If
RabbitMQ
connection is down, then the whole /actuator/health returns status as down. However, we won’t know if the component that it needs is down. - The client will have to check each and every component’s health. And it checks that by accessing /actuator/health/<component-name>. But for more than one component, the client would still spend more effort doing health-checks.
To summarize, These are the inconveniences we should avoid. To do that, we could arrange our health indicators to a named group. For instance, The below configuration creates an health group called my-health-check.
management.endpoint.health.group.my-health-check.include = db,ping
Code language: PHP (php)
Understandably, We can also also access this health check group by its name.
$ curl -s -i -X GET http://localhost:8080/actuator/health/my-health-check
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 13:35:19 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"database": "H2",
"validationQuery": "isValid()"
}
},
"ping": {
"status": "UP"
}
}
}
Code language: JavaScript (javascript)
With this approach, the client only has to hit one URL for application status check. The client doesn’t have to worry about any component failures other than db
and ping
.
Most importantly, you could even set management.endpoint.health.group.my-health-check.show-details=never.Here, the custom health check can hide sensitive data.
$ curl -s -i -X GET http://localhost:8080/actuator/health/my-health-check
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v3+json
Transfer-Encoding: chunked
Date: Sun, 26 Jul 2020 13:43:17 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"status": "UP"
}
Code language: JavaScript (javascript)
To summarize, We learned how All the examples mentioned in this post are available in this github repository.
You may also find the following articles relevant.