0% found this document useful (0 votes)
108 views

Spring Boot Actuator Spring Boot 2 Recipes A Problem-Solution Approach

Spring Boot Actuator enables monitoring of a Spring Boot application by exposing health and metrics endpoints over JMX, HTTP, or for export to external systems. It provides health indicators that check the status of the application and its dependencies. Metrics endpoints expose usage, performance, and utilization statistics. Individual endpoints and health indicators can be configured through properties. When Spring Security is present, management endpoints are automatically secured with HTTP Basic authentication using a default username and generated password.

Uploaded by

Erick Andrade
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
108 views

Spring Boot Actuator Spring Boot 2 Recipes A Problem-Solution Approach

Spring Boot Actuator enables monitoring of a Spring Boot application by exposing health and metrics endpoints over JMX, HTTP, or for export to external systems. It provides health indicators that check the status of the application and its dependencies. Metrics endpoints expose usage, performance, and utilization statistics. Individual endpoints and health indicators can be configured through properties. When Spring Security is present, management endpoints are automatically secured with HTTP Basic authentication using a default username and generated password.

Uploaded by

Erick Andrade
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

© Marten Deinum 2018

Marten Deinum, Spring Boot 2 Recipes


https://doi.org/10.1007/978-1-4842-3963-6_10

10. Spring Boot Actuator

Marten Deinum1
(1) Meppel, Drenthe, The Netherlands
When developing an application, you also want to be able to monitor the
behavior of the application. Spring Boot makes it very easy to enable that
by introducing Spring Boot Actuator. Spring Boot actuator exposes health
and metrics from the application to interested parties. This can be over
JMX, HTTP, or exported to an external system.

The health endpoints tell something about the health of your application
and/or the system it is running on. It will detect if the database is up, re-
port the diskspace, etc. The metrics endpoints expose usage and perfor-
mance statistics like number of request, the longest request, the fastest,
the utilization of your connection pool, etc.

All these metrics can be viewed either through JMX or HTTP when en-
abled, but can also be automatically exported to an external system like
Graphite, InfluxDB, and many others.

10.1 Enable and Configure Spring Boot Actuator

Problem

You want to enable health and metrics in your application so that you can
monitor the status of the application.

Solution

Add a dependency for the spring-boot-starter-actuator to your


project and the health and metrics will be enabled and exposed for your
application. Additional configuration can be done through properties in
the management namespace.
How It Works

When adding the spring-boot-starter-actuator, Spring Boot will auto-


matically set up the health and metrics based on the beans in the applica-
tion context. Which health and metrics are exposed depends on the beans
and features that are enabled. When a DataSource is detected, metrics
for that will be collected and exposed as well as health. Spring Boot does
this for many components like Hibernate, RabbitMQ, Caches, etc.

To enable the actuator, add the dependency to your application (here we


assume Recipe 3.3 sources as a starting point).

<dependency>

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

</dependency>

Now when starting the application, Spring Boot will have the actuator
con�igured and it is accessible through JMX (Figure 10-1, and see Recipe 8.4 on
how to use JConsole) and through the web (default under the /actuator
path)(see Figure 10-2).
Figure 10-1 JMX exposed metrics

Figure 10-2 HTTP exposed metrics

You will notice that JMX exposes a lot more endpoints then HTTP does. HTTP
only exposes /actuator/health and /actuator/info. JMX exposed a lot
more. This is done with security in mind: the /actuator is exposed publicly and
as such you don’t want everyone to see things. What to expose can be con�igured
through the management.endpoints.web.exposure.include and
management.endpoints.web.exposure.exclude properties. Using a * for
the include will expose all endpoints to the web.

management.endpoints.web.exposure.include=*

With the preceding con�iguration added to the application.properties,


the same features will be exposed to the web as through JMX (Figure 10-3).

Figure 10-3 HTTP exposed metrics (all)

Configure the Management Server

By default, the actuator is available on the same port and address


(http://localhost:8080) as the regular application. It is, however, very easy
(and common) to run the management endpoints on a different port. This can be
con�igured through properties in the management.server namespace; most of
them mimic the ones in the regular server namespace (Table 10-1).
Table 10-1 Management Server Properties
Property Description

Add an X-Application-
management.server.add- Context header to the response
application-context-header containing the application con-
text name

The port to run the manage-


management.server.port ment server on, default same as
server.port

The network address to bind to,


default same as server.ad-
management.server.address
dress (which is 0.0.0.0 all ad-
dresses)

man-
The context path of the manage-
age-
ment server, default none re-
ment.server.servlet.context-
sulting in /
path

SSL properties to configure SSL


for the management server (see
management.server.ssl.*
Recipe 3.8 on how to configure
SSL)

Adding the following to the application.properties will run the


management endpoints on a separate port and add the X-Application-
Context header .

management.server.add-application-context-header=true
management.server.port=8090

When restarting the application, the management endpoints are now


available on http://localhost:8090/actuator. Running the actuator
on a different port has the benefit of hiding it from the public internet by
blocking the port on the firewall and only allowing local access.

NoteThe management.server properties are only effective when using


an embedded server; when deploying to an external server these proper-
ties don’t apply anymore!

Configure Individual Management Endpoints

Individual endpoints can be con�igured through properties in the


management.endpoint.<endpoint-name> namespace. Most of them have at
least an enabled property and a cache.time-to-live property. The �irst will
enable or disable the endpoint, the other one speci�ies how long to cache a result
of the endpoint (Table 10-2).
Table 10-2 Endpoint Configuration Properties

Property Description

Whether the specific endpoint is en-


abled, generally defaults to true and
management.endpoint. sometimes depends on availability of a
<endpoint-name>.enabled feature (i.e., if Flyway isn’t present,
then enabling the flyway endpoint
wouldn’t have any effect)

management.endpoint.
<endpoint- Time to cache a response, default is
name>.cache.time-to- 0ms meaning no caching
live

man-
Whether to show details for the health
age-
endpoint, default is never, can be
ment.end-
changed to always or when-
point.health.show-
authorized
details

management.end- Roles that are allowed to see the de-


Property Description

tails (use together with when-


point.health.roles
authorized for show-details)

Adding management.endpoint.health.show-details=always to the


application.properties will show more information about the health of the
application. By default it will only show UP, but now you can see the different parts
of the health information for your application (Figure 10-4).

Figure 10-4 Extended health endpoint output

Securing Management Endpoints

When Spring Boot detects both Spring Boot Actuator and Spring Security,
it will enable secure access to management endpoints automatically.
When accessing the endpoint, a Basic Login prompt will be shown and
asks for a username and password. Spring Boot will generate a default
user, with the username user and a generated password (see Recipe 6.1)
to use for login.

Adding the spring-boot-starter-security in addition to the spring-


boot-starter-actuator is enough to have secured management endpoints.

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

</dependency>

This will enable security in your application and for the management
endpoints. Now when accessing the endpoint http://localhost:8090
/actuator a Basic login prompt will be shown. After entering the correct
credentials you should still be able to see the results.

Configure Healthchecks

One of the features of Spring Boot Actuator is to do healthchecks. Those are


exposed under http://localhost:8090/actuator/health; this produces a
result if the application is UP or DOWN. The health endpoint calls all the available
HealthIndicators in the system and reports those in the endpoint. Which
HealthIndicators are present can be controlled by setting the
management.health.<health-indicator>.enabled property. Setting a
property to true for a not available feature (like trying to get information on the
DataSource while one isn’t available) won’t work.

management.health.diskspace.enabled=false

This will disable the healthcheck for the diskspace, and it won’t be part of
the health checks anymore.

Configure Metrics

One of the features of Spring Boot Actuator is to expose metrics. Those are
exposed under http://localhost:8090/actuator/metrics; this will
produce a list of available metrics for your application (Figure 10-5).
Figure 10-5 List of currently available metrics

More information about a metric can be obtained by accessing


http://localhost:8090/actuator/metrics/{name-of-metric}, for
example, http://localhost:8090/actuator/metrics
/system.cpu.usage will show the current CPU usage (Figure 10-6).

Figure 10-6 Detailed CPU metrics

Spring Boot uses micrometer.io1 to record metrics. Metrics are enabled by


default for the features detected by Spring Boot. So if a DataSource is detected,
metrics will be enabled. To disable metrics, add them to the
management.metrics.enable property. This is a map containing keys and
values on which metrics to enable.

management.metrics.enable.system=false
management.metrics.enable.tomcat=false

The preceding configuration will disable system and tomcat metrics .


When viewing the metrics at http://localhost:8090/actuator/met-
rics, they aren’t part of the list anymore.

10.2 Create Custom Health Checks and Metrics

Problem

Your application needs to expose certain metrics and have a health check
that aren’t available by default.

Solution

The health checks and metrics are pluggable, and beans of type
HealthIndicator and MetricBinder are automatically registered to pro-
vide additional health checks and/or metrics. The task is to create a class
implementing the desired interface and register an instance of that class
as a bean in the context of having it contribute to the health and metrics.

How It Works

Assuming that a dependency on Spring Boot Actuator is already present,


you can start writing an implementation right away. Assume you have an
application using a TaskScheduler and you want to have some metrics
and health on it. (Adding @EnableScheduling is enough to have Spring
Boot create a default TaskScheduler.)

First, let’s write the HealthIndicator . You can either directly implement the
HealthIndicator interface or use the convenience
AbstractHealthIndicator as a base class.
package com.apress.springbootrecipes.library.actuator;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
@Component
class TaskSchedulerHealthIndicator extends AbstractHealthIndicator {
private final ThreadPoolTaskScheduler taskScheduler;
TaskSchedulerHealthIndicator(ThreadPoolTaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
int poolSize = taskScheduler.getPoolSize();
int active = taskScheduler.getActiveCount();
int free = poolSize - active;
builder
.withDetail("active", taskScheduler.getActiveCount())
.withDetail("poolsize", taskScheduler.getPoolSize());
if (poolSize > 0 && free <= 1) {
builder.down();
} else {
builder.up();
}
}
}

The TaskSchedulerHealthIndicator operates on the given


ThreadPoolTaskExecutor . It reports the status as down if there is one or
fewer threads available to schedule tasks. The condition on poolSize >
0 is there because the creation of the underlying Executor is delayed un-
til needed; until then the poolSize will report 0. The returned value in-
cludes the poolsize and active thread count just for information.

The TaskSchedulerMetrics implements the MeterBinder interface from


micrometer.io. It exposes the active and pool-size to the metrics registry.
package com.apress.springbootrecipes.library.actuator;
import io.micrometer.core.instrument.FunctionCounter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
@Component
class TaskSchedulerMetrics implements MeterBinder {
private final ThreadPoolTaskScheduler taskScheduler;
TaskSchedulerMetrics(ThreadPoolTaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
@Override
public void bindTo(MeterRegistry registry) {
FunctionCounter
.builder("task.scheduler.active", taskScheduler,
ThreadPoolTaskScheduler::getActiveCount)
.register(registry);
FunctionCounter
.builder("task.scheduler.pool-size", taskScheduler,
ThreadPoolTaskScheduler::getPoolSize)
.register(registry);
}
}

Now when placing an @EnableScheduling on the LibraryApplication


and restarting the application, metrics and health will be reported for the
TaskScheduler (Figure 10-7).
Figure 10-7 TaskScheduler health check

10.3 Export Metrics

Problem

You want to export the metrics to an external system, to create a dash-


board to monitor the application.

Solution

Use one of the supported systems like Graphite and periodically push the
metrics to that system. Include a micrometer.io registry dependency in
your application (next to the spring-boot-starter-actuator depen-
dency) and metrics will automatically be exported. By default, every
minute the data will be pushed to the server.

How It Works

Exporting metrics is part of the Micrometer.io library and it supports a wide


variety of services like Graphite, DataDog, Ganglia, or regular StatsD. This recipe
uses Graphite, so a dependency to micrometer-registry-graphite needs to
be added.

<dependency>

<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-graphite</artifactId>
</dependency>

In theory this could be enough to have metrics published to Graphite if


Graphite ( https://graphiteapp.org ) is running on localhost and with the
default ports. However, Spring Boot makes it easy to con�igure this by exposing
some properties, generally in the management.metrics.export.<registry-
name> namespace (Table 10-3).
Table 10-3 Common Metrics Export Properties

Property Description

man- Whether or not to enable metrics ex-


agement.metrics.export. porting. Default true when the li-
<registry-name>.enabled brary is detected on the classpath

man- Host to send metrics to, mostly lo-


agement.metrics.export. calhost or well-known url of service
<registry-name>.host (like SignalFX, DataDog, etc.)

man- Port to send metrics to, defaults to the


agement.metrics.export. well-known port of the desired ser-
<registry-name>.port vice

man-
How often to send metrics, default 1
agement.metrics.export.
minute
<registry-name>.step

man-
agement.metrics.export. Base time unit used to report rates,
<registry-name>.rate- default seconds
units

man-
Base time unit used to report dura-
agement.metrics.export.
tions, default milliseconds
<registry-
Property Description

name>.duration-units

To report the metrics every ten seconds instead of each minute, add the
following to the application.properties:

management.metrics.export.graphite.step=10s

NoteThe bin directory contains a graphite.sh, which uses docker to


start a Graphite instance.
Now the metrics will be published to Graphite every ten seconds. If you start the
application and open Graphite on http://localhost (assuming you are running
the aforementioned Docker container) you could, for example, create a graph of
the CPU usage (Figure 10-8).

Figure 10-8 Graphite CPU graph

Footnotes
1 https://micrometer.io

You might also like