Complete Guide for Spring 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.

Table of Contents

The sections covered in this post.

  1. What is Spring Boot Actuator?
  2. How to enable spring boot actuator?
  3. Actuator endpoints
  4. Customizing endpoints
  5. Security
  6. Endpoint – Info
  7. Endpoint – Health
  8. Custom Health Endpoint
  9. Endpoint – Metrics
  10. Create custom endpoints
  11. List all the endpoints
  12. Example application
  13. 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 12 endpoints that are currently supported by spring boot actuator module is:

  1. 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.
  2. autoconfig:  Report on auto-configuration details.
  3. beans:  This endpoint lists all the beans loaded by the application.
  4. configprops:  This endpoint shows configuration properties used by your application.
  5. dump:  Performs a thread dump.
  6. env:  Exposes spring’s properties from the configurations.
  7. health:  Health of the application.
  8. info:  Displays application information like version, description, etc.
  9. metrics:  Metrics about memory, heap, etc. for the currently running application
  10. mappings:  Displays a list of all @RequestMapping paths.
  11. shutdown:  This endpoint allows to shutdown the application. This is not enabled by default.
  12. trace:  Displays trace information for the current application.

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 fileapplication.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 server
  • management.address=127.0.0.1 –  restrict to run only on localhost
  • management.context-path=/details  – change the context path for actuator
  • endpoints.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 thespring securityfiles 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 – 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.

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<T>. Any class of type Endpoint<T> 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<T> 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 yourclasspath. Please check your pom.xml and update accordingly to add the spring securityJARs on theclasspath 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)

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

原文地址:https://www.cnblogs.com/duyinqiang/p/5696545.html