Spring Boot Actuator: Monitoring and Management Made Easy
Introduction
Ever deployed a Spring Boot application and wondered how it's performing in production? Or needed to check the health status of your microservices without digging through logs? That's where Spring Boot Actuator comes in — one of those features that once you start using, you'll wonder how you ever managed without it.
When I first discovered Actuator several years ago, it completely changed how I approach application monitoring and management. Instead of building custom endpoints or relying on complex external tools, Spring Boot Actuator provided out-of-the-box solutions for the most common operational needs.
In this post, I'll walk you through Spring Boot Actuator from the ground up. We'll explore what it is, why you should care, and how to implement it in your applications with practical examples. By the end, you'll have all the knowledge you need to start monitoring your Spring Boot applications like a pro!
Usages
Spring Boot Actuator adds several production-ready features to your application with minimal setup. Here are some of the key use cases that make it invaluable in real-world environments:
Health Monitoring
With Actuator's health endpoint, you can check if your application and its dependencies (databases, message queues, etc.) are operating correctly. This is crucial for:
- Load balancers deciding whether to route traffic to your instance
- Kubernetes readiness/liveness probes
- DevOps teams monitoring application status
Metrics Collection
Actuator provides detailed metrics about your application's performance:
- JVM memory usage and garbage collection statistics
- HTTP request timing and response codes
- Database connection pool usage
- Custom business metrics you define
Environment Inspection
Need to verify what configuration properties your application is actually using in production? Actuator exposes:
- Active profiles
- Property sources and values
- Environment variables
Logging Control
Actuator allows you to dynamically change log levels at runtime — incredibly useful when troubleshooting production issues without restarting your application.
Thread Dump & Heap Dump
When performance issues strike, you can capture thread dumps and heap dumps for detailed analysis.
Real-world Use Case: Microservice Monitoring
Imagine you're running a microservice architecture with dozens of services. With Actuator:
- Your ops team can build a dashboard showing health status across all services
- Alert systems can notify you when a service dependency fails
- You can identify which microservices are experiencing high latency
- During an incident, you can increase log verbosity without service disruption
Code Example
Let's implement Spring Boot Actuator in a sample microservice application to see it in action!
1. Add Actuator to Your Project
First, add the Actuator dependency to your pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Or with Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
2. Basic Configuration
Add these properties to your application.properties (or application.yml):
# Enable all actuator endpoints management.endpoints.web.exposure.include=* # Base path for actuator endpoints management.endpoints.web.base-path=/actuator # Show details in health endpoint management.endpoint.health.show-details=always # Enable shutdown endpoint (disabled by default) management.endpoint.shutdown.enabled=true
Note: In production, you might want to be more selective about which endpoints you expose.
3. Create a Custom Health Indicator
Let's create a custom health indicator that checks connectivity to an external API our application depends on:
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @Component public class ExternalApiHealthIndicator implements HealthIndicator { private final RestTemplate restTemplate; private final String apiUrl = "https://api.example.com/health"; public ExternalApiHealthIndicator(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Override public Health health() { try { // Attempt to call the external API restTemplate.getForObject(apiUrl, String.class); return Health.up() .withDetail("message", "External API is responding") .build(); } catch (Exception e) { return Health.down() .withDetail("message", "External API is not available") .withDetail("error", e.getMessage()) .build(); } } }
4. Add Custom Metrics
Let's add custom metrics to track business-specific operations:
import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import org.springframework.stereotype.Service; @Service public class OrderService { private final Counter orderCounter; private final Counter failedOrderCounter; private final Timer orderProcessingTimer; public OrderService(MeterRegistry registry) { this.orderCounter = Counter.builder("app.orders.created") .description("Total number of orders created") .register(registry); this.failedOrderCounter = Counter.builder("app.orders.failed") .description("Number of failed order creations") .register(registry); this.orderProcessingTimer = Timer.builder("app.orders.processing.time") .description("Time taken to process orders") .register(registry); } public void createOrder(Order order) { Timer.Sample sample = Timer.start(); try { // Business logic to process the order processOrder(order); // Increment the order counter orderCounter.increment(); } catch (Exception e) { // Increment the failed order counter failedOrderCounter.increment(); throw e; } finally { // Record the time taken sample.stop(orderProcessingTimer); } } private void processOrder(Order order) { // Order processing logic } }
5. Create Info Contributor
Let's add custom information to the /info endpoint:
import org.springframework.boot.actuate.info.Info; import org.springframework.boot.actuate.info.InfoContributor; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @Component public class ApplicationInfoContributor implements InfoContributor { @Override public void contribute(Info.Builder builder) { Map<String, Object> details = new HashMap<>(); details.put("version", "1.2.3"); details.put("releaseDate", "2025-04-20"); details.put("environment", getEnvironmentName()); builder.withDetail("application", details); } private String getEnvironmentName() { // Logic to determine environment return "production"; } }
6. Configure Logging Endpoint
Enable runtime log level changes:
# in application.properties management.endpoint.loggers.enabled=true
7. Secure Actuator Endpoints
Add Spring Security to protect sensitive endpoints:
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class ActuatorSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeHttpRequests(requests -> requests .requestMatchers(EndpointRequest.to("health", "info")).permitAll() .anyRequest().hasRole("ACTUATOR_ADMIN")) .httpBasic(); return http.build(); } }
Explanation
Let's break down what we've implemented and how it works:
Basic Setup
By adding the spring-boot-starter-actuator
dependency, Spring Boot automatically registers various endpoints under the /actuator
base path. Our configuration exposes all endpoints for demonstration purposes, but in production, you'd typically limit this to only what you need.
Custom Health Indicator
The ExternalApiHealthIndicator
class implements Spring's HealthIndicator
interface. When someone accesses the /actuator/health
endpoint, Spring aggregates results from all health indicators, including ours. If our external API check fails, the overall health status will show as DOWN.
This gives you an instant view of whether all your application dependencies are functioning correctly.
Custom Metrics
Micrometer (included with Actuator) provides a vendor-neutral metrics facade. In our example:
- We created counters for successful and failed orders
- We added a timer to measure order processing latency
These metrics are exposed via the /actuator/metrics
endpoint. More importantly, they can be scraped by monitoring systems like Prometheus and visualized in dashboards like Grafana.
Info Contributor
The ApplicationInfoContributor
adds custom details to the /actuator/info
endpoint. This information is useful for identifying which version of the application is running in a particular environment.
Logging Configuration
With the loggers endpoint enabled, you can view and change log levels at runtime by sending POST requests to /actuator/loggers/{logger-name}
with a JSON body specifying the desired level.
Security
Our security configuration permits anonymous access to non-sensitive endpoints like health and info, while requiring authentication with the ACTUATOR_ADMIN role for all other endpoints.
Best Practices
Based on my experience implementing Actuator in production systems, here are some best practices to follow:
1. Be Selective with Endpoint Exposure
Don't expose all endpoints in production. Instead, be explicit about which ones you need:
management.endpoints.web.exposure.include=health,info,metrics,prometheus
2. Secure Endpoints Properly
Always secure sensitive endpoints. Consider:
- Using a separate management port accessible only from internal networks
- Implementing strong authentication for management endpoints
- Limiting access to specific IP ranges
# Use a different port for actuator endpoints management.server.port=8081
3. Customize Health Indicators
Create custom health indicators for all critical dependencies. This provides a complete picture of your application's health status.
4. Implement Business-Relevant Metrics
Don't just rely on technical metrics. Track business-specific metrics that matter to your domain:
- Number of active users
- Transaction volumes
- Business process success/failure rates
- Domain-specific performance indicators
5. Use Tags for Metric Dimensions
Tags make your metrics more powerful by allowing multi-dimensional analysis:
Counter.builder("app.orders.created") .tag("channel", order.getChannel()) .tag("product", order.getProductType()) .register(registry) .increment();
6. Integrate with Monitoring Systems
Actuator works well with various monitoring systems. For production use, consider:
- Prometheus + Grafana for metrics collection and visualization
- Spring Boot Admin for a ready-made UI dashboard
- ELK stack for advanced log analysis
7. Add Spring Boot Admin
For a quick visual dashboard of your Actuator data, add Spring Boot Admin to your project:
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> <version>3.2.0</version> </dependency>
8. Include Version Information
Always expose application version info to aid in troubleshooting:
# In application.properties info.app.name=${project.name} info.app.version=${project.version} info.app.build-timestamp=${maven.build.timestamp}
9. Use Health Groups
Organize health indicators into logical groups (available since Spring Boot 2.3):
management.endpoint.health.group.readiness.include=db,redis,kafka management.endpoint.health.group.liveness.include=ping,diskSpace
10. Rate Limit Access to Endpoints
For high-traffic environments, consider implementing rate limiting for Actuator endpoints to prevent DoS risks.
Conclusion
Spring Boot Actuator is one of those features that transforms how you operate your applications in production. With minimal configuration, you get deep insights into your application's health, performance, and behavior.
In this post, we've covered:
- Setting up Actuator in your Spring Boot application
- Creating custom health indicators for dependency checks
- Implementing business-specific metrics
- Adding custom application information
- Securing sensitive endpoints
- Best practices for production deployment
While the examples we've covered are a great starting point, Actuator offers even more capabilities worth exploring, like HTTP tracing, audit events, and scheduled task insights.
The effort required to implement Actuator is minimal, yet the operational benefits are substantial. In today's world of microservices and distributed systems, having robust monitoring and management capabilities isn't optional—it's essential. And Spring Boot Actuator makes achieving this remarkably simple.
So, what are you waiting for? If you haven't already, add Actuator to your Spring Boot applications today. Your future self (and your DevOps team) will thank you!
Have you implemented Actuator in your projects? What metrics have you found most valuable? Let me know in the comments below!
Description: Master Spring Boot Actuator with this comprehensive guide covering health checks, metrics, and monitoring. Learn implementation best practices with real code examples to improve your application's observability and management capabilities.