java yaml 102 lines · 3 tabs

Custom Spring Boot Actuator Health Indicators for Database and Disk

Shared by codesnips Aug 2026
3 tabs
package com.example.health;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component("database")
public class DatabaseHealthIndicator implements HealthIndicator {

    private final DataSource dataSource;
    private final String validationQuery;

    public DatabaseHealthIndicator(DataSource dataSource,
            @Value("${health.db.validation-query:SELECT 1}") String validationQuery) {
        this.dataSource = dataSource;
        this.validationQuery = validationQuery;
    }

    @Override
    public Health health() {
        long start = System.currentTimeMillis();
        try (Connection connection = dataSource.getConnection();
                Statement statement = connection.createStatement()) {
            statement.setQueryTimeout(2);
            statement.execute(validationQuery);
            return Health.up()
                    .withDetail("query", validationQuery)
                    .withDetail("responseMillis", System.currentTimeMillis() - start)
                    .withDetail("catalog", connection.getCatalog())
                    .build();
        } catch (SQLException ex) {
            return Health.down(ex)
                    .withDetail("query", validationQuery)
                    .build();
        }
    }
}
3 files · java, yaml Explain with highlit

This snippet shows how a Spring Boot service exposes an aggregated /actuator/health endpoint backed by two custom indicators — one that verifies database connectivity and one that checks free disk space — plus the configuration that wires them into a readiness group for Kubernetes probes.

Spring Boot's actuator already ships with DataSourceHealthIndicator and DiskSpaceHealthIndicator, but a real service usually needs to add domain-specific detail: a bespoke validation query, custom thresholds, and extra fields in the response. The pattern is to implement the HealthIndicator interface, whose single health() method returns a Health object built with Health.up(), Health.down(), or Health.outOfService(). The framework discovers every such @Component by bean name and contributes it to the overall status, taking the worst individual status as the aggregate.

In DatabaseHealthIndicator, the check borrows a Connection from the injected DataSource and runs a lightweight validationQuery inside a try-with-resources block so the connection is always returned to the pool. A successful query yields Health.up() enriched with withDetail metadata; any SQLException is caught and mapped to Health.down(ex), which attaches the exception without letting it bubble up and crash the endpoint. Running a real query rather than trusting Connection.isValid() catches cases where the pool is alive but the database is rejecting statements.

In DiskSpaceHealthIndicator, File.getUsableSpace() is compared against a configurable threshold. When free space drops below the limit the indicator reports DOWN, otherwise UP, and both branches expose free, threshold, and path details so operators can see the actual numbers. This is the classic guardrail against a service that keeps accepting writes until the volume fills and corrupts state.

In HealthConfig, application.yml turns on show-details: always, registers the two indicators under the readiness group, and enables probes so Kubernetes gets distinct livenessState and readinessState endpoints. Grouping matters: a full disk should fail readiness (stop routing traffic) without failing liveness (which would trigger a pointless restart). The main trade-off is that health checks run on the probe thread, so both queries are deliberately cheap and time-bounded to avoid turning a monitoring endpoint into a source of load.


Related snips

Share this code

Here's the card — post it anywhere.

Custom Spring Boot Actuator Health Indicators for Database and Disk — share card
Link copied