Files
spring-boot-demo/actuator-in-production/docs/01-what-actuator-exposes.md
Ankur Mhatre 958b401f0f Spring Boot startup time: bean-by-bean diagnosis, and one directory per post
Adds spring-boot-startup-time/, the companion project for BLOG-618: a runnable
Spring Boot 4.1.1 application on JDK 25 that installs BufferingApplicationStartup
and FlightRecorderApplicationStartup behind a system property, and a /diag/startup
endpoint that computes step self time -- the number /actuator/startup does not give
you and the one that names the actual culprits.

Captured under docs/output/: the step tree sorted both ways, the same startup as JFR
events, a +5000-class experiment putting 0.11 ms per scanned class on the classpath
scan tax, the silent truncation a 2048-step buffer performs, and JDK 25 AOT cache
timings (6.93 s to 4.82 s). Post body and metadata live in post/.

Moves the existing Actuator project into actuator-in-production/ so the repository
holds one directory per article; the root README is now an index.
2026-09-05 00:17:37 +05:30

2.4 KiB

← README · 01 · What Actuator actually exposes · 02 What changed in Spring Boot 4 →

01 — What Actuator actually exposes

Add the starter, configure nothing, and ask the application what it publishes.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

The answer, from ../docs/output/01-default-exposure.txt:

{"_links":{"self":{...},"health":{...},"health-path":{...}}}

One endpoint. GET /actuator/env returns 404, not 403 — it was discovered, it exists as a JMX endpoint, and it is simply not mapped onto HTTP.

That distinction matters more than it looks:

  • Discovery — Actuator finds every @Endpoint bean on the classpath.
  • Access (management.endpoint.<id>.access) — whether the endpoint may be operated at all. Defaults to unrestricted for everything except heapdump and shutdown.
  • Exposure (management.endpoints.web.exposure.include) — whether it is mapped onto HTTP. Defaults to health only.

All three have to line up. A 404 from an Actuator path tells you nothing about whether the endpoint is enabled, and people read it as "it's off" when it is often "it's on, over JMX".

The default health body

{"groups":["liveness","readiness"],"status":"DOWN"}

Two things to notice.

The groups are there by default. In Spring Boot 3 the liveness and readiness probes only appeared when you asked for them or when Boot detected Kubernetes. In Boot 4 they are enabled out of the box — see chapter 02.

show-details defaults to never, so even an authenticated caller sees a bare status. That is a sensible default and almost everyone overrides it to always without thinking about who can reach the endpoint. Chapter 04 covers the middle option.

The status is DOWN because this repository registers a Kafka indicator and there is no broker. One custom indicator that touches a third party is all it takes to turn the default /actuator/health red — and that URL is what most Kubernetes manifests point their readiness and liveness probes at. Chapter 07 is about not doing that.


← README · 01 · 02 What changed in Spring Boot 4 →