On this page
Spring Boot Actuator
Spring Boot Actuator exposes production-ready endpoints for monitoring, metrics, health checks, and environment inspection.
Setup
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Expose endpoints:
management:
endpoints:
web:
exposure:
include: health,info,metrics,env,loggers
endpoint:
health:
show-details: when_authorized
Key Endpoints
| Endpoint | Description |
|---|---|
/actuator/health |
Application health status |
/actuator/info |
Custom application info |
/actuator/metrics |
Application metrics |
/actuator/env |
Environment properties |
/actuator/loggers |
View/modify log levels |
/actuator/beans |
All Spring beans |
/actuator/mappings |
Request mappings |
Health Checks
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
private final DataSource dataSource;
@Override
public Health health() {
try (Connection conn = dataSource.getConnection()) {
return Health.up().withDetail("database", "PostgreSQL").build();
} catch (SQLException e) {
return Health.down().withDetail("error", e.getMessage()).build();
}
}
}
Response:
{
"status": "UP",
"components": {
"db": { "status": "UP", "details": { "database": "PostgreSQL" } },
"diskSpace": { "status": "UP" }
}
}
Custom Info
info:
app:
name: My Application
version: 1.0.0
description: Order management system
Metrics with Micrometer
@Service
public class OrderService {
private final Counter orderCounter;
private final Timer orderTimer;
public OrderService(MeterRegistry registry) {
this.orderCounter = registry.counter("orders.created");
this.orderTimer = registry.timer("orders.processing.time");
}
public Order createOrder(OrderRequest request) {
return orderTimer.record(() -> {
Order order = processOrder(request);
orderCounter.increment();
return order;
});
}
}
View at /actuator/metrics/orders.created.
Security
Secure actuator endpoints in production:
@Configuration
public class ActuatorSecurity {
@Bean
public SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
return http
.securityMatcher("/actuator/**")
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.anyRequest().hasRole("ADMIN"))
.httpBasic(Customizer.withDefaults())
.build();
}
}
Best Practices
- Expose only necessary endpoints in production
- Always secure sensitive endpoints (
/env,/beans,/loggers) - Implement custom
HealthIndicatorfor critical dependencies - Use Micrometer metrics for observability integration (Prometheus, Grafana)
- Set
management.server.portto a separate port for isolation