Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Latest commit

 

History

History
486 lines (432 loc) · 16.5 KB

lab03.adoc

File metadata and controls

486 lines (432 loc) · 16.5 KB

Enhancing Boot Application with Metrics

Set up the Actuator

Spring Boot includes a number of additional features to help you monitor and manage your application when it’s pushed to production. These features are added by adding spring-boot-starter-actuator to the classpath. During our initial project setup with start.spring.io we’ve already included that.

  1. Verify the Spring Boot Actuator dependency the following file: /cloud-native-spring/pom.xml. You should see the following dependency in the list:

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  2. By default Spring Boot will use Spring Security to protect these management endpoints (which is a good thing!). Though you wouldn’t want to disable this in production, we’ll do so in this sample app to make demonstration a bit easier and simpler. . Add the following properties to cloud-native-spring/src/main/resources/application.yml. You must create the file first.

    endpoints: # add this section
      sensitive: false
  3. Run the updated application

    $ mvn clean spring-boot:run

    Try out the following endpoints. The output is omitted here because it can be quite large:

    Displays Application and Datasource health information. This can be customized based on application functionality, which we’ll do later.

    Dumps all of the beans in the Spring context.

    Dumps all of the auto-configuration performed as part of application bootstrapping.

    Displays a collated list of all @ConfigurationProperties.

    Dumps the application’s shell environment as well as all Java system properties.

    Dumps all URI request mappings and the controller methods to which they are mapped.

    Performs a thread dump.

    Displays trace information (by default the last few HTTP requests).

  4. Stop the cloud-native-spring application.

Include Version Control Info

Spring Boot provides an endpoint (http://localhost:8080/info) that allows the exposure of arbitrary metadata. By default, it is empty.

One thing that actuator does well is expose information about the specific build and version control coordinates for a given deployment.

  1. Edit the following file: /cloud-native-spring/pom.xml. Add the git-commit-id-plugin to your Maven build. You must edit the file and add the plugin code below into the existing <plugins> XML structure, which should already have one plugin defined. The git-commit-id-plugin adds Git branch and commit coordinates to the /info endpoint:

    <plugin>
    	<groupId>pl.project13.maven</groupId>
    	<artifactId>git-commit-id-plugin</artifactId>
    	<configuration>
    		<dotGitDirectory>../../../.git</dotGitDirectory>
    	</configuration>
    </plugin>

    NOTE The path ../../../.git refers to the .git directory at the root of the lab materials repo.

    Completed:

    <?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>io.pivotal</groupId>
    	<artifactId>cloud-native-spring</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>cloud-native-spring</name>
    	<description>Demo project for Spring Boot</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.2.8.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-actuator</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-rest</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>com.h2database</groupId>
    			<artifactId>h2</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    			<plugin>
    				<groupId>pl.project13.maven</groupId>
    				<artifactId>git-commit-id-plugin</artifactId>
    				<configuration>
    					<dotGitDirectory>../../../.git</dotGitDirectory>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    
    
    </project>
  2. Run the cloud-native-spring application:

    $ mvn clean spring-boot:run

  3. Browse to http://localhost:8080/info. Git commit information is now included

    {
     "git":{
        "branch": "master",
        "commit": {
          "id": "123456",
          "time": "2016-03-03T12:05:10-0500"
        }
      }
    }
  4. Stop the cloud-native-spring application

    What Just Happened?

    By including the git-commit-id-plugin, details about git commit information will be included in the /info endpoint. Git information is captured in a git.properties file that is generated with the build. Review the following file: /cloud-native-spring/target/classes/git.properties

Include Build Info

  1. Add the following properties to cloud-native-spring/src/main/resources/application.yml. You must create the file first.

    info: # add this section
      build:
        artifact: @project.artifactId@
        name: @project.name@
        description: @project.description@
        version: @project.version@

    These will add the project’s Maven coordinates to the /info endpoint. The Spring Boot Maven plugin will cause them to automatically be replaced in the assembled JAR.

    NOTE: if STS reports a problem with the application.yml due to @ character the problem can safely be ignored.

  2. Build and run the cloud-native-spring application:

    $ mvn clean spring-boot:run
  3. Browse to http://localhost:8080/info. Build information is now included.

    {
     "build": {
        "artifact": "cloud-native-spring",
        "name": "cloud-native-spring",
        "description": "Demo project for Spring Boot",
        "version": "0.0.1-SNAPSHOT"
     },
     "git":{
        "branch": "master",
        "commit": {
          "id": "123456",
          "time": "2016-03-03T12:05:10-0500"
        }
      }
    }
  4. Stop the cloud-native-spring application.

    What Just Happened?

    We have mapped Maven properties from the pom.xml into the /info endpoint.

    Read more about exposing data in the /info endpoint here

Health Indicators

Spring Boot provides an endpoint http://localhost:8080/health that exposes various health indicators that describe the health of the given application.

Normally, when Spring Security is not enabled, the /health endpoint will only expose an UP or DOWN value.

{
  "status": "UP"
}
  1. To simplify working with the endpoint for this lab, we will turn off additional security for the health endpoint. Add the following to /cloud-native-spring/src/main/resources/application.yml:

    management:
      security:
        enabled: false
  2. Build and run the cloud-native-spring application:

    $ mvn clean spring-boot:run
  3. Browse to http://localhost:8080/health. Out of the box is a DiskSpaceHealthIndicator that monitors health in terms of available disk space. Would your Ops team like to know if the app is close to running out of disk space? DiskSpaceHealthIndicator can be customized via DiskSpaceHealthIndicatorProperties. For instance, setting a different threshold for when to report the status as DOWN.

    {
      "status": "UP",
      "diskSpace": {
          "status": "UP",
          "free": 42345678945,
          "threshold": 12345678
      }
    }
  4. Stop the cloud-native-spring application.

  5. Create the class io.pivotal.FlappingHealthIndicator (/cloud-native-spring/src/main/java/io/pivotal/FlappingHealthIndicator.java) and into it paste the following code:

    package io.pivotal;
    
    import java.util.Random;
    
    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.actuate.health.HealthIndicator;
    import org.springframework.stereotype.Component;
    
    @Component
    public class FlappingHealthIndicator implements HealthIndicator {
    
        private Random random = new Random(System.currentTimeMillis());
    
        @Override
        public Health health() {
            int result = random.nextInt(100);
            if (result < 50) {
                return Health.down().withDetail("flapper", "failure").withDetail("random", result).build();
            } else {
                return Health.up().withDetail("flapper", "ok").withDetail("random", result).build();
            }
        }
    }

    This demo health indicator will randomize the health check.

  6. Build and run the cloud-native-spring application:

    $ mvn clean spring-boot:run
  7. Browse to http://localhost:8080/health and verify that the output is similar to the following (and changes randomly!).

    {
      "status": "UP",
      "flapping": {
          "status": "UP",
          "flapper": "ok",
          "random": 42
      },
      "diskSpace": {
          "status": "UP",
          "free": 42345678945,
          "threshold": 12345678
      }
    }

Metrics

Spring Boot provides an endpoint http://localhost:8080/metrics that exposes several automatically collected metrics for your application. It also allows for the creation of custom metrics.

  1. Browse to http://localhost:8080/metrics. Review the metrics exposed.

    {
    "mem": 418830,
    "mem.free": 239376,
    "processors": 8,
    "instance.uptime": 59563,
    "uptime": 69462,
    "systemload.average": 1.5703125,
    "heap.committed": 341504,
    "heap.init": 262144,
    "heap.used": 102127,
    "heap": 3728384,
    "nonheap.committed": 79696,
    "nonheap.init": 2496,
    "nonheap.used": 77326,
    "nonheap": 0,
    "threads.peak": 14,
    "threads.daemon": 11,
    "threads.totalStarted": 17,
    "threads": 13,
    "classes": 9825,
    "classes.loaded": 9825,
    "classes.unloaded": 0,
    "gc.ps_scavenge.count": 9,
    "gc.ps_scavenge.time": 80,
    "gc.ps_marksweep.count": 2,
    "gc.ps_marksweep.time": 157,
    "httpsessions.max": -1,
    "httpsessions.active": 0,
    "gauge.response.metrics": 75,
    "gauge.response.star-star.favicon.ico": 9,
    "counter.status.200.star-star.favicon.ico": 1,
    "counter.status.200.metrics": 1
    }
  2. Stop the cloud-native-spring application.

Deploy cloud-native-spring to Pivotal Cloud Foundry

  1. Build the application

    $ mvn clean package
  2. When running a Spring Boot application on Pivotal Cloud Foundry with the actuator endpoints enabled, you can visualize actuator management information on the Applications Manager app dashboard. To enable this there are a few properties we need to add. Add the following to /cloud-native-spring/src/main/resources/application.yml:

    management:
      security:
        enabled: false
      info:
        git:
          mode: full
      cloudfoundry:
        enabled: true
        skip-ssl-validation: true
  3. In order to add full build information to you artifact that is pushed to cloudfoundry, update /cloud-native-spring/pom.xml and add the following execution and classifier to the spring-boot-maven-plugin:

    <executions>
      <execution>
    	  <goals>
    		  <goal>build-info</goal>
    		</goals>
    	</execution>
    </executions>
    <configuration>
    	<classifier>exec</classifier>
    </configuration>

    The full plugin config should look like the following:

    <plugin>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-maven-plugin</artifactId>
    	<executions>
    		<execution>
    			<goals>
    			  <goal>build-info</goal>
    		  </goals>
    	  </execution>
      </executions>
    	<configuration>
    	  <classifier>exec</classifier>
      </configuration>
    </plugin>
  4. By specifying a classifier we actually just produced 2 jars, one that is executable and one that can be used as an artifact that could be included in other apps (such as our Client UI app we’ll create later). Because of this we need to chance the name of the jar we included in our manifest.yml file. Change the jar in the path property to ./target/cloud-native-spring-0.0.1-SNAPSHOT-exec.jar:

    ---
    applications:
    - name: cloud-native-spring
      host: cloud-native-spring
      memory: 512M
      instances: 1
      path: ./target/cloud-native-spring-0.0.1-SNAPSHOT-exec.jar
      buildpack: java_buildpack_offline
      timeout: 180 # to give time for the data to import
      env:
        JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
  5. Push application into Cloud Foundry

    $ cf push -f manifest.yml

  6. Find the URL created for your app in the health status report. Browse to your app. Also view your application details in the Apps Mananger UI:

    appsman
  7. From this UI you can also dynamically change logging levels:

    logging

Congratulations! You’ve just learned how to add health and metrics to any Spring Boot application.