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"
}
}