Spring Boot Actuator and Observability
Introduction
Production services need health checks, metrics, and safe operational endpoints—not guesswork from log tailing alone. Spring Boot Actuator exposes /actuator/health, metrics via Micrometer, and optional integration with Prometheus and Grafana. This chapter enables Actuator securely and outlines logs + metrics + tracing as one observability stack.
Prerequisites
Add Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>Expose endpoints:
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: when_authorizedDefault base path: /actuator.
Health Endpoint
curl http://localhost:8080/actuator/healthExample response:
{
"status": "UP"
}With DB on classpath, db indicator appears:
{
"status": "UP",
"components": {
"db": { "status": "UP" },
"diskSpace": { "status": "UP" }
}
}Kubernetes liveness/readiness probes often hit /actuator/health/liveness and /actuator/health/readiness when configured.
Custom health indicator:
Application Info
info:
app:
name: demo-service
version: 1.0.0
management:
info:
env:
enabled: truecurl http://localhost:8080/actuator/infoMetrics With Micrometer
Actuator registers JVM, HTTP, and datasource metrics automatically.
List names:
curl http://localhost:8080/actuator/metricsSingle metric:
curl "http://localhost:8080/actuator/metrics/http.server.requests"Custom counter:
Prometheus Scraping
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>management:
endpoints:
web:
exposure:
include: health,prometheusPrometheus scrapes /actuator/prometheus. Grafana dashboards visualize latency, error rate, and JVM heap.
Secure Actuator in Production
Warning
Do Not Expose All Endpoints Publicly
/actuator/env and /actuator/beans leak internals—restrict by network or Spring Security.
management:
endpoints:
web:
exposure:
include: health,info,prometheus
server:
port: 9091Separate management port on internal network only.
Integrate with Spring Security:
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/actuator/**").hasRole("ADMIN")Logs + Metrics + Tracing
| Pillar | Tooling |
|---|---|
| Logs | Logback JSON, centralized ELK/Loki |
| Metrics | Micrometer → Prometheus → Grafana |
| Tracing | Micrometer Tracing + OpenTelemetry + Zipkin/Jaeger |
Add tracing starter (concept):
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>Trace id in logs correlates slow HTTP span with SQL—debug production latency.
FAQ
Actuator 404?
Missing dependency or endpoints not in exposure.include.
Health DOWN but app runs?
DB/Redis unreachable—fix dependency or disable indicator in dev.
High cardinality metrics?
Avoid unbounded tags (user id on every counter)—explodes Prometheus.
Actuator vs custom /health?
Actuator standardizes probes—prefer over ad-hoc endpoint.
Cloud platform metrics?
AWS CloudWatch, Azure Monitor via Micrometer registries—same MeterRegistry API.
Sensitive env in /actuator/env?
Keep endpoint disabled in prod or sanitize properties.