Spring Boot Actuator

1 minute read

Actuator exposes production-ready endpoints — health checks, metrics, environment info, and more.


Setup

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
  endpoints:
    web:
      exposure:
        include: health, info, metrics, prometheus, env
  endpoint:
    health:
      show-details: when-authorized
  info:
    env:
      enabled: true

Key Endpoints

Endpoint Purpose
/actuator/health App health status
/actuator/info App info (version, description)
/actuator/metrics All available metrics
/actuator/metrics/{name} Specific metric
/actuator/env Environment properties
/actuator/prometheus Prometheus-format metrics

Health Endpoint

{
  "status": "UP",
  "components": {
    "db": { "status": "UP", "details": { "database": "PostgreSQL" } },
    "diskSpace": { "status": "UP" },
    "redis": { "status": "UP" }
  }
}

Custom Health Indicator

@Component
public class BookstoreHealthIndicator implements HealthIndicator {

    private final BookRepository bookRepository;

    public BookstoreHealthIndicator(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    @Override
    public Health health() {
        long count = bookRepository.count();
        if (count > 0) {
            return Health.up()
                .withDetail("bookCount", count)
                .withDetail("status", "Bookstore has data")
                .build();
        }
        return Health.down()
            .withDetail("bookCount", 0)
            .withDetail("status", "No books in store")
            .build();
    }
}

Prometheus Integration

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
management:
  endpoints:
    web:
      exposure:
        include: prometheus, health
  prometheus:
    metrics:
      export:
        enabled: true

Visit /actuator/prometheus → Prometheus scrapes this endpoint → Grafana dashboards.

Custom Metrics

@Service
public class BookService {

    private final Counter bookCreatedCounter;
    private final Timer bookSearchTimer;

    public BookService(MeterRegistry registry, BookRepository bookRepository) {
        this.bookCreatedCounter = Counter.builder("bookstore.books.created")
            .description("Number of books created")
            .register(registry);
        this.bookSearchTimer = Timer.builder("bookstore.books.search")
            .description("Book search duration")
            .register(registry);
    }

    public BookResponse create(CreateBookRequest request) {
        Book book = bookRepository.save(/* ... */);
        bookCreatedCounter.increment();
        return BookResponse.from(book);
    }

    public Page<BookResponse> search(String query, Pageable pageable) {
        return bookSearchTimer.record(() ->
            bookRepository.searchByTitle(query, pageable).map(BookResponse::from)
        );
    }
}

Securing Actuator

.authorizeHttpRequests(auth -> auth
    .requestMatchers("/actuator/health").permitAll()
    .requestMatchers("/actuator/**").hasRole("ADMIN")
    .anyRequest().authenticated()
)

Key Takeaways

  1. Actuator = production monitoring out of the box.
  2. Expose only what you need — /health public, others secured.
  3. Prometheus + Grafana = industry-standard monitoring.
  4. Create custom health indicators for business-specific checks.
  5. Custom metrics with Micrometer counters and timers.

What’s Next?

Next: Spring Boot Testing — @SpringBootTest, @WebMvcTest, MockMvc, and @DataJpaTest.

Updated: