Actuator

What is an Actuator?

Spring Boot Actuator module helps you monitor and manage your Spring Boot application by providing production-ready features like health check-up, auditing, metrics gathering, HTTP tracing etc. All of these features can be accessed over JMX or HTTP endpoints.

Actuator also integrates with external application monitoring systems like Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic and many more. These systems provide you with excellent dashboards, graphs, analytics, and alarms to help you monitor and manage your application from one unified interface.

Actuator uses Micrometer, an application metrics facade to integrate with these external application monitoring systems. This makes it super easy to plug-in any application monitoring system with very little configuration.

Creating a Spring Boot application with Actuator

You can create the app using Spring Boot CLI like so

cd ~
spring init -d=web,actuator -n=actuator-demo actuator-demo
Using service at https://start.spring.io
Project extracted to '/home/hadoop/actuator-demo'

Adding Spring Boot Actuator to an existing application

You can add spring-boot-actuator module to an existing spring boot application using the following dependency.

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

Monitoring your application through Actuator Endpoints

Actuator creates several so-called endpoints that can be exposed over HTTP or JMX to let you monitor and interact with your application.

Note that, every actuator endpoint can be explicitly enabled and disabled. Moreover, the endpoints also need to be exposed over HTTP or JMX to make them remotely accessible.

Type the following command from the root directory of the application to run it -

cd ~/actuator-demo
mvn spring-boot:run

Once the application has started, you can list all the actuator endpoints exposed over HTTP from the URL http://localhost:8080/actuator

http http://localhost:8080/actuator
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:20:41 GMT
Transfer-Encoding: chunked

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

By default, only the health and info endpoints are exposed over HTTP. That’s why the /actuator page lists only the health and info endpoints.

You can see the complete list of actuator endpoints on the official documentation.

Enabling and Disabling Actuator Endpoints

You can enable or disable an actuator endpoint by setting the property management.endpoint.<id>.enabled to true or false (where id is the identifier for the endpoint).

For example, to enable the shutdown endpoint, add the following to your application.properties file -

management.endpoint.shutdown.enabled=true

Exposing Actuator Endpoints

By default, all the actuator endpoints are exposed over JMX but only the health and info endpoints are exposed over HTTP.

Here is how you can expose actuator endpoints over HTTP and JMX using application properties -

Exposing Actuator endpoints over HTTP

Use * to expose all endpoints, or a comma-separated list to expose selected ones

management.endpoints.web.exposure.include=health,info
management.endpoints.web.exposure.exclude=

Exposing Actuator endpoints over JMX

Use * to expose all endpoints, or a comma-separated list to expose selected ones

management.endpoints.jmx.exposure.include=*
management.endpoints.jmx.exposure.exclude=

Let’s expose all actuator endpoints by setting the property management.endpoints.web.exposure.include to *

cd ~/actuator-demo
cat << EOF > src/main/resources/application.properties
management.endpoints.web.exposure.include=*
EOF

Check the output of http://localhost:8080/actuator page. You’ll notice that the actuator page now lists all the enabled endpoints-

cd ~/actuator-demo
mvn spring-boot:run
http http://localhost:8080/actuator
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:27:06 GMT
Transfer-Encoding: chunked

{
    "_links": {
        "auditevents": {
            "href": "http://localhost:8080/actuator/auditevents",
            "templated": false
        },
        "beans": {
            "href": "http://localhost:8080/actuator/beans",
            "templated": false
        },
        "caches": {
            "href": "http://localhost:8080/actuator/caches",
            "templated": false
        },
        "caches-cache": {
            "href": "http://localhost:8080/actuator/caches/{cache}",
            "templated": true
        },
        "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
        },
        "health": {
            "href": "http://localhost:8080/actuator/health",
            "templated": false
        },
        "health-component": {
            "href": "http://localhost:8080/actuator/health/{component}",
            "templated": true
        },
        "health-component-instance": {
            "href": "http://localhost:8080/actuator/health/{component}/{instance}",
            "templated": true
        },
        "heapdump": {
            "href": "http://localhost:8080/actuator/heapdump",
            "templated": false
        },
        "httptrace": {
            "href": "http://localhost:8080/actuator/httptrace",
            "templated": false
        },
        "info": {
            "href": "http://localhost:8080/actuator/info",
            "templated": false
        },
        "loggers": {
            "href": "http://localhost:8080/actuator/loggers",
            "templated": false
        },
        "loggers-name": {
            "href": "http://localhost:8080/actuator/loggers/{name}",
            "templated": true
        },
        "mappings": {
            "href": "http://localhost:8080/actuator/mappings",
            "templated": false
        },
        "metrics": {
            "href": "http://localhost:8080/actuator/metrics",
            "templated": false
        },
        "metrics-requiredMetricName": {
            "href": "http://localhost:8080/actuator/metrics/{requiredMetricName}",
            "templated": true
        },
        "scheduledtasks": {
            "href": "http://localhost:8080/actuator/scheduledtasks",
            "templated": false
        },
        "self": {
            "href": "http://localhost:8080/actuator",
            "templated": false
        },
        "threaddump": {
            "href": "http://localhost:8080/actuator/threaddump",
            "templated": false
        }
    }
}

Exploring common actuator endpoints

/health endpoint

http http://localhost:8080/actuator/health
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:27:40 GMT
Transfer-Encoding: chunked

{
    "status": "UP"
}

The status will be UP as long as the application is healthy. It will show DOWN if the application gets unhealthy due to any issue like connectivity with the database or lack of disk space etc.

/metrics endpoint

The /metrics endpoint lists all the metrics that are available for you to track.

http http://localhost:8080/actuator/metrics
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:28:01 GMT
Transfer-Encoding: chunked

{
    "names": [
        "jvm.memory.max",
        "jvm.threads.states",
        "process.files.max",
        "jvm.gc.memory.promoted",
        "tomcat.cache.hit",
        "tomcat.servlet.error",
        "system.load.average.1m",
        "tomcat.cache.access",
        "jvm.memory.used",
        "jvm.gc.max.data.size",
        "jvm.memory.committed",
        "system.cpu.count",
        "logback.events",
        "http.server.requests",
        "tomcat.global.sent",
        "jvm.buffer.memory.used",
        "tomcat.sessions.created",
        "jvm.threads.daemon",
        "system.cpu.usage",
        "jvm.gc.memory.allocated",
        "tomcat.global.request.max",
        "tomcat.global.request",
        "tomcat.sessions.expired",
        "jvm.threads.live",
        "jvm.threads.peak",
        "tomcat.global.received",
        "process.uptime",
        "tomcat.sessions.rejected",
        "process.cpu.usage",
        "tomcat.threads.config.max",
        "jvm.classes.loaded",
        "jvm.gc.pause",
        "jvm.classes.unloaded",
        "tomcat.global.error",
        "tomcat.sessions.active.current",
        "tomcat.sessions.alive.max",
        "jvm.gc.live.data.size",
        "tomcat.servlet.request.max",
        "tomcat.threads.current",
        "tomcat.servlet.request",
        "process.files.open",
        "jvm.buffer.count",
        "jvm.buffer.total.capacity",
        "tomcat.sessions.active.max",
        "tomcat.threads.busy",
        "process.start.time"
    ]
}

To get the details of an individual metric, you need to pass the metric name in the URL like this - http://localhost:8080/actuator/metrics/{MetricName}

http http://localhost:8080/actuator/metrics/system.cpu.usage
HTTP/1.1 200
Content-Disposition: inline;filename=f.txt
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:28:20 GMT
Transfer-Encoding: chunked

{
    "availableTags": [],
    "baseUnit": null,
    "description": "The \"recent cpu usage\" for the whole system",
    "measurements": [
        {
            "statistic": "VALUE",
            "value": 0.00609115522177783
        }
    ],
    "name": "system.cpu.usage"
}

/loggers endpoint

The loggers endpoint displays a list of all the configured loggers in your application with their corresponding log levels.

http http://localhost:8080/actuator/loggers
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:28:45 GMT
Transfer-Encoding: chunked

{
    "levels": [
        "OFF",
        "ERROR",
        "WARN",
        "INFO",
        "DEBUG",
        "TRACE"
    ],
        "loggers": {
        "ROOT": {
            "configuredLevel": "INFO",
            "effectiveLevel": "INFO"
        },
        "com": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
        "com.example": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
        "com.example.actuatordemo": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
        "com.example.actuatordemo.ActuatorDemoApplication": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
        "org": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
        "org.apache": {
            "configuredLevel": null,
            "effectiveLevel": "INFO"
        },
                "...": "..."
            }
}

You can also view the details of an individual logger by passing the logger name in the URL like this - http://localhost:8080/actuator/loggers/{name}.

http http://localhost:8080/actuator/loggers/root
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:34:52 GMT
Transfer-Encoding: chunked

{
    "configuredLevel": "INFO",
    "effectiveLevel": "INFO"
}

/info endpoint

The /info endpoint displays arbitrary information about your application. It obtains build information from META-INF/build-info.properties file, Git information from git.properties file. It also displays any information available in environment properties under the key info.

You can add properties under the key info in application.properties file like so -

cd ~/actuator-demo
echo '
# INFO ENDPOINT CONFIGURATION
info.app.name=@project.name@
info.app.description=@project.description@
info.app.version=@project.version@
info.app.encoding=@project.build.sourceEncoding@
info.app.java.version=@java.version@' | tee -a src/main/resources/application.properties

mvn spring-boot:run

Note that, I’m using Spring Boot’s Automatic property expansion feature to expand properties from the maven project.

Once you add the above properties, the /info endpoint will start displaying the information like so -

http http://localhost:8080/actuator/info
HTTP/1.1 200
Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
Date: Mon, 17 Dec 2018 09:35:50 GMT
Transfer-Encoding: chunked

{
    "app": {
        "description": "Demo project for Spring Boot",
        "encoding": "UTF-8",
        "java": {
            "version": "1.8.0_191"
        },
        "name": "actuator-demo",
        "version": "0.0.1-SNAPSHOT"
    }
}

results matching ""

    No results matching ""