Spring Boot Actuator adds production-oriented monitoring and management features to a Spring Boot application. It exposes information such as health, metrics, configuration, log levels, and thread state through HTTP endpoints or JMX.
Actuator is part of the application itself. It is not a separate monitoring server and does not retain historical data. An endpoint reports the application’s current state; an external system such as Prometheus periodically collects that state and stores it over time.
Adding Actuator #
For Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>For Gradle:
implementation("org.springframework.boot:spring-boot-starter-actuator")After the application starts, the root discovery endpoint is normally:
GET /actuatorThe health endpoint is:
GET /actuator/healthThe exact endpoints that exist depend on the application’s dependencies and configuration. For example, a database health contributor is useful only when the application has a configured data source.
What Actuator Provides #
Common Actuator endpoints include:
| Endpoint | Purpose |
|---|---|
health | Reports overall and component health |
info | Reports application information |
metrics | Lists and inspects Micrometer meters |
prometheus | Exposes metrics in Prometheus scrape format |
loggers | Inspects and changes logging levels |
env | Inspects properties from the Spring environment |
configprops | Shows properties bound to configuration classes |
beans | Lists beans in the application context |
conditions | Explains positive and negative auto-configuration matches |
mappings | Lists web request mappings |
caches | Inspects and evicts application caches |
scheduledtasks | Lists scheduled tasks |
quartz | Inspects Quartz jobs and triggers |
startup | Reports application startup steps when startup recording is enabled |
threaddump | Produces a JVM thread dump |
heapdump | Downloads a JVM heap dump |
httpexchanges | Shows recent HTTP request-response exchanges when a repository is configured |
auditevents | Shows security audit events when an audit repository is configured |
shutdown | Gracefully shuts down the application when explicitly enabled |
Not every endpoint should be exposed in production. Several reveal configuration, application structure, runtime behavior, or large diagnostic artifacts.
Enabled Is Different from Exposed #
Actuator treats two decisions separately:
- Enabled: Whether an endpoint is created in the application context.
- Exposed: Whether that endpoint is available through HTTP or JMX.
An endpoint must be both enabled and exposed before a remote client can use it.
Enable or disable one endpoint:
management:
endpoint:
shutdown:
enabled: trueControl HTTP exposure:
management:
endpoints:
web:
exposure:
include: health,info,prometheusControl JMX exposure independently:
management:
endpoints:
jmx:
exposure:
include: health,infoAn exclusion takes precedence over an inclusion:
management:
endpoints:
web:
exposure:
include: "*"
exclude: env,beans,heapdump,shutdownExposing everything and maintaining a denylist is risky because a framework upgrade can add a new endpoint. A small explicit allowlist is safer.
Health Information #
/actuator/health combines results from registered health contributors. Spring
Boot can auto-configure contributors for facilities such as:
- Databases and connection pools
- Disk space
- Redis
- Message brokers
- Search services
- Mail servers
- Custom application dependencies
A healthy response may be as small as:
{"status":"UP"}By default, component details are not shown. Their visibility is controlled by:
management:
endpoint:
health:
show-details: when-authorized
show-components: when-authorizedThe supported policies are never, when-authorized, and always. Avoid
publishing component details anonymously because names, addresses, database
state, and exception information can disclose useful operational details.
Custom Health Indicators #
A custom health indicator expresses whether an application-specific dependency can perform the operation the service requires:
import org.springframework.boot.health.contributor.Health;
import org.springframework.boot.health.contributor.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class PaymentProviderHealthIndicator implements HealthIndicator {
private final PaymentClient paymentClient;
public PaymentProviderHealthIndicator(PaymentClient paymentClient) {
this.paymentClient = paymentClient;
}
@Override
public Health health() {
if (paymentClient.isAvailable()) {
return Health.up().build();
}
return Health.down()
.withDetail("provider", "primary")
.build();
}
}The bean name, without the HealthIndicator suffix, becomes the component ID.
The preceding contributor appears as paymentProvider.
Health checks run in response to endpoint requests, so they must be bounded and fast. A check should use a short timeout and avoid expensive scans, large allocations, or modifying remote state.
Health Status and HTTP Responses #
The built-in status values include:
UP
DOWN
OUT_OF_SERVICE
UNKNOWNDOWN and OUT_OF_SERVICE normally produce HTTP 503; healthy and unmapped
statuses produce 200. A StatusAggregator combines component statuses into
the overall result.
Custom status ordering and HTTP mappings can be configured, but custom mappings replace the defaults. Preserve the standard mappings explicitly when adding a new status.
Liveness and Readiness #
Actuator provides health groups for container orchestrators:
/actuator/health/liveness
/actuator/health/readinessThe distinction matters:
- Liveness asks whether the process is irrecoverably broken and should be restarted.
- Readiness asks whether the process should currently receive traffic.
Do not add every external dependency to liveness. If a shared database fails, restarting every application instance will not repair the database and may make the incident worse.
Readiness may include dependencies required to serve requests, but the choice depends on system behavior. A service that can provide degraded responses without a dependency may remain ready.
Health groups can also be published on the main application port:
management:
endpoint:
health:
group:
live:
additional-path: server:/healthz
ready:
additional-path: server:/readyzThis avoids a misleading result where a separate management port responds even though the main server can no longer accept requests.
How Actuator Interfaces with Micrometer #
Actuator uses Micrometer as its metrics and observation foundation. Spring Boot
auto-configures a Micrometer MeterRegistry, binds JVM, process, system, HTTP,
database-pool, and framework instrumentation to it, and adds each supported
registry implementation found on the runtime classpath. The Actuator metrics
endpoint lets an operator inspect those meters, while a registry-specific
endpoint exports them to a backend. For example,
micrometer-registry-prometheus adds a Prometheus registry and enables the
prometheus Actuator endpoint. Actuator therefore supplies auto-configuration
and transport, Micrometer supplies the instrumentation model, and Prometheus
supplies time-series storage and PromQL.
Add the Prometheus registry:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>Expose its endpoint:
management:
endpoints:
web:
exposure:
include: health,prometheusPrometheus can then scrape:
GET /actuator/prometheusThe metrics and prometheus endpoints serve different audiences:
/actuator/metricsis a diagnostic API for exploring meter names, measurements, and available tags./actuator/prometheusreturns all publishable measurements in the text format expected by Prometheus.
The metrics endpoint does not provide historical graphs. It reads the current state of the in-process Micrometer registry.
Built-in Metrics #
Depending on the application and its dependencies, Spring Boot can publish metrics for:
- JVM memory, garbage collection, threads, and loaded classes
- Process CPU use, uptime, and file descriptors
- Host CPU and disk space
- HTTP server requests
- HTTP client requests
- Data source connection pools
- Caches
- Spring Data repositories
- Messaging systems
- Task executors and schedulers
- Application startup
- Log events
For example, HTTP server instrumentation records a timer with dimensions such as method, normalized route, response status, outcome, and exception. Prometheus may expose it as a family based on:
http_server_requests_secondsUse normalized routes such as /orders/{id} rather than raw paths such as
/orders/4815162342. Raw paths create unbounded metric cardinality.
Common Tags #
Apply stable tags before meters are registered:
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.micrometer.metrics.autoconfigure.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MetricsConfiguration {
@Bean
MeterRegistryCustomizer<MeterRegistry> commonTags() {
return registry -> registry.config().commonTags(
"service", "checkout",
"region", "eu-west-1"
);
}
}Do not use request IDs, user IDs, email addresses, timestamps, or other unbounded values as metric tags.
Info Contributors #
The info endpoint can publish selected application information. Useful values
include the application name, build version, and source revision:
info:
app:
name: checkout
description: Checkout APIBuild plugins can generate build metadata, and source-control plugins can generate Git metadata. Publish only what operators need; branch names, complete property sets, and environment details may reveal more than intended.
Changing Log Levels at Runtime #
The loggers endpoint can inspect effective logging levels:
GET /actuator/loggers/com.example.checkoutIt can also change a configured level while the process is running:
POST /actuator/loggers/com.example.checkout
Content-Type: application/json
{"configuredLevel":"DEBUG"}To clear the explicit level and return to inherited configuration:
POST /actuator/loggers/com.example.checkout
Content-Type: application/json
{"configuredLevel":null}Runtime changes are operational state, not persistent configuration. They are lost when the application restarts. This endpoint is powerful and should be restricted to trusted operators.
HTTP Exchange Recording #
The httpexchanges endpoint is available when the application provides an
HttpExchangeRepository. An in-memory implementation is suitable only for
development because it retains a limited number of exchanges in application
memory.
HTTP exchange data may contain paths, headers, principal names, timing, and status information. Configure recording conservatively and never treat it as a replacement for a production log or tracing backend.
Auditing #
Actuator’s auditing support can publish security events such as authentication
success, authentication failure, and access denial. An AuditEventRepository
stores and retrieves the events exposed by auditevents.
An in-memory repository is useful for development but is not durable. Production audit requirements normally call for a purpose-built persistent and access-controlled destination.
Audit records can contain sensitive security information. Protect them independently from ordinary application metrics.
Management Server Configuration #
The Actuator HTTP endpoints use the application server by default. Their base path can be changed:
management:
endpoints:
web:
base-path: /manageThey can also run on a separate port:
management:
server:
port: 9091A separate management address can limit which network interfaces accept management traffic:
management:
server:
port: 9091
address: 127.0.0.1A separate port provides network isolation but creates another server to operate. It can also report healthy while the main application connector is broken. Use main-port health paths when the orchestrator must verify the actual traffic-serving interface.
Securing Actuator #
Actuator endpoints are administrative APIs. Network placement is not a substitute for authentication and authorization.
When Spring Security is present and the application has not supplied its own
security filter chain, Spring Boot secures Actuator endpoints other than health.
Once the application defines a SecurityFilterChain, Spring Boot backs off and
the application owns the complete access policy.
A typical policy permits probes, restricts Prometheus to the monitoring network or role, and reserves other endpoints for administrators:
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurityConfiguration {
@Bean
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint())
.authorizeHttpRequests(requests -> requests
.requestMatchers(EndpointRequest.to(HealthEndpoint.class))
.permitAll()
.anyRequest()
.hasRole("OPS"))
.httpBasic(Customizer.withDefaults());
return http.build();
}
}The application’s normal routes need their own filter chain when a dedicated
Actuator chain uses securityMatcher.
Additional safeguards include:
- Expose only required endpoints.
- Restrict management traffic with firewalls, security groups, or Kubernetes network policies.
- Require TLS and authentication across untrusted networks.
- Avoid exposing environment, configuration, heap dump, and shutdown endpoints publicly.
- Keep sensitive-value sanitization enabled.
- Audit write operations such as log-level changes and shutdown.
Creating Custom Endpoints #
Actuator can expose custom management operations through technology-neutral endpoint annotations:
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;
@Component
@Endpoint(id = "featureflags")
public class FeatureFlagsEndpoint {
private final FeatureFlags featureFlags;
public FeatureFlagsEndpoint(FeatureFlags featureFlags) {
this.featureFlags = featureFlags;
}
@ReadOperation
public Map<String, Boolean> flags() {
return featureFlags.snapshot();
}
}Actuator maps endpoint operations to HTTP and JMX:
@ReadOperationreads state.@WriteOperationchanges state.@DeleteOperationdeletes state.
Custom endpoints should expose management state, not become an alternative business API. Keep responses bounded, stable, and free of secrets. Write and delete operations need stricter authorization than read-only diagnostics.
Actuator Compared with a Monitoring Stack #
| Component | Responsibility |
|---|---|
| Spring Boot Actuator | Exposes application management endpoints |
| Micrometer | Instruments metrics and observations |
| Prometheus | Scrapes, stores, queries, and evaluates metric rules |
| Grafana | Visualizes metrics, logs, and traces |
| Alertmanager | Groups and routes Prometheus alerts |
| Loki or Elasticsearch | Stores and queries logs |
| Tempo, Jaeger, or another tracing backend | Stores and queries traces |
Actuator is the application’s observability surface, not the entire observability platform. Its health endpoint serves current status, while Micrometer and external backends provide measurements that remain useful after the application restarts.
Production Guidelines #
- Begin with only
healthand the required metrics-export endpoint exposed. - Keep health checks fast, bounded, and side-effect free.
- Separate liveness from readiness.
- Do not make liveness depend on shared external infrastructure.
- Protect diagnostic and write-capable endpoints with strong authorization.
- Keep endpoint details and sensitive values hidden from anonymous clients.
- Use Micrometer tags with bounded cardinality.
- Export metrics to a durable backend rather than polling
metricsmanually. - Treat heap dumps, environment data, and configuration reports as sensitive.
- Test management access rules separately from the application’s user-facing security rules.
Actuator makes a Spring Boot process manageable by exposing carefully designed views of its current state. Its value comes from combining those endpoints with Micrometer instrumentation and external systems that retain, query, visualize, and alert on telemetry over time.
Comments
Read or comment on GitHub (sign-in required to comment)