Today, we will be discussing about spring boot actuator in great details. This post aims to provide a complete tutorial on spring boot actuators. Starting from the overview, we will deep dive into actuator concepts, configuring actuator in spring boot applications, customizing actuator endpoints, exposing custom endpoints and override default security to the sensitive endpoints of spring boot actuator.
With the rise of microservice based architectured application, application monitoring has been a critical and challenging task. There are many Devops tool that can be employed such as Prometheus, ELK, etc. Apart from these tools we can integrate Spring Boot Actuator from developer perspective with our microservices which actually provides options to monitor and manage spring boot apps. There are many internal aspects of an app which can't be managed with Prometheus which we will discuss here.
Actuator only provides the endpoint for application monitoring and manage. Later, in the next article we will discuss how these APIs can be integrated to provide an Admin console to visualise our app metrics and health using Spring Boot Admin.
What is Spring Boot Actuator
Spring Boot Actuator is a sub-project of Spring Boot. It provides several production grade ready features to any spring boot application. Once it is configured in any spring boot application, it exposes a no. of REST endpoints out of the box to manage and monitor your application. You can monitor your application health, application bean details, version details, thread dumps, logger details etc. without wrting any extra line of code.
Once spring actuator is configured in your project, you get 16 built-in endpoints to manage and monitor your application by default. The list of these endpoints are provided below.
By using these default endpoints you can monitor your application health, check the beans configured, monitor your application properties and many more. Also you can restrict the endpoints access to certain role by integrating with spring security. You can customize default endpoints and even create your own custom endpoints to monitor your application.
We can restrict the access of these endpoints by authorized users only with integration of spring security. Spring boot provides security sensitivity defaults to true for all endpoints except /info
and /health
which requires username/password
to be accessible over http.
The authentication and authorization of these endpoints are can be integrated with existing Spring security configuration of our application.
Enabling Spring Boot Actuator
Let us set up a sample spring boot project for our demo. Head over to https://start.spring.io to generate a sample spring boot app with the actuator dependency. The spring boot version that we are using is 2.3.1.RELEASE.
Below is our pom.xml file which contains spring-boot-starter-actuator dependency.
<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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
With just this much of configuration there are few HTTP endpoints that are already exposed for monitoring of our application. Let us run ActuatorDemoApplication.java as a Java application.
@SpringBootApplication @RestController public class ActuatorDemoApplication { public static void main(String[] args) { SpringApplication.run(ActuatorDemoApplication.class, args); } @GetMapping("/greeting") public String greet(){ return "Hello there!"; } }
Now we can access http://localhost:8080/actuator to see all the endpoints that are already exposed.
These are the basic actuator endpoints which are exposed by default to monitor our application. By default, all endpoints except for shutdown are enabled. There are many other endpoints which can be enabled or disabled and customized which we will discuss in next section.
Not only this we can even customize the path /actuator
to our custom URL with a simple configuration. With below entry in the application.properties we can access http://localhost:8080/myapp for above info.
management.endpoints.web.base-path=/myapp
If you will hit the health endpoint as http://localhost:8080/myapp/health then you will see only the status of your App as UP or DOWN. Again we can configure this particular endpoint to show some more details about the application health.
For this type of configuration, we have a generic syntax as management.endpoint.<id>.<action>
. For example, now if we want to customize the endpoint health to add an action as show-details then we can below entry in our application.properties file.
Here, id is health and action is show-details. In the similar way we can configure all the other endpoints.
management.endpoint.health.show-details=always
By default the value for show-details is never and we can configure its value as when_authorized. Now the response to http://localhost:8080/myapp/health becomes
{ "status": "UP", "components": { "diskSpace": { "status": "UP", "details": { "total": 241340108800, "free": 132397277184, "threshold": 10485760, "exists": true } }, "ping": { "status": "UP" } } }
Some of the other valid actions could be enabled to enable or disable any particular endpoint, roles to determine if a user is authorised to see the health details, groups, etc.
Now, let us list down all the actuator endpoints and then we will discuss about those endpoints in detail.
Different Actuator Endpoints
Once actuator feature is enabled by including above maven dependency, more then 16 endpoints are exposed out of the box by spring Boot actuator. Among the list of 16 endpoints, only /health
and /info
can be accessed and rest of the endpoints are not exposed by default unless you enable it explicitly or include spring-boot-starter-security
artifact as maven dependency.
Let us discuss about these endpoints first.
1. actuator : It provides a hypermedia-based discovery page for the other endpoints. It is required to have Spring HATEOS on the classpath to enable it. By default it is sensitive and hence requires username/password for access or may be disabled if web security is not enabled.
2. auditevents: It exposes audit events information.
3. autoconfig: It displays an auto-configuration report showing all auto-configuration candidates.
4. beans: It displays complete beans configured in the app.
5. configprops: It displays a collated list of all @ConfigurationProperties.
6. dump: It performs a thread dump.
7. env: It exposes properties from Spring ConfigurableEnvironment.
8. flyway: It shows any Flyway database migrations that have been applied.
9. health: It shows application health information (when the application is secure, a simple ‘status’ when accessed over an unauthenticated connection or full message details when authenticated).
10. info: It displays arbitrary application info.
11. loggers: It shows and modifies the configuration of loggers in the application.
12. liquibase: It shows any Liquibase database migrations that have been applied.
13. metrics: It shows metrics information for the current application.
14. mappings: It displays a collated list of all @RequestMapping paths.
15. shutdown: It allows the application to be gracefully shutdown (not enabled by default).
16. trace: It displays trace information (by default the last 100 HTTP requests).
17. caches: To check available caches available in the app.
If you are also using spring mvc then other 4 additional endpoints such as docs
, heapdump
, jolokia
and logfile
can be used
Other Interesting Posts Spring Boot Actuator Rest Endpoints Example Securing Spring Boot Actuator Endpoints with Spring Security Spring 5 Features and Enhancements Spring Boot Thymeleaf Example Spring Boot Security Hibernate Example with complete JavaConfig Securing REST API with Spring Boot Security Basic Authentication Spring Boot Security Password Encoding using Bcrypt Encoder Websocket spring Boot Integration Without STOMP with complete JavaConfig
Enable/Disable Endpoints
The simple way to enable and disable any endpoint is by making an entry in the properties file in the format management.endpoint.<id>.enabled
where id is the endpoint that we want to deal with. Simply put to enable health endpoint we make below entry.
management.endpoint.health.enabled=true
We saw the list of all the endpoints but we can only see few endpoints at http://localhost:8080/myapp. Now, let us make the configuration to expose all the endpoints with below configuration.
management.endpoints.web.exposure.include=*
This will expose all the endpoints but you can also provide comma(,) seperated id to enable only few of it as below. Now, if you try to access http://localhost:8080/myapp, you will see all the endpoints.
management.endpoints.web.exposure.include=health,beans,env
Similarly, if we want to disable all the endpoints and enable some specific endpoints then we can do below configuration that will only enable /health endpoint.
management.endpoints.enabled-by-default=false management.endpoint.health.enabled=true
Customizing Endpoints
You can customize each actuator endpoints in 3 different ways. You can enable or disable an endpoint, customize its sensitivity and its endpoint path called as id. All these customization can be achieved by creating entries in application.properties
Wecan also customize behaviour of all the endpoints with one time configurations by customizing endpoints globally with the property prefix management.endpoints like we exposed all the endpoints with below configurations.
management.endpoints.enabled-by-default=true
You can check the documentation for all the available global configurations here.
Securing Actuator Endpoints
Apart from 2 endpoints - /health and /info, all the other endpoints are sensitive by default. And also to have access to other endpoints apart from /health and /info, we require to have required authorization. To have access to non-sensitive endpoints you can either disable the sensitivity of these sensitive endpoints which is of course not recommended or secure it using spring security(recommended).
While dealing with Spring Boot, include following maven dependency in your pom.xml.
Once you include this dependency to pom file, all of your rest endpoints including application controllers endpoints will also be secure by Spring basic authentication and to avoid this you require some extra effort which I have discussed in Securing Spring Boot Actuator Endpoints with Spring Security
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
Now, once this spring security dependency is added, all the sensitive actuator endpoints requires authentication and authorization. Now even after making to true, you will be redirected to form based default authentication page for authentication while trying to access any sensitive actuator endpoints such as
http://localhost:8080/myapp/beans
.
Now, let us add basic authentication username and password in our properties file.
spring.security.user.name=actuator spring.security.user.password=actuator
Now, above configured username and password can be used to access the sensitive actuator endpoints.
Above security configuration is a very basic one and is good enough for a demo app. Now, let us enable a role based authorization for the actuator endpoint /myapp. You can follow my another article to enable role-based authorization with JWT.
Let us make the spring security configuration for role based authentication and authorization of actuator endpoints. We will comment the security related key value from our properties file and add below in-memory configuration. The password is Bcrypt encoded generated with this online free tool.
@Configuration @EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { public void configure(HttpSecurity http) throws Exception { http.httpBasic(); http .authorizeRequests() .antMatchers("/myapp/**").hasRole("ACTADMIN"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") //password is password(Bcrypted with online free tool) - https://devglan.com/online-tools/bcrypt-hash-generator .password("{bcrypt}$2a$04$fPsaMC/8QJvinvTKzoxEkuzfJ85BiWP2HyR37go9Vf5tEetlN9Im2") .roles("ACTADMIN"); } }
A user with role ACTADMIN will only be able to access the actuator endpoint(myapp) now. Here, we are using an in-memory authentication but we can also configure the same using UserDetailsService configuration as below. Comment out above configure(AuthenticationManagerBuilder auth)
method to enable below configuration.
@Override public UserDetailsService userDetailsService() { UserDetails user = User .withUsername("user") //password is password - https://devglan.com/online-tools/bcrypt-hash-generator .password("{bcrypt}$2a$04$fPsaMC/8QJvinvTKzoxEkuzfJ85BiWP2HyR37go9Vf5tEetlN9Im2") .roles("ACTADMIN") .build(); return new InMemoryUserDetailsManager(user); }
Define Custom Actuator Endpoints
This is the last section of this guide on spring boot actuator endpoint where we will be creating a new custom endpoint and define some custom functions for this endpoint. Spring Actuator provides an abstract class AbstractEndpoint
which you can extend to define your own custom endpoint.
Following is a simple example of creating a custom actuator endpoint that can be accessed at localhost:8080/showendpoints
ListEndPoints.javaimport org.springframework.boot.actuate.endpoint.AbstractEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.stereotype.Component; import java.util.List; @Component public class ListEndPoints extends AbstractEndpoint<List<Endpoint>> { private Listendpoints; public ListEndPoints(List<Endpoint> endpoints) { super("showendpoints"); this.endpoints = endpoints; } @Override public List<Endpoint> invoke() { return this.endpoints; } }
Conclusion
I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section. The source code can be found on my github page.