Build Your REST API with Spring - VIDEO CoursesSpring Boot Actuator
You are here to learn about Spring Boot Actuator for collecting metrics about your production grade applications. Spring Boot Actuator is sub-project of Spring Boot and it is one of the nice feature that adds great value to the Spring Boot applications. Lets understand in this tutorial about spring boot actuator and different types of metrics that can be collected using this feature.
- Are you interested in reading more about spring boot, please look at our spring boot tutorials page.
Table of Contents
The sections covered in this post about the Spring Boot Actuator.
- What is Spring Boot Actuator?
- How to enable spring boot actuator?
- Actuator endpoints
- Customizing endpoints
- Security
- Endpoint – Info
- Endpoint – Dump
- Endpoint – Health
- Custom Health Endpoint
- Endpoint – Metrics
- Caching Metrics (Since Spring Boot 1.3.0)
- Endpoint – Logfile
- Create custom endpoints
- List all the endpoints
- Example application
- Common exceptions
What is Spring Boot Actuator?
- Spring Boot Actuator is a sub-project / feature that is part of the spring boot framework. It is not a separate framework to be added to your applications.
- Main purpose of this feature is to provide various useful metrics about the applications. It is very helpful in the production environment to check the various metrics like health of your application, configurations, error page, version details, etc.
- Actuator is supported out of the box within spring boot applications. You just have to add the dependency to enable the actuator. The default configurations are enabled if you are not providing any application specific configurations.
- Actuator makes the metrics are accessed through different endpoints like /error, /metrics, /beans, /info, etc. End points are HTTP URLs that can be accessed through your browser.
How To Enable Spring Boot Actuator?
Please add the following pom.xml entries in your spring boot application.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
That’s it?. Yes. You have now added the actuator to your existing application. When you re-start your application, endpoints are enabled for the user access. More detailed configurations and customization of the metrics are explained in the future sections.
Actuator Endpoints
HTTP Endpoints are enabled for accessing the various information about your application. The list of 15 endpoints that are currently supported by spring boot actuator module is:
- actuator: It is the default endpoint to list the available endpoints exposed to the user. It is enabled only when HATEOAS available in your classpath.
- autoconfig : Report on auto-configuration details.
- beans : This endpoint lists all the beans loaded by the application.
- configprops : This endpoint shows configuration properties used by your application.
- dump : Performs a thread dump.
- env : Exposes spring’s properties from the configurations.
- health : Health of the application.
- info : Displays application information like version, description, etc.
- metrics : Metrics about memory, heap, etc. for the currently running application
- mappings : Displays a list of all @RequestMapping paths.
- shutdown : This endpoint allows to shutdown the application. This is not enabled by default.
- trace : Displays trace information for the current application.
- logfile : Provides access to the configured log files (This feature supported since Spring Boot 1.3.0).
- flyway : This endpoint provides the details of any flyway database migrations have been applied (This feature supported since Spring Boot 1.3.0).
- liquibase : This endpoint provides the details of any liquibase database migrations have been applied (This feature supported since Spring Boot 1.3.0).
In the above list, only few are enabled by default. Others are disabled by default for the security reasons. Developers can override the properties to enable them. We will explain the manual configurations in the subsequent sections.
Customizing Endpoints
In the above section, we have listed all the endpoints and the purpose of each endpoints in brief. But, just enabling the endpoints may not be sufficient in most of the real time applications. You would like to update application specific configurations. That can be done through spring boot’s configurations file application.properties.
If you want to understand how the project structure and location of the properties files are in the project, look at the below screen shot of the example project structure.
The most common settings are:
management.port=8081
– change the port of the actuator endpoints in your servermanagement.address=127.0.0.1
– restrict to run only on localhostmanagement.context-path=/details
– change the context path for actuatorendpoints.health.enabled=false
– enable or disable the endpoints.
The above are just for the understanding purpose I have listed few configurations.
Security
Most of the times, the details exposed via few of the endpoints are sensitive and requires authorized user to view the details. You can add spring security to secure your endpoints. Just add the dependency, when the spring security files are available in the classpath, it will be automatically configured.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
By default, the basic security enabled. This will be enabled for all the endpoints. But, you can disable them by updating the application.properties file and expose the non-sensitive endpoints without security.
The following are the basic entries that are required to configure the security for your spring boot actuator application:
management.security.enabled=true security.basic.enabled=true security.user.name=admin security.user.password=admin
In the above configurations, we are enabling the basic security and providing the user name and password to access the endpoints. When user tries to access the endpoints, there will be pop-up on the browser to authenticate the user with credentials.
Endpoint – Info
- This endpoint helpful for displaying the details of the applications like application name, description, version, etc.
- By default, the endpoint can be accessed using
/info
- The default value for sensitive is false. There is no harm in exposing this details as that is common details that has to be exposed to others.
Configuration in application.properties file:
endpoints.info.id=info endpoints.info.sensitive=false endpoints.info.enabled=true info.app.name=Spring Actuator Example info.app.description=Spring Actuator Working Examples info.app.version=0.0.1-SNAPSHOT
When you execute the above configurations, you would get the following output in the browser:
{ "app": { "version": "0.0.1-SNAPSHOT", "description": "Spring Actuator Working Examples", "name": "Spring Actuator Example" } }
Endpoint – Dump
Thread dumps are important when your application encounters any performance issues. In normal scenarios, you have to request the production server administrator to take the thread dumps at the frequent intervals and send across to you for the analysis. But, that takes lot of time and also you would require the thread dumps only when the actual performance issue arises.
This end point is would offer real benefits to the production applications to get the thread dumps just by accessing the application using browser. It is awesome to see spring boot offers such an excellent features for the production application. Long live spring boot :).
Endpoint – Health
- This endpoint used for knowing the status / health of application whether it is Up or Down.
- If the endpoint is accessed through normal unauthenticated way, it returns simple status message. If accessed through authenticated way, there will be additional details displayed.
- The default value for sensitive is false.
- You can write your custom health indicator to provide additional details to the user. The following are the list of health indication implementation classes available for customization:
- DiskSpaceHealthIndicator
- DataSourceHealthIndicator
- MongoHealthIndicator
- RabbitHealthIndicator
- SolrHealthIndicator
The basic configurations for health endpoint is:
endpoints.health.id=health endpoints.health.sensitive=true endpoints.health.enabled=true
Custom Health Endpoint
In the above section what we have learnt is how to use the built-in health endpoint. One can extend the HealthIndicator interface and provide their own implementation. CustomHealthCheck is implementing the method health() which is declared in the interface HealthIndicator. When you create a custom class of this type and override the method health(), the default functionality will be overwritten by your custom logic.
Look at the example code:
@Component public class CustomHealthCheck implements HealthIndicator { public Health health() { int errorCode = 0; if (errorCode != 1) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build(); } }
The output will be:
{ "status": "DOWN", "customHealthCheck": { "status": "DOWN", "Error Code": 0 }, "diskSpace": { "status": "UP", "free": 195979440128, "threshold": 10485760 } }
Endpoint – Metrics
- By default this endpoint is enabled under the HTTP URL /metrics.
- This endpoint used for collecting the details of applications performance like memory, processors, up time, heap size, classes loaded, garbage collection, http sessions, etc.
The example configuration for this endpoint is:
endpoints.metrics.id=metrics endpoints.metrics.sensitive=true endpoints.metrics.enabled=true
When you access the endpoint, you would receive the output as in the below screen. This is for the default configurations.
Cache Metrics
- Cache metrics details are added to the metrics endpoint since the spring boot 1.3.0 release.
The newly added metrics details are:
- The current size of the cache
cache.xxx.size
- The hit ratio
cache.xxx.hit.ratio
- The miss ration
cache.xxx.miss.ratio
The hit and miss ration may not be consistent across the cache providers. Because they might have different way of exposing the hit and miss ratios. Please refer their documentation for more details.
By default spring boot actuator supports the caching metrics for EhCache (Also Read : Spring Cache Tutorial), Hazelcast, Infinispan, JCache and Guava. If your caching implementation in your application is not one of the above, then please add the CacheStatisticsProvider
bean to support the caching metrics.
If you are interested, please read our in-depth article on caching support in spring boot.
Endpoint – Logfile
- This end point is added from the spring boot 1.3.0 release.
This endpoint will be automatically enabled if logging.path
or logging.file
properties are configured in the application.properties
file. When you access the logile endpoint, this will return the complete log of the application.
Whatever the log file location configured in the environment will be displayed in the browser. This feature is very useful for the production grade applications to check the log files easily through browser. Let’s look at the same log file accessed from the example application.
Custom Endpoint Implementation
Apart from the above default endpoints exposed by spring boot, developers can write their own endpoints by implementing the interface Endpoint. This is useful when you want to expose application details which are an added feature to your application. For example, in this example I have created a custom endpoint to display the server details for the application.
The implementation class would looks like this:
@Component public class ServerEndpoint implements Endpoint<List<String>> { public String getId() { return "server"; } public List<String> invoke() { List<String> serverDetails = new ArrayList<String>(); try { serverDetails.add("Server IP Address : " + InetAddress.getLocalHost().getHostAddress()); serverDetails.add("Server OS : " + System.getProperty("os.name").toLowerCase()); } catch (Exception e) { e.printStackTrace(); } return serverDetails; } public boolean isEnabled() { return true; } public boolean isSensitive() { return false; } }
- ServerEndpoint class implements Endpoint. Any class of type Endpoint will be exposed as an endpoint in the server
- If you look at the methods, getId(), isEnabled() and isSensitive(), which are the properties that are overridden by the application.properties file.
- invoke() is the important method responsible for writing the message. Here I have written simple message, in real time applications it could involve more complex logic.
When you execute example application, the output will be:
["Server IP Address : 192.168.1.4","Server OS : windows nt (unknown)"]
List All The Endpoints
It is quite useful if you have an endpoint to display all the endpoints in a single web page. There is a built-in endpoint /actuator for this purpose, but you have to add HateOAS in the classpath to enable that feature.
We could write a custom endpoint in the similar way how we have written in the above section to print the endpoints. The following class extends AbstractEndpoint to list all the end points.
Sample implementation is :
@Component public class ShowEndpoints extends AbstractEndpoint<List<Endpoint>>{ private List<Endpoint> endpoints; @Autowired public ShowEndpoints(List<Endpoint> endpoints) { super("showEndpoints"); this.endpoints = endpoints; } public List<Endpoint> invoke() { return this.endpoints; } }
When you implement the above class, there will be a new endpoint “showEndpoints” will be registered and exposed to the users. The output will be:
[ { "sensitive": false, "id": "server", "enabled": true }, { "id": "mappings", "sensitive": true, "enabled": true }, { "id": "env", "sensitive": true, "enabled": true }, { "id": "health", "sensitive": true, "enabled": true, "timeToLive": 1000 }, { "id": "beans", "sensitive": true, "enabled": true }, { "id": "info", "sensitive": false, "enabled": true }, { "id": "metrics", "sensitive": true, "enabled": true }, { "id": "trace", "sensitive": true, "enabled": true }, { "id": "dump", "sensitive": true, "enabled": true }, { "id": "autoconfig", "sensitive": true, "enabled": true }, { "id": "shutdown", "sensitive": true, "enabled": false }, { "id": "configprops", "sensitive": true, "enabled": true } ]
Example Application for Actuator
In this section I have listed all the source code for writing this tutorial from the beginning. There is no other configurations required to run this example application. Note that this example just used actuator feature and not considered any other concept in the spring boot, so I have nore written any Spring MVC controller classes.
How to run this example application?
If you are running this project inside Eclipse or from the maven command, you can run using the following command:
mvn spring-boot:run
The application’s actuator endpoint will be enabled at
http://localhost:8081/details/
Here is the list of source codes.
pom.xml
<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 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>javabeat.net</groupId> <artifactId>spring-boot-actuator-example</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-actuator-example Maven Webapp</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.5.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> <build> <finalName>spring-boot-example</finalName> </build> </project>
Application.java
package net.javabeat; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; @EnableAutoConfiguration @ComponentScan public class Application{ public static void main(final String[] args) { SpringApplication.run(Application.class, args); } }
ServerEndpoint.java
package net.javabeat; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.stereotype.Component; @Component public class ServerEndpoint implements Endpoint<List<String>> { public String getId() { return "server"; } public List<String> invoke() { List<String> serverDetails = new ArrayList<String>(); try { serverDetails.add("Server IP Address : " + InetAddress.getLocalHost().getHostAddress()); serverDetails.add("Server OS : " + System.getProperty("os.name").toLowerCase()); } catch (Exception e) { e.printStackTrace(); } return serverDetails; } public boolean isEnabled() { return true; } public boolean isSensitive() { return false; } }
ShowEndpoints.java
package net.javabeat; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.endpoint.AbstractEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.stereotype.Component; @Component public class ShowEndpoints extends AbstractEndpoint<List<Endpoint>>{ private List<Endpoint> endpoints; @Autowired public ShowEndpoints(List<Endpoint> endpoints) { super("showEndpoints"); this.endpoints = endpoints; } public List<Endpoint> invoke() { return this.endpoints; } }
CustomHealthCheck.java
package net.javabeat; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Component public class CustomHealthCheck implements HealthIndicator { public Health health() { int errorCode = 0; if (errorCode != 1) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build(); } }
application.properties
management.port=8081 management.context-path=/details management.security.enabled=true security.basic.enabled=true security.user.name=admin security.user.password=admin endpoints.health.id=health endpoints.health.sensitive=true endpoints.health.enabled=true endpoints.metrics.id=metrics endpoints.metrics.sensitive=true endpoints.metrics.enabled=true endpoints.server.id=server endpoints.server.sensitive=false endpoints.server.enabled=true endpoints.info.id=info endpoints.info.sensitive=false endpoints.info.enabled=true info.app.name=Spring Actuator Example info.app.description=Spring Actuator Working Examples info.app.version=0.0.1-SNAPSHOT
Common Exceptions
This section lists some of the common exceptions you would have encountered if by chance missed any configurations. If you encounter any other hurdles on the way to learn actuator, please post it in the comments section. We will add that in this section.
ContextPath Issues:
If you are seeing the following exception, that means that you are not having the proper context path configured. The context path must start with “/” and must not end with “/”. For example “/details” is correct and “details” is not correct.
Caused by: java.lang.IllegalArgumentException: ContextPath must start with '/ and not end with '/' at org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer. checkContextPath(AbstractConfigurableEmbeddedServletContainer.java:103) at org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer. setContextPath(AbstractConfigurableEmbeddedServletContainer.java:91) at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcChildContextConfiguration $ ServerCustomization.customize(EndpointWebMvcChildContextConfiguration.java:87)
Security Exception:
If you are getting the following exception, then probably you have the following entry in your application.properties and not added your spring security dependency in your classpath. Please check your pom.xml and update accordingly to add the spring security JARs on the classpath to resolve this error.
management.security.enabled=true
This is the exception:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'managementServerProperties' defined in class path resource [org/springframework/boot/actuate/autoconfigure/ ManagementServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/security/config/http/SessionCreationPolicy at org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory.doCreateBean( AbstractAutowireCapableBean Factory.java:547) Caused by: java.lang.NoClassDefFoundError: org/springframework/ security/config/http/SessionCreationPolicy at org.springframework.boot.actuate.autoconfigure. ManagementServerProperties$ Security.<init>(ManagementServerProperties.java:95) at sun.reflect.NativeConstructorAccessorImpl. newInstance0(Native Method) Caused by: java.lang.ClassNotFoundException: org.springframework. security.config.http. SessionCreationPolicy at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
Actuator Video
Here is a short video on how to use actuator by Baeldung in his REST video course:
Conclusion
I hope this tutorial about spring boot actuator would have provided most comprehensive details. I have explained about the basic concepts on actuators, endpoints, list of endpoints, creating custom endpoints, health check,metrics (also caching metrics introduced in spring boot 1.3.0) and provided a complete working example application for spring boot actuator.
If you have faced any challenges on using the actuator feature in spring boot, please write to me in the comments section. I am happy to resolve your issues.
Thank you for visiting my blog. Happy Reading!!