Overview:

When planning the deployment SpringBoot¬† (or any Spring Framework) JAR applications to your production enterprise, the first question from IT and Application Hosting is “how do we monitor this Java app?”. Their faces usually portraying the prospect of stitching together yet another Nagios plugin to sense disruptions in the Java run-time force …

SpringBoot Actuator to the rescue! As part of the Spring Framework, Spring Actuator, can easily be implemented to provide a wide range of monitoring tools and metrics through simple RESTful JSON. In fact, the list of all end-points and features exposed through Spring Actuator is too complex for a single article.

Here is a simple, yet tremendously useful, internal /health Actuator system status end-point published on an exclusive port, separate and isolated from the applications main entry end-points:

Prerequisites

Procedure:

This article provides a brief overview of implementing SpringBoot Actuator into a simple REST application. Example project code is provided on our BitBucket site.

1. Setting Up the Spring Actuator Dependencies in the POM:

The POM changes are as follows, and can be used to add Spring Actuator to any of your SpringBoot REST applications. There are three org.springframework.boot artifacts that are required; we do not specify a version, but let SpringBoot choose the appropriate curated version for our build.

  • spring-boot-starter-actuator includes everything we need to publish monitoring REST end points.
  • spring-boot-starter-web is required, as this is a requirement for the following Spring Security framework.
  • spring-boot-starter-security is required, as several of the end-points provide administrative-level monitoring and access to your deployment system.
    • Discussion of Spring Security implementation will take several follow-on articles; we will scratch the surface of possibilities in this article.
    • Other Spring derivatives from Spring Security, such as Spring OAUTH, can also be used to authorize access to actuator end points. This will be addresses in future articles.
<?xml version="1.0" encoding="UTF-8"?>
<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.paulsdevblog</groupId>
    <artifactId>hellospringaccuator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>hellospringaccuator</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Actuator Dependency START -->
        <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-security</artifactId> 
        </dependency>
        <!-- Spring Actuator Dependency END -->
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. Setting Up the Spring Actuator End Points in application.properties:

As shown below, I have broke down Spring Actuator configuration into three areas within the application.properties file.

  • The “management.” properties specify the port and address that the Spring Actuator end-points will be published on. This provides a great way for your IT and Application Hosting team to setup monitoring end-points internally and unexposed to the internet.
    > In our example, we have the Actuator endpoints publishing on port 9011.
  • You may wish to include system identifers, information or other instance attributes in your monitoring end points, the “info.” properties provide a method for you to create any number of custom information properties for display purposes.
  • There are many Spring Actuator metric sub-applications and end-points that can be exposed with the “endpoint.” properties.
    • IMPORTANT: Many of the Actuator end points publish administrative details about your system and expose administrative functions. Ensure you review each of the end-points features and implement an authorization scheme as appropriate.
    • We shall be enabling and investigating the /health, /auditevents, /env (environment), /info, /logging,¬† and /trace end points.

#server.address=
server.port=9006

#------------REST Field Name JSON spring.jackson-------

spring.jackson.property-naming-strategy=SNAKE_CASE


#------------Spring Actuator Path---------------------

management.context-path=/monitoring
management.port=9011
#management.address=10.10.10.100

#------------Spring Actuator Customer Info message ----

info.app.name=helloSpringAccuator
info.app.custom_id=Custom_Identifier111
info.app.instance_id=Instance_Identifier222

#------------Spring Actuator Metrics------------------

endpoints.auditevents.enabled=true

endpoints.autoconfig.enabled=true

endpoints.beans.enabled=false

endpoints.configprops.enabled=false

endpoints.dump.enabled=false

endpoints.env.enabled=true

endpoints.heapdump.enabled=false

management.health.cassandra.enabled=false

management.health.diskspace.enabled=false

management.info.build.enabled=true

management.info.env.enabled=true

endpoints.jmx.enabled=false

endpoints.loggers.enabled=true

endpoints.mappings.enabled=true

endpoints.shutdown.enabled=false

endpoints.trace.enabled=true

3. Simple WebSecurityConfigurerAdapter for Actuator End-point Authorization

As noted in the introduction, this article is not intended to be a review of Spring Security, as the complexity would require several articles to address. The following will scratch the surface on security and authentication possibilities.

  • As shown in the code snippet below, this class has the @Configuration and @Order annotations to force this to instantiate at the very beginning of the application startup, so this bean takes precedence.

This class is also an extension of the WebSecurityConfigurerAdapter and over-rides two specific methods:

  • configure( AuthenticationManagerBuilder auth ) setups up the authentication management method to be used. In our simple example, we are generating an “in memory” listing of hard-coded users.
  • configure ( HttpSecurity http ) configures how authentication shall be applied to the micro-service’s REST end points. As shown, the authorization build chain ensures that each of the end points published through Actuator is authenticated against the setup AuthenticationManager … in our example, an “in memory” user listing.
package com.paulsdevblog.hellospringactuator.config;


import org.springframework.core.annotation.Order;
import org.springframework.context.annotation.Configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties;
import org.springframework.core.Ordered;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;

/**
 * Simple WebSecurityConfigurerAdapter to enable Spring Actuator
 * 
 * @author PaulsDevBlog.com
 */
@Configuration
@EnableWebSecurity
@Order( Ordered.HIGHEST_PRECEDENCE )
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("monitoruser").password("monitorpwd").roles("ACTUATOR");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        http
            .httpBasic()
            .and()
            .csrf().disable()
            .authorizeRequests() //require detault HTTP authorization for every endpoint here
                .antMatchers("/monitoring/auditevents").permitAll()
                .antMatchers("/monitoring/env").permitAll()
                .antMatchers("/monitoring/health").permitAll()
                .antMatchers("/monitoring/info").permitAll()
                .antMatchers("/monitoring/logging").permitAll()
                .antMatchers("/monitoring/mappings").permitAll()
                .antMatchers("/monitoring/trace").permitAll()
                
        ;
    }

    
}

That’s all that it takes to configure Spring Actuator! Perform a Clean Build and run your micro service application.

Spring Actuator Example End Points

Spring Actuator: /auditevents

Though intended as an auditing tool, I use the /auditevents to debug Spring Security, Oauth and other authentication functions.

Spring Actuator: /env

The /env endpoint provides a lot on in-depth system information and should be protected through your Spring Security scheme, as well as publishing only to an internally accessible port.

The /env end point can also be used to narrowly inquire about specific environment properties. The following screen shot shows how to query the systems JAVA_HOME environment variable:

Spring Actuator: /info

The /info endpoint can display any information you set within the application.properties file, as detailed previously.

Spring Actuator: /loggers

Spring provides several logging frameworks, which can be monitored through the /loggers endpoint. Run-time logging levels and other attributes are published:

Spring Actuator: /metrics

As a complement to the /health end point, the /metrics end point provides a listing of key system and Java run time metrics that can be actively monitored through systems like Nagios. The instance.uptime, mem, and threads are all great performance monitoring data points.

Spring Actuator: /trace

The last end point discussed is /trace.  I use this as a debugging tool, as it reflects the most recent client requests.

BitBucket Repo and Project Code

I use the Actuator end-points listed above during the development, testing and deployment phases of every application build. It’s just too easy to monitor. Thanks, and Like and Link! paulsDevBlog.End();

References: