Boot

Spring Boot Actuator Example

The Spring Boot Actuator helps you monitor and manage your application when you deploy it to production. Monitoring, gathering metrics, understanding the state of your app, etc. can be automatically applied when using this library. There are two ways of managing and monitoring your application, HTTP endpoint and JMX. This example demonstrates the HTTP endpoint.

1. Tools

  1. Apache Maven
  2. Mars Eclipse
  3. Spring Boot
  4. Spring Data Actuator

2. Assumptions

This article assumes that you know your way around Eclipse. You are familiar with Maven. Basically, you have done some coding. This project has been created using Eclipse Mars so all instructions are based on this IDE.

3. Project Setup

To start, create your project. This can be done by going to File -> New -> Maven Project and fill up what is required.

4. Project Object Model

Your pom.xml should look like the one below:

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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.example</groupId>
	<artifactId>spring-boot-actuator</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>

	<dependencies>
		<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>

	<properties>
		<java.version>1.8</java.version>
		<maven-jar-plugin.version>2.6</maven-jar-plugin.version> <!-- fixes Eclipse Mars m2e error in MavenArchiver.getManifest() -->
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

The simplest way to enable the Spring Boot Actuator features is to add the spring-boot-starter-actuator dependency. You may not need the maven-jar-plugin.version property if you have updated your Eclipse m2e extensions. You are using spring-boot-starter-web because you’re doing HTTP endpoints. You’re also using spring-boot-starter-security because you will be overriding the default actuator setting. In Eclipse, you can see the dependency hierarchy by opening the pom.xml and clicking on the Dependency Hierarchy tab. The Spring Boot Maven plugin enables you to package the project as an executable jar.

5. Create the Web App

Main.java

package com.javacodegeeks.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
	
	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}

}

This is just a simple code to get your web application up and running. Instead of annotating your class with @Configuration, @EnableAutoConfiguration, and @ComponentScan, you use the @SpringBootApplication annotation as a convenient alternative. This annotation tells Spring Boot to scan for other components, add beans based on the classpath, and tags the class as a source of bean definitions. You should be able to run (Run As -> Java Application) the web application and access it on localhost or use the curl command.

Console Output

...
2018-03-17 17:54:24.056  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/auditevents],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.058  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/beans],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.059  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.060  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/conditions],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.061  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/configprops],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.062  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.064  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/env/{toMatch}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.065  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
2018-03-17 17:54:24.066  INFO 8244 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/loggers],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map)
...

You should see something like the lines above in your console output. This means that your actuator is working and ready to serve. These are the available actuator endpoints.

6. Enable Endpoints

By default all endpoints are enabled except for shutdown. The syntax to configure the enablement of an endpoit is management.endpoit.<id>.enabled. To enable the shutdown endpoint, add the line below to your application.properties (or YML) file.

application.properties

management.endpoint.shutdown.enabled=true

7. Expose All Endpoints

This is not a good idea to do in a production environment but for learning purposes you are going to do it. Endpoints contain sensitive information, so you must choose wisely what to expose. To expose all the endpoints, add the line below to your properties file.

application.properties

management.endpoints.web.exposure.include=*

Next is to configure Spring Security to allow you to access the endpoints.

MainSecurity.java

package com.javacodegeeks.example;

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class MainSecurity extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
			.anyRequest().permitAll();
	}
}

The code above allows all endpoint requests to be permitted. Happy days! You should now be able to access /actuator/health, /actuator/beans, /actuator/heapdump, etc. and see some JSON response.

/actuator/env

{
  "activeProfiles": [],
  "propertySources": [
    {
      "name": "server.ports",
      "properties": {
        "local.management.port": {
          "value": 9090
        },
        "local.server.port": {
          "value": 8080
        }
      }
    },
    {
      "name": "servletContextInitParams",
      "properties": {}
    },
    {
      "name": "systemProperties",
      "properties": {
        "java.runtime.name": {
          "value": "Java(TM) SE Runtime Environment"
        },
        "sun.boot.library.path": {
          "value": "C:\\Program Files\\Java\\jre1.8.0_121\\bin"
        },

The response above is a JSON excerpt of the /actuator/env endpoint.

8. Customizing Endpoint Path and Port

Use the management.endpoints.web.base-path property to change the prefix of your endpoint. The example below sets your endpoint path to start with /monitoring. So instead of /actuator/health, it will now be /monitoring/health.

application.properties

management.endpoints.web.base-path=/monitoring

Use the management.server.port property to change the management server’s HTTP port. The example below sets your port to 9090. So the server is accessible at http://localhost:9090/actuator/health.

application.properties

management.server.port=9090

9. Custom Application Information

Hitting /actuator/info displays your application information. To add your own custom application information, set the info.* Spring properties.

application.properties

info.app.encoding=UTF-8
info.app.java.source=1.7
info.app.java.target=1.7
info.app.motd=Spring Boot Actuator Example

Below is the result when hitting /actuator/info again with the above configuration.

/actuator/info JSON response

{
  "app": {
    "encoding": "UTF-8",
    "java": {
      "source": "1.7",
      "target": "1.7"
    },
    "motd": "Spring Boot Actuator Example"
  }
}

Alternatively, if you’re using spring-boot-starter-parent, you can refer to your Maven project properties with @..@ placeholders. So the above example will look like below:

application.properties

info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@
info.app.motd=Spring Boot Actuator Example

10. Custom Health Information

The default response when hitting /actuator/health is UP, DOWN, UNKNOWN, or OUT_OF_SERVICE. To provide more health information, you need to register Spring beans that implement the HealthIndicator interface.

MainHealthIndicator.java

package com.javacodegeeks.example;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MainHealthIndicator implements HealthIndicator {

	@Override
	public Health health() {
		return Health.down().withDetail("Memory Usage", "Limit reached.").build();
	}

}

You must provide an implementation of the health() method and return a Health response. The Health response must include a status, in this case it’s DOWN. Optionally, you can add details to be displayed.

Below is the result when hitting /actuator/health with the above health indicator implementation.

/actuator/health JSON response

{
  "status": "DOWN",
  "details": {
    "main": {
      "status": "DOWN",
      "details": {
        "Memory Usage": "Limit reached."
      }
    },
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 243164770304,
        "free": 72515084288,
        "threshold": 10485760
      }
    }
  }
}

11. Your Own Web Endpoint

You can also add your very own endpoint. You simply create a bean and annotate it with @Endpoint and annotate your method with @ReadOperation. For the sake of simplicity, the example below will just respond with the word of the day but this is where your monitoring logic should be.

WotdEndpoint.java

package com.javacodegeeks.example;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

@Component
@Endpoint(id = "wotd", enableByDefault = true)
public class WotdEndpoint {
	
	@ReadOperation
	public String wordOfTheDay() {
		return "{\"wotd\": \"Brilliant\"}";
	}

}

/actuator/wotd JSON response

{"wotd": "Brilliant"}

12. Spring Boot Actuator Summary

There you have it. Are you now more familiar with Spring Boot Actuator? In this example, you were able to use the actuators for your web application, enabled and exposed your endpoints. Furthermore, you created your own endpoint, customized existing endpoint output, and changed the endpoint path and the management server port. For more information go to Spring Data Actuator.

13. Download the Source Code

This is an example about Spring Boot Actuator.

Download
You can download the source code of this example here: spring-boot-actuator.zip.

Joel Patrick Llosa

I graduated from Silliman University in Dumaguete City with a degree in Bachelor of Science in Business Computer Application. I have contributed to many Java related projects at Neural Technologies Ltd., University of Southampton (iSolutions), Predictive Technologies, LLC., Confluence Service, North Concepts, Inc., NEC Telecom Software Philippines, Inc., and NEC Technologies Philippines, Inc. You can also find me in Upwork freelancing as a Java Developer.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button