SoFunction
Updated on 2025-04-06

Spring Boot Actuator Getting Started Guide

Spring Boot Actuator

Spring Boot Actuator was found when the first version of Spring Boot was released. It provides Spring Boot with a series of product-level features: monitoring applications, collecting metadata, operating status or database status, etc.

Using Spring Boot Actuator, we can directly use these features without implementing them ourselves. It uses HTTP or JMX to interact with the outside world.

Get started with Spring Boot Actuator

To use Spring Boot Actuator, you need to add the following dependencies:

<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Get started with Actuator

After matching the above dependencies, we can use Actuator using the following main program entry:

@SpringBootApplication
public class ActuatorApp {
    public static void main(String[] args) {
        (, args);
    }
}

Start the application and visit http://localhost:8080/actuator:

{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"health-path":{"href":"http://localhost:8080/actuator/health/{*path}","templated":true},"info":{"href":"http://localhost:8080/actuator/info","templated":false}}}

We can see that actuator has two portals enabled by default: /health and /info.

If we configure this in the configuration file, we can open all the portals of actuator:

=*

Restart the application and visit http://localhost:8080/actuator again:

{"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false},"beans":{"href":"http://localhost:8080/actuator/beans","templated":false},"caches-cache":{"href":"http://localhost:8080/actuator/caches/{cache}","templated":true},"caches":{"href":"http://localhost:8080/actuator/caches","templated":false},"health":{"href":"http://localhost:8080/actuator/health","templated":false},"health-path":{"href":"http://localhost:8080/actuator/health/{*path}","templated":true},"info":{"href":"http://localhost:8080/actuator/info","templated":false},"conditions":{"href":"http://localhost:8080/actuator/conditions","templated":false},"configprops":{"href":"http://localhost:8080/actuator/configprops","templated":false},"env":{"href":"http://localhost:8080/actuator/env","templated":false},"env-toMatch":{"href":"http://localhost:8080/actuator/env/{toMatch}","templated":true},"loggers-name":{"href":"http://localhost:8080/actuator/loggers/{name}","templated":true},"loggers":{"href":"http://localhost:8080/actuator/loggers","templated":false},"heapdump":{"href":"http://localhost:8080/actuator/heapdump","templated":false},"threaddump":{"href":"http://localhost:8080/actuator/threaddump","templated":false},"metrics":{"href":"http://localhost:8080/actuator/metrics","templated":false},"metrics-requiredMetricName":{"href":"http://localhost:8080/actuator/metrics/{requiredMetricName}","templated":true},"scheduledtasks":{"href":"http://localhost:8080/actuator/scheduledtasks","templated":false},"mappings":{"href":"http://localhost:8080/actuator/mappings","templated":false}}}

We can see all the portals exposed by actuator.

Health Indicators

The Health entry is used to monitor the status of the component. Through the above entry, we can see that the Health entry is as follows:

"health":{"href":"http://localhost:8080/actuator/health","templated":false},"health-path":{"href":"http://localhost:8080/actuator/health/{*path}","templated":true},

There are two entrances, one is the overall health and the other is the specific health-path.

Let's visit http://localhost:8080/actuator/health:

{"status":"UP"}

The above result actually hides specific information, we can set it

-details=ALWAYS

Let’s open the details, and access it after opening it as follows:

{"status":"UP","components":{"db":{"status":"UP","details":{"database":"H2","result":1,"validationQuery":"SELECT 1"}},"diskSpace":{"status":"UP","details":{"total":250685575168,"free":12428898304,"threshold":10485760}},"ping":{"status":"UP"}}}

The components in it are health-path. We can access a specific component such as http://localhost:8080/actuator/health/db:

{"status":"UP","details":{"database":"H2","result":1,"validationQuery":"SELECT 1"}}

You can see the information about a specific component.

The information of these Health components is collected from beans that implement the HealthIndicator interface.

Let's take a look at how to customize HealthIndicator:

@Component
public class CustHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        int errorCode = check(); // perform some specific health check
        if (errorCode != 0) {
            return ()
                    .withDetail("Error Code", errorCode).build();
        }
        return ().build();
    }
    public int check() {
        // Our logic to check health
        return 0;
    }
}

Check http://localhost:8080/actuator/health again, and we will find that there is an additional Cust component:

"components":{"cust":{"status":"UP"} }

After Spring Boot, Spring has added React support. We can add ReactiveHealthIndicator as follows:

@Component
public class DownstreamServiceHealthIndicator implements ReactiveHealthIndicator {
    @Override
    public Mono<Health> health() {
        return checkDownstreamServiceHealth().onErrorResume(
                ex -> (new ().down(ex).build())
        );
    }
    private Mono<Health> checkDownstreamServiceHealth() {
        // we could use WebClient to check health reactively
        return (new ().up().build());
    }
}

Check http://localhost:8080/actuator/health again, and you can see that there is another component:

"downstreamService":{"status":"UP"}

/info portal

info displays app app general information, which is empty by default. We can customize it like this:

=Spring Sample Application
=This is my first spring boot application
=1.0.0

View: http://localhost:8080/actuator/info

{"app":{"name":"Spring Sample Application","description":"This is my first spring boot application","version":"1.0.0"}}

/metrics entry

/metrics provides some information about the JVM and operating system. Let's look at the metrics directory and visit: http://localhost:8080/actuator/metrics:

{"names":["","","","","",".1m","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]}

Visit one of the specific components as follows http://localhost:8080/actuator/metrics/:

{"name":"","description":"The maximum amount of memory in bytes that can be used for memory management","baseUnit":"bytes","measurements":[{"statistic":"VALUE","value":3.456106495E9}],"availableTags":[{"tag":"area","values":["heap","nonheap"]},{"tag":"id","values":["Compressed Class Space","PS Survivor Space","PS Old Gen","Metaspace","PS Eden Space","Code Cache"]}]}

Spring Boot's metrics are implemented through Micrometer, and Spring Boot will automatically register MeterRegistry. We will explain in detail in the later article about the combination of Micrometer and Spring Boot.

Custom Endpoint

Spring Boot's Endpoint can also be customized:

@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {
    private Map<String, String> features = new ConcurrentHashMap<>();
    @ReadOperation
    public Map<String, String> features() {
        return features;
    }
    @ReadOperation
    public String feature(@Selector String name) {
        return (name);
    }
    @WriteOperation
    public void configureFeature(@Selector String name, String value) {
        (name, value);
    }
    @DeleteOperation
    public void deleteFeature(@Selector String name) {
        (name);
    }
}

Visit http://localhost:8080/actuator/, and we will find an additional entry: http://localhost:8080/actuator/features/ .

In the above code, @ReadOperation corresponds to GET, @WriteOperation corresponds to PUT, and @DeleteOperation corresponds to DELETE.

The corresponding path parameters are followed by @Selector. For example, we can call the configureFeature method like this:

POST /actuator/features/abc HTTP/1.1
Host: localhost:8080
Content-Type: application/json
User-Agent: PostmanRuntime/7.18.0
Accept: */*
Cache-Control: no-cache
Postman-Token: dbb46150-9652-4a4a-95cb-3a68c9aa8544,8a033af4-c199-4232-953b-d22dad78c804
Host: localhost:8080
Accept-Encoding: gzip, deflate
Content-Length: 15
Connection: keep-alive
cache-control: no-cache
{"value":true}

Note that the request BODY here is provided in JSON form:

{"value":true}

The request URL: abc in /actuator/features/abc is the name in @Selector.

Let's take a look at the GET request:

http://localhost:8080/actuator/features/

{"abc":"true"}

This is the value we entered before.

Expand existing Endpoints

We can use @EndpointExtension (@EndpointWebExtension or @EndpointJmxExtension) to implement extensions to existing EndPoints:

@Component
@EndpointWebExtension(endpoint = )
public class InfoWebEndpointExtension {
    private InfoEndpoint delegate;
    // standard constructor
    @ReadOperation
    public WebEndpointResponse<Map> info() {
        Map<String, Object> info = ();
        Integer status = getStatus(info);
        return new WebEndpointResponse<>(info, status);
    }
    private Integer getStatus(Map<String, Object> info) {
        // return 5xx if this is a snapshot
        return 200;
    }
}

The above example extends InfoEndpoint.

The examples mentioned in this article can be found in: /ddean2009/learn-springboot2/tree/master/springboot-actuator

This is all about this article about Spring Boot Actuator. For more related Spring Boot Actuator content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!