Spring Boot Actuator | Monitor Rest API using spring boot actuator

Imran Shaikh
1

I had built a Rest API using the spring boot framework and release it to the production. However, I was wondering, is there any way to monitor my Rest API?


After some research, I founded a tool to monitor my rest API, which is a Spring Boot Actuator. In this article, I'll walk you through how to use the spring boot actuator to monitor your rest API.


Project source code is available at (getButton) #text=(GitHub) #icon=(download) #color=(#000000)

Spring Boot Actuator Monitor Rest API Thumbnail Image
toc

Prerequisite


1. How to build Rest API using the Spring boot

2. Java 8 or later, I'll use Amazon Corretto 11

3. Maven


What is the Spring Boot Actuator?


The Spring boot Actuator is a tool to monitor your rest API. The spring boot actuator presents numerous endpoints to observe your Rest API.


Some of the endpoints which very beneficial in the productions are health, info, metrics, httptrace etc.


Project structure


Spring boot actuator project structure by the learnjavaskills.in

You can find github source code from here.


Maven dependencies


Maven dependency for Spring boot project

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
 </dependency>

The latest verion for the Spring-boot-starter-actuator dependency will be found from here. However, you can avoid the version tag because spring boot is capable of handling version for this dependency for you.


Maven dependency for maven project

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-actuator</artifactId>
     <version>2.3.4.RELEASE</version>
 </dependency>

The latest version for the maven project is available here.


How to access the Spring boot actuator?


The Spring boot actuator is the sub-project of the Spring boot framework, so the spring boot allows the auto-configuration for you.


Once you have added the spring boot actuator dependency in the pom.xml of the spring boot project, you are ready to monitory your rest API by using the following endpoint.


http://localhost:8080/actuator(code-box)

Once you access the above URL in your favorite browser, you will get the JSON document of the spring boot actuator endpoints.


 {
     _links: {
         self: {
         href: "http://localhost:8080/actuator",
         templated: false
         },
         health: {
         href: "http://localhost:8080/actuator/health",
         templated: false
         },
         health-path: {
         href: "http://localhost:8080/actuator/health/{*path}",
         templated: true
         },
         info: {
         href: "http://localhost:8080/actuator/info",
         templated: false
         }
     }
 }

Default spring boot actuator endpoints


If you take a closer look, you will get two spring boot actuator endpoints, such as health, and info. By default, these two endpoints are exposed via the web API.


The health endpoint

Let us check the health of the spring boot project by using the health endpoint of the spring boot actuator.


http://localhost:8080/actuator/health(code-box)

{ status: "UP" }(code-box)

The Status UP means your application is running.


Display more health information

In the default health actuator endpoint, we only get the status of our application. What if we want more information like disk space. Let's configure our application to monitor the disk space in the health endpoint.


management.endpoint.health.show-details=always(code-box)

Add the above configuration in the application.properties file and relaunch your application. Now you will get more information in the health endpoint.


 {
     status: "UP",
     components: {
         diskSpace: {
             status: "UP",
             details: {
                 total: 187904815104,
                 free: 116903780352,
                 threshold: 10485760,
                 exists: true
             }
         },
         ping: {
            status: "UP"
         }
     }
  }

The info endpoint

Let's use the info endpoint, which is


http://localhost:8080/actuator/info(code-box)

Surely you will get empty information here because we have not configured the info endpoint yet.


{ }(code-box)

Spring boot framework provides two ways to configure info endpoint.
  • application.properties or application.yml
  • Java-based configuration
(alert-success)

The info endpoint configure using the application.properties

To configure info endpoint using the application.properties, use info prefix, and followed by your desire properties name. In the below example, we have mention our project name.


info.application.name=SpringBootActuatord(code-box)

The info endpoint configure using java code

Well, if we can configure info endpoint using the application.properties or application.yml then why need to use java code?


What if you want dynamic information in the info endpoint. To display dynamic information in the info endpoint we can use java base configuration. Let's configure the info endpoint using the java.


 package in.learnjavaskills.springbootactuator.actuatorConfigure;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.actuate.info.Info.Builder;
 import org.springframework.boot.actuate.info.InfoContributor;
 import org.springframework.context.annotation.Configuration;
 import in.learnjavaskills.springbootactuator.service.UserService;
 @Configuration
 public class InfoConfigure implements InfoContributor
 {
     @Autowired
     private UserService userService;
     @Override
     public void contribute(Builder builder)
     {
         builder.withDetail("Active Users", userService.getActiveusers());
     }
 }

To configure the info endpoint in the spring boot, you must implements the InfoContributor interface.


Once you implements InfoContributor, then you must override the contribute method as shown in the above example.


The contribute method has one argument which Builder static class.


To add the information in the info endpoint, you must call the withDetail method of the Builder static class. The withDetail method accepts two parameters, Key in the form of String and the value in the form of Object.


In this example, we are displaying the number of active users in our rest API. You can find the source code from the (getButton) #text=(GitHub) #icon=(download) #color=(#000000)


Let's run the application to check the info endpoint

After configuring the info endpoint, if you run this application you will get the following document.


 {
    application: {
        name: "SpringBootActuatord"
    },
    Active Users: [{
        username: "Imran Shaikh"
    },
    {
        username: "LearnJavaSkills.in"
    }]
 }

Important spring boot actuator endpoint


By default spring boot actuator display only two endpoints, info, and health via web APIs. The spring boot actuator also exposes others' endpoints via JMX.


To expose other endpoints, we can use application.properties to enable them. Write the following code in the application.properties files.


management.endpoints.web.exposure.include=*(code-box)

The * means, enable all the endpoints. Now relaunch your Rest API and hit to actuator URL to watch the magic of the spring boot actuator.


http://localhost:8080/actuator(code-box)
 {
    _links: {
    self: {
    href: "http://localhost:8080/actuator",
    templated: false
    },
    beans: {
    href: "http://localhost:8080/actuator/beans",
    templated: false
    },
    caches-cache: {
    href: "http://localhost:8080/actuator/caches/{cache}",
    templated: true
    },
    caches: {
    href: "http://localhost:8080/actuator/caches",
    templated: false
    },
    health: {
    href: "http://localhost:8080/actuator/health",
    templated: false
    },
    health-path: {
    href: "http://localhost:8080/actuator/health/{*path}",
    templated: true
    },
    info: {
    href: "http://localhost:8080/actuator/info",
    templated: false
    },
    conditions: {
    href: "http://localhost:8080/actuator/conditions",
    templated: false
    },
    configprops: {
    href: "http://localhost:8080/actuator/configprops",
    templated: false
    },
    env: {
    href: "http://localhost:8080/actuator/env",
    templated: false
    },
    env-toMatch: {
    href: "http://localhost:8080/actuator/env/{toMatch}",
    templated: true
    },
    loggers: {
    href: "http://localhost:8080/actuator/loggers",
    templated: false
    },
    loggers-name: {
    href: "http://localhost:8080/actuator/loggers/{name}",
    templated: true
    },
    heapdump: {
    href: "http://localhost:8080/actuator/heapdump",
    templated: false
    },
    threaddump: {
    href: "http://localhost:8080/actuator/threaddump",
    templated: false
    },
    metrics-requiredMetricName: {
    href: "http://localhost:8080/actuator/metrics/{requiredMetricName}",
    templated: true
    },
    metrics: {
    href: "http://localhost:8080/actuator/metrics",
    templated: false
    },
    scheduledtasks: {
    href: "http://localhost:8080/actuator/scheduledtasks",
    templated: false
    },
    mappings: {
    href: "http://localhost:8080/actuator/mappings",
    templated: false
    }
    }
 }

How to enable only required actuator endpoint

If you are wondering how to enable only a specific required endpoint? Then, you are on the right path. Enabling all the unnecessary endpoints in the production can cause you OutOfMemoryError Exception.


Let's enable only health, info, env, and metrics endpoints.


management.endpoints.web.exposure.include=info, health, env, metrics(code-box)

Update your application.preoperties to the above code. Now it will expose only those four endpoints like below.


 {
    _links: {
    self: {
    href: "http://localhost:8080/actuator",
    templated: false
    },
    health: {
    href: "http://localhost:8080/actuator/health",
    templated: false
    },
    health-path: {
    href: "http://localhost:8080/actuator/health/{*path}",
    templated: true
    },
    info: {
    href: "http://localhost:8080/actuator/info",
    templated: false
    },
    env: {
    href: "http://localhost:8080/actuator/env",
    templated: false
    },
    env-toMatch: {
    href: "http://localhost:8080/actuator/env/{toMatch}",
    templated: true
    },
    metrics-requiredMetricName: {
    href: "http://localhost:8080/actuator/metrics/{requiredMetricName}",
    templated: true
    },
    metrics: {
    href: "http://localhost:8080/actuator/metrics",
    templated: false
    }
    }
 }

How to enable httptrace endpoint on spring boot 2.2 or later version


If you are using the Spring boot version 2.2 or later, you will not find the httptrace endpoint by default enabled.


After the spring boot 2.2 or later version, Because of a large amount of memory used by the httptrace, The spring decided to disable this endpoint.


But wait a minute, if httptrace occupies a large amount of the memory then why we should enable this endpoint?


Well, The httptrace endpoints produce the history of the Rest API URL have been accessed. In the same case, it's very important to monitor the history of the accessed URL by the user to debug the issue.


Let's enable httptrace by creating the @Bean of HttpTraceRepository.


 package in.learnjavaskills.springbootactuator.actuatorConfigure;
 import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
 import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 @Configuration
 public class HttpTraceConfigure
 {
     @Bean
     public HttpTraceRepository enableHttpTrace()
     {
         return new InMemoryHttpTraceRepository();
     }
 }

Now, add the httptrace in the application.properties.


management.endpoints.web.exposure.include=info, health, env, metrics, httptrace(code-box)

Now launch the httptrace endpoint by visiting the following URL


http://localhost:8080/actuator/httptrace(code-box)

 {
    traces: [
    {
        timestamp: "2020-10-17T15:43:56.107815100Z",
        principal: null,
        session: null,
        request: {},
        response: {},
        timeTaken: 64
    }
    ]
}

NOTE: In the above JSON document, we are not displaying an array of requests and response data. You can explorer more.


How to filter httptrace actuator endpoint

Why you should filter actuator endpoint from httptrace history?


The httptrace by default allows a maximum of last 100 requests only and it's store in memory. If you can take a closer look at the httptrace history, you will find an actuator endpoint as well. This actuator endpoint in the httptrace history makes no sense. That the main reason to filter out this request.


 package in.learnjavaskills.springbootactuator.actuatorConfigure;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import org.springframework.boot.actuate.trace.http.HttpExchangeTracer;
 import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
 import org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter;
 import org.springframework.stereotype.Component;
 @Component
 public class HttpTraceFilterConfigure extends HttpTraceFilter
 {
     public HttpTraceFilterConfigure(HttpTraceRepository repository, HttpExchangeTracer tracer)
     {
         super(repository, tracer);
     }
    
     @Override
     protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException
     {
         return request.getServletPath()
                       .contains("actuator");
     }
 }

Conclusion


In this tutorial, we had learned what is the spring boot actuator and how to monitor our Rest API using the spring boot actuator.


We have also seen how to override the default properties of the spring boot actuator by using the application.properties or Java base configuration.


If you have enjoyed reading this article, please subscribe to the LearnJavaSkills, So that in the future if I publish a new article you don't miss it. The subscription link is available at the top of the menu bar and at the sidebar.


Thanks for reading and keep learning, keep growing.

(getButton) #text=(Next: Document Your Rest API With Swagger) #icon=(link) #color=(#2339bd)

Post a Comment

1 Comments
Post a Comment

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !
To Top