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!