Files
spring-boot-demo/observability/README.md
T
Claude 03bdf7ee87 Add observability: real OTLP metrics/traces to grafana/otel-lgtm, Docker Compose auto-wiring, and a dual-version (Boot 4.0 vs 4.1) proof of the new OTEL_* env var support
Companion module for the rewritten ankurm.com Prometheus/Grafana monitoring post. Verified
against a real running grafana/otel-lgtm container (not mocked): 8 real requests produce a real
orders_placed_total metric queried back from the bundled Prometheus-compatible API with zero
management.otlp.* properties, auto-wired entirely by Boot's Docker Compose service-connection
detection. Two real findings surfaced along the way and documented rather than smoothed over:
@Observed silently produces no span without an explicit ObservedAspect bean (AspectJ weaving
alone is not sufficient, despite Micrometer Tracing being active), and OTEL_EXPORTER_OTLP_ENDPOINT
already worked on Boot 4.0 via Micrometer's own OtlpConfig fallback -- what's actually new in 4.1
is the rest of the standard OTEL_* surface (verified with OTEL_METRIC_EXPORT_INTERVAL against
identical source compiled on both Boot 4.0.8 and 4.1.1).

Also fixes the root README's module table, which was missing a row for
resilience4j-circuit-breaker (added in a previous commit but never indexed here).
2026-09-18 09:32:34 +00:00

4.5 KiB

observability

Companion module for the ankurm.com post "A Practical Guide to Monitoring Spring Boot Microservices: Prometheus, Grafana, and Boot 4.1's OpenTelemetry Starter" (the original 2025 Prometheus + Grafana walkthrough, rewritten around spring-boot-starter-opentelemetry). Every metric and trace quoted in the post came out of a real grafana/otel-lgtm container, driven by real HTTP traffic against a real running app -- not a diagram, not an invented log line.

For the deep, start-to-finish Micrometer/OpenTelemetry treatment -- what spring-boot-starter-opentelemetry actually changes, the Observation API, cardinality, context propagation -- see Micrometer to OpenTelemetry: The Spring Boot 4 Observability Guide, already on this blog. This module exists to run a handful of that guide's claims against real infrastructure rather than just restate them, and it found two gaps along the way: @Observed needs a bean the guide doesn't mention, and the OTLP endpoint env var it demonstrates was not, in fact, new in Boot 4.1 -- only the rest of the standard variable surface was.

Lives in this container repo (not as its own top-level repository) alongside ../actuator-in-production, the companion module for Boot 4's Actuator endpoints generally.

Versions (verified against repo1.maven.org maven-metadata.xml and primary-source release notes)

Component Version Notes
JDK 25 (Temurin 25.0.4.1+1) latest LTS
Spring Boot 4.1.1 latest GA at time of writing
Spring Framework 7.0.9 latest GA
grafana/otel-lgtm latest (LGTM_VERSION v0.33.0 at time of writing) Loki + Grafana + Tempo + Prometheus-compatible backend + OTLP collector, one image

env-var-proof/ additionally builds against spring-boot-starter-parent 4.0.8, on purpose -- see docs/03-otel-env-vars.md.

Quickstart

./scripts/run.sh              # starts on :8080; auto-starts grafana/otel-lgtm via Docker Compose
./scripts/run.sh fulltrace    # same, with 100% trace sampling instead of the 10% default
./scripts/run-all.sh          # regenerates every file in docs/output/ from a real run (Docker, ~6 min)
./scripts/run-env-var-proof.sh   # the Boot 4.0 vs 4.1 OTEL_* env var experiment on its own

curl -X POST localhost:8080/orders/1
open http://localhost:3000          # Grafana, admin/admin
curl "http://localhost:9090/api/v1/query?query=orders_placed_total"
curl "http://localhost:3200/api/search?limit=10"

Requires JDK 25, Maven, and Docker with network access (to pull grafana/otel-lgtm, roughly 1.5GB). First run must be online for Maven too.

What's demonstrated where

Area Source Transcript
Docker Compose auto-wires the OTLP endpoint with zero management.otlp.* properties compose.yaml, application.yml 00
Real metrics, real requests, queried back from LGTM's own Prometheus-compatible API OrderController 01
Default 0.10 trace sampling vs fulltrace profile (1.0) application.yml 02
@Observed is inert without an explicit ObservedAspect bean ObservationConfig 03
OTEL_* env vars: what's genuinely new in Boot 4.1 vs what already worked on 4.0 env-var-proof/ 04

Documentation chapters

  1. Migrating to spring-boot-starter-opentelemetry -- what replaces the old Prometheus-registry-plus-scrape-config setup, and Docker Compose auto-wiring proven with a real container
  2. The Observation API and @Observed -- the missing ObservedAspect bean
  3. OTEL_* environment variables -- Boot 4.0 vs 4.1, dual-version proof, plus the trace-sampling gotcha it surfaced
  4. Production checklist

License

MIT -- see ../LICENSE.