Spring Boot Actuator & Observability

Spring Boot Actuator adds production-ready features to an application: health checks, metrics, info about the build, environment and configuration inspection, log level management, and more, exposed as HTTP endpoints (or JMX) under /actuator. Combined with Micrometer, Spring's vendor-neutral metrics and observation facade, it makes a Spring Boot service observable with a few dependencies and properties.

In practice, Actuator is how Kubernetes knows whether your app is alive and ready, how Prometheus scrapes JVM and HTTP metrics, and how traces flow to OpenTelemetry-compatible backends. It also exposes sensitive internals, so deciding what to expose and how to protect it matters as much as enabling it.

TL;DR

Quick Example

Core Concepts

Endpoints

Enable exposure explicitly with management.endpoints.web.exposure.include. Never expose everything (*) on a public interface.

Health Indicators and Groups

Actuator auto-configures health indicators for detected infrastructure: DataSource, Redis, MongoDB, Kafka, Elasticsearch, disk space, and more. The overall status aggregates them. Health groups let you define separate checks:

Spring Boot also tracks AvailabilityState, so apps can mark themselves not ready during startup, warm-up, or graceful shutdown. See Kubernetes workloads.

Metrics With Micrometer

Micrometer is to metrics what SLF4J is to logging: one API with pluggable backends. Out of the box you get:

Custom metrics:

Keep tag values bounded (no user IDs). The same cardinality rules apply as in Prometheus.

The Observation API and Tracing

Micrometer's Observation API instruments an operation once and produces both metrics and trace spans. Micrometer Tracing bridges to OpenTelemetry or Brave, auto-instruments Spring MVC, WebFlux, RestClient/WebClient, JDBC (via datasource-micrometer), and Kafka, propagates W3C trace context, and adds trace IDs to logs (MDC). Export traces via OTLP to an OpenTelemetry Collector. Alternatively, the OpenTelemetry Java agent provides zero-code instrumentation, so choose one approach per app to avoid double instrumentation.

Info and Build Metadata

Populate /actuator/info with build info (the spring-boot-maven-plugin build-info goal), git commit (git-commit-id plugin), Java version, and custom info.* properties, so you can see which version is running, which is invaluable during incidents.

Best Practices

Separate Liveness From Readiness

Liveness should fail only when restarting would help (deadlock, corrupted state). Put dependency checks in readiness, so an outage removes pods from load balancing without restart storms.

Use a Management Port and Restrict Access

Serve actuator on a separate port that isn't exposed via the public ingress, and protect sensitive endpoints with Spring Security (an operator role, or network policies). Don't expose heapdump, env, or loggers publicly.

Enable Histograms for Latency SLOs

Percentile histograms on http.server.requests let Prometheus compute accurate p95 and p99 latency across instances, which is essential for SLOs. Configure SLO buckets that match your objectives.

Add Business Metrics

Technical metrics tell you the service is up; business metrics (orders placed, payments failed, signups) tell you it's working. They're often the fastest signal of real user impact.

Common Mistakes

Database Checks in Liveness Probes

Keep external dependencies in readiness.

Exposing All Endpoints Publicly

management.endpoints.web.exposure.include=* on the main port exposes environment details, thread dumps, heap dumps, and runtime log-level control to anyone who can reach the app.

High-Cardinality Tags

Tagging metrics with raw paths, user IDs, or order IDs explodes the number of time series and can overwhelm Prometheus. Spring's http.server.requests uses URI templates for this reason, so keep custom tags similarly bounded.

FAQ

Which actuator endpoints are enabled by default?

Most endpoints are available, but only health is exposed over HTTP by default (JMX exposes more). You choose HTTP exposure with management.endpoints.web.exposure.include. shutdown is disabled by default.

How do I integrate Spring Boot with Prometheus?

Add micrometer-registry-prometheus, expose the prometheus endpoint, and configure Prometheus (or a ServiceMonitor with the Prometheus Operator) to scrape /actuator/prometheus on the management port.

Should I use Micrometer Tracing or the OpenTelemetry Java agent?

Both work. Micrometer Tracing integrates tightly with Spring (the Observation API, configuration via properties, and log correlation) and suits Spring-centric teams. The OpenTelemetry agent offers zero-code, broad library coverage and consistent behavior across non-Spring services. Pick one per application to avoid duplicate spans.

How do I write a custom health indicator?

Implement HealthIndicator (or ReactiveHealthIndicator) as a bean, returning Health.up() or Health.down() with details. Its name derives from the bean name, and you can include it in health groups such as readiness.

Related Topics

References