Spring Boot Actuator
IntermediateActuator exposes operational endpoints (/health, /info, /metrics, /env) over HTTP or JMX, enabling real-time insight into a running application.
Overview
Spring Boot Actuator is the production-readiness module of Spring Boot. Adding spring-boot-starter-actuator gives your application a set of HTTP (or JMX) endpoints that expose operational information: health status, application info, environment properties, live metrics, thread dumps, heap dumps, HTTP request traces, and more. These endpoints are the foundation for Kubernetes liveness/readiness probes, Prometheus scraping, and operational dashboards. By default, only /health and /info are exposed over HTTP for security reasons — you explicitly enable the others. Actuator integrates directly with Micrometer to expose JVM, Tomcat, HikariCP, and custom application metrics.
Key Endpoints and Configuration
Important endpoints: - `/health` — UP/DOWN with detail on DB, Kafka, disk, custom indicators. Required for K8s probes. - `/info` — static metadata (build version, git commit, description) from application.properties. - `/metrics` — lists all Micrometer metric names; drill into specific ones with `/metrics/{name}`. - `/env` — all resolved environment properties (redacts passwords). - `/loggers` — view and change log levels at runtime without restart. - `/threaddump` — full JVM thread dump for deadlock analysis. - `/httptrace` (Boot 2) / `/httpexchanges` (Boot 3) — recent HTTP request/response trace. - `/actuator/prometheus` — Prometheus scrape endpoint (requires micrometer-registry-prometheus).
# application.yml — Actuator configuration
management:
endpoints:
web:
exposure:
include: "health,info,metrics,loggers,env,prometheus"
# use "*" to expose everything (not recommended in production)
base-path: /actuator # default; change to obscure from public
endpoint:
health:
show-details: when-authorized # show component details only to authenticated users
show-components: always
# Bind management endpoints to a separate internal port
server:
port: 8081 # expose actuator on internal port, block 8081 from public LB
# Kubernetes health probes — point to actuator
# spec.containers[].livenessProbe:
# httpGet:
# path: /actuator/health/liveness
# port: 8081
# spec.containers[].readinessProbe:
# httpGet:
# path: /actuator/health/readiness
# port: 8081/health — Liveness, Readiness, and Custom Indicators
Spring Boot 2.3+ exposes two health groups that map directly to Kubernetes probes: - `/health/liveness` — is the application alive? If DOWN, K8s restarts the pod. Only flag liveness down for unrecoverable states (deadlock, corrupted in-memory state). A slow DB does NOT make the app dead. - `/health/readiness` — is the application ready to receive traffic? If DOWN, K8s stops sending requests to this pod. A degraded DB connection IS a reason to report not-ready.
# application.yml — map built-in indicators to liveness/readiness groups
management:
health:
livenessState:
enabled: true
readinessState:
enabled: true
endpoint:
health:
group:
liveness:
include: "livenessState"
readiness:
include: "readinessState,db,redis" # readiness includes DB + cache
// Custom HealthIndicator — reports health of a critical external dependency
@Component
public class ExternalApiHealthIndicator implements HealthIndicator {
private final ExternalApiClient client;
@Override
public Health health() {
try {
client.ping(); // fast health-check call
return Health.up()
.withDetail("url", client.getBaseUrl())
.build();
} catch (Exception e) {
return Health.down()
.withDetail("error", e.getMessage())
.build();
}
}
}/loggers — Change Log Levels at Runtime
The /loggers endpoint is one of the most operationally useful Actuator features. Without restarting the JVM, you can temporarily raise or lower a logger's level — for example, enable DEBUG for a specific package while investigating a production issue, then reset to INFO.
# See all loggers and their current levels
GET /actuator/loggers
# See a specific logger
GET /actuator/loggers/com.example.service
# Response:
# {"configuredLevel": "INFO", "effectiveLevel": "INFO"}
# Change level — POST with JSON body
curl -X POST http://localhost:8081/actuator/loggers/com.example.service \
-H 'Content-Type: application/json' \
-d '{"configuredLevel": "DEBUG"}'
# Reset to use parent level (inherits from root)
curl -X POST http://localhost:8081/actuator/loggers/com.example.service \
-H 'Content-Type: application/json' \
-d '{"configuredLevel": null}'
# Programmatic: change log level from application code (e.g., after a circuit breaker opens)
LoggingSystem loggingSystem = context.getBean(LoggingSystem.class);
loggingSystem.setLogLevel("com.example", LogLevel.DEBUG);Key Points to Remember
- 1Add spring-boot-starter-actuator; by default only /health and /info are exposed — explicitly include others in management.endpoints.web.exposure.include.
- 2Bind actuator to a separate management port (management.server.port) so it is not reachable via the public load balancer.
- 3/health/liveness and /health/readiness map to K8s probes — liveness for dead-pod restart, readiness for traffic routing.
- 4Never mark liveness DOWN for a slow DB; only mark it DOWN for truly unrecoverable application state (deadlock, corruption).
- 5/loggers lets you change log levels at runtime without restart — indispensable during production incident investigation.
- 6Pair Actuator with Micrometer (micrometer-registry-prometheus) to expose /actuator/prometheus for Prometheus scraping.
Interview Questions
Sign in to ask AriaWhat is Spring Boot Actuator and what are its key endpoints?
What is the difference between the liveness and readiness health probes?
Why should you expose Actuator endpoints on a separate management port in production?
How would you add a custom health indicator for an external dependency?
How do you temporarily enable DEBUG logging for one package on a live production server without restarting?
Ask Aria about Spring Boot Actuator
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.