Search This Blog

Sunday 4 March 2018

Spring boot 2 Actuator Support and Pivotal Cloud Foundry 2.0

With Spring Boot Actuator you get production-ready features to your application. The main benefit of this library is that we can get production grade tools without having to actually implement these features ourselves.

Actuator is mainly used to expose operational information about the running application – health, metrics, info, dump, env, etc. It uses HTTP endpoints or JMX beans to enable us to interact with it.

In this post we will show how Spring Boot 2.0 Actuator endpoints are automatically integrated into Pivotal Cloud Foundry Apps Manager.

1. Clone the following project as shown below

pasapicella@pas-macbook:~/temp$ git clone https://github.com/papicella/springboot-actuator-2-demo.git
Cloning into 'springboot-actuator-2-demo'...
remote: Counting objects: 57, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 57 (delta 0), reused 6 (delta 0), pack-reused 48
Unpacking objects: 100% (57/57), done.

2. Package as follows

pasapicella@pas-macbook:~/temp/springboot-actuator-2-demo$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building springboot-autuator-2-demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ springboot-autuator-2-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource

...

[INFO]
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ springboot-autuator-2-demo ---
[INFO] Building jar: /Users/pasapicella/temp/springboot-actuator-2-demo/target/springboot-autuator-2-demo-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.0.0.M7:repackage (default) @ springboot-autuator-2-demo ---
[INFO]
[INFO] --- maven-dependency-plugin:3.0.1:unpack (unpack) @ springboot-autuator-2-demo ---
[INFO] Configured Artifact: com.example:springboot-autuator-2-demo:0.0.1-SNAPSHOT:jar
[INFO] Unpacking /Users/pasapicella/temp/springboot-actuator-2-demo/target/springboot-autuator-2-demo-0.0.1-SNAPSHOT.jar to /Users/pasapicella/temp/springboot-actuator-2-demo/target/dependency with includes "" and excludes ""
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.650 s
[INFO] Finished at: 2018-03-04T21:04:08+11:00
[INFO] Final Memory: 46M/594M
[INFO] ------------------------------------------------------------------------

3. Deploy as follows

pasapicella@pas-macbook:~/temp/springboot-actuator-2-demo$ cf push
Pushing from manifest to org apples-pivotal-org / space development as papicella@pivotal.io...
Using manifest file /Users/pasapicella/temp/springboot-actuator-2-demo/manifest.yml
Getting app info...
Updating app with these attributes...
  name:                springboot-actuator-appsmanager
  path:                /Users/pasapicella/temp/springboot-actuator-2-demo/target/springboot-autuator-2-demo-0.0.1-SNAPSHOT.jar
  buildpack:           client-certificate-mapper=1.5.0_RELEASE container-security-provider=1.13.0_RELEASE java-buildpack=v4.9-offline-https://github.com/cloudfoundry/java-buildpack.git#830f4c3 java-main java-opts java-security jvmkill-agent=1.12.0_RELEASE open-jdk-l...
  command:             JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.12.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security $JAVA_OPTS" && CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.10.0_RELEASE -totMemory=$MEMORY_LIMIT -stackThreads=250 -loadedClasses=17785 -poolType=metaspace -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 SERVER_PORT=$PORT eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher
  disk quota:          1G
  health check type:   port
  instances:           1
  memory:              1G
  stack:               cflinuxfs2
  routes:
    springboot-actuator-appsmanager-forgiving-camel.cfapps.io

Updating app springboot-actuator-appsmanager...
Mapping routes...
Comparing local files to remote cache...
Packaging files to upload...
Uploading files...

...

Waiting for app to start...

name:              springboot-actuator-appsmanager
requested state:   started
instances:         1/1
usage:             1G x 1 instances
routes:            springboot-actuator-appsmanager-forgiving-camel.cfapps.io
last uploaded:     Sun 04 Mar 21:07:03 AEDT 2018
stack:             cflinuxfs2
buildpack:         client-certificate-mapper=1.5.0_RELEASE container-security-provider=1.13.0_RELEASE java-buildpack=v4.9-offline-https://github.com/cloudfoundry/java-buildpack.git#830f4c3
                   java-main java-opts java-security jvmkill-agent=1.12.0_RELEASE open-jdk-l...
start command:     JAVA_OPTS="-agentpath:$PWD/.java-buildpack/open_jdk_jre/bin/jvmkill-1.12.0_RELEASE=printHeapHistogram=1 -Djava.io.tmpdir=$TMPDIR
                   -Djava.ext.dirs=$PWD/.java-buildpack/container_security_provider:$PWD/.java-buildpack/open_jdk_jre/lib/ext -Djava.security.properties=$PWD/.java-buildpack/java_security/java.security
                   $JAVA_OPTS" && CALCULATED_MEMORY=$($PWD/.java-buildpack/open_jdk_jre/bin/java-buildpack-memory-calculator-3.10.0_RELEASE -totMemory=$MEMORY_LIMIT -stackThreads=250 -loadedClasses=17785
                   -poolType=metaspace -vmOptions="$JAVA_OPTS") && echo JVM Memory Configuration: $CALCULATED_MEMORY && JAVA_OPTS="$JAVA_OPTS $CALCULATED_MEMORY" && MALLOC_ARENA_MAX=2 SERVER_PORT=$PORT
                   eval exec $PWD/.java-buildpack/open_jdk_jre/bin/java $JAVA_OPTS -cp $PWD/. org.springframework.boot.loader.JarLauncher

     state     since                  cpu      memory         disk           details
#0   running   2018-03-04T10:08:16Z   196.2%   385.7M of 1G   157.4M of 1G

4. The application.yml exposes all methods and is totally unsecure so you would not want to do this in a production application. The application is deployed using an application.yml as follows.

spring:
  application:
    name: PCFSpringBootActuatorDemo
  jpa:
    hibernate:
      ddl-auto: update
management:
  endpoint:
    health:
      show-details: true
  endpoints:
    web:
      expose: '*'
      enabled: true
    jmx:
      expose: '*'
      enabled: true

Once deployed Pivotal Cloud Foundry Apps Manager will show the Spring Icon and use the Actuator endpoints.





Lets invoke some of the Actuator endpoints using HTTPIE or CURL if you like. Remember we have exposed all web endpoints allowing us to do this. One thing that has changed form Actuator 1.x to 2.0 is the endpoints are now mapped to /actuator out of the box. You can get all that are available endpoints just by invoking /actuator as shown below using a GET RESTful call.

pasapicella@pas-macbook:~/temp/springboot-actuator-2-demo$ http http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Sun, 04 Mar 2018 10:13:38 GMT
X-Vcap-Request-Id: 22116a58-f689-4bd9-448c-023bae2ed5ec
transfer-encoding: chunked

{
    "_links": {
        "auditevents": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/auditevents",
            "templated": false
        },
        "beans": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/beans",
            "templated": false
        },
        "conditions": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/conditions",
            "templated": false
        },
        "configprops": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/configprops",
            "templated": false
        },
        "env": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/env",
            "templated": false
        },
        "env-toMatch": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/env/{toMatch}",
            "templated": true
        },
        "health": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/health",
            "templated": false
        },
        "heapdump": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/heapdump",
            "templated": false
        },
        "info": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/info",
            "templated": false
        },
        "loggers": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/loggers",
            "templated": false
        },
        "loggers-name": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/loggers/{name}",
            "templated": true
        },
        "mappings": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/mappings",
            "templated": false
        },
        "metrics": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/metrics",
            "templated": false
        },
        "metrics-requiredMetricName": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/metrics/{requiredMetricName}",
            "templated": true
        },
        "scheduledtasks": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/scheduledtasks",
            "templated": false
        },
        "self": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator",
            "templated": false
        },
        "threaddump": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/threaddump",
            "templated": false
        },
        "trace": {
            "href": "http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/trace",
            "templated": false
        }
    }
}

pasapicella@pas-macbook:~/temp/springboot-actuator-2-demo$ http http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/health
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 183
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Sun, 04 Mar 2018 10:16:03 GMT
X-Vcap-Request-Id: be45c751-b77d-4e7c-77b6-0d7affa0fe16

{
    "details": {
        "db": {
            "details": {
                "database": "H2",
                "hello": 1
            },
            "status": "UP"
        },
        "diskSpace": {
            "details": {
                "free": 908681216,
                "threshold": 10485760,
                "total": 1073741824
            },
            "status": "UP"
        }
    },
    "status": "UP"
}

pasapicella@pas-macbook:~/temp/springboot-actuator-2-demo$ http http://springboot-actuator-appsmanager-forgiving-camel.cfapps.io/actuator/trace
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Sun, 04 Mar 2018 10:19:46 GMT
X-Vcap-Request-Id: e0c86f51-dcc4-4349-41d2-6b603677c3f4
transfer-encoding: chunked

{
    "traces": [
        {
            "info": {
                "headers": {
                    "request": {
                        "accept": "*/*",
                        "accept-encoding": "gzip, deflate",
                        "host": "springboot-actuator-appsmanager-forgiving-camel.cfapps.io",
                        "user-agent": "HTTPie/0.9.9",
                        "x-b3-spanid": "0ad427a9f13bad0c",
                        "x-b3-traceid": "0ad427a9f13bad0c",
                        "x-cf-applicationid": "c1e50a41-5e1e-475f-b9e6-116a7acd98a2",
                        "x-cf-instanceid": "db74a5d2-ac72-4c45-539a-118f",
                        "x-cf-instanceindex": "0",
                        "x-forwarded-port": "80",
                        "x-forwarded-proto": "http",
                        "x-request-start": "1520158694338",
                        "x-vcap-request-id": "5f1e5572-a841-4e3f-4b6f-2cfd0c0ccc8e"
                    },
                    "response": {
                        "Content-Type": "application/vnd.spring-boot.actuator.v2+json;charset=UTF-8",
                        "Date": "Sun, 04 Mar 2018 10:18:14 GMT",

...

More Information

https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html

No comments: