zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    对在Qtopia中添加国际化支持一文补充
    在Redhat中添加微软雅黑字体
    QGridLayout中multi cell处理
    QScrollArea处理与显示问题
    升级ubuntu后EMACS 无法使用
    在Qtopia中添加国际化支持
    Delphi面向对象编程的20条规则
    Spring AOP 实例
    使用Dynamic LINQ实现Ext Grid的远程排序
    高效实现数据仓库的七个步骤
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696544.html
Copyright © 2011-2022 走看看