Auto‑Instrumentation in Spring Boot: One‑liner Tracing for HTTP, JDBC, and Async
Learn how to add OpenTelemetry auto‑instrumentation to a Spring Boot app with a single JVM flag, verify traces for HTTP, JDBC, and CompletableFuture flows, and understand the trade‑offs and limits of the Java agent.
26 Jul 2026, 02:50 UTC

Why Auto‑Instrumentation? The Concrete Problem
In a modern microservice, every inbound HTTP request, database query, and outbound HTTP call becomes a span. Writing a Tracer by hand for each service is tedious and error‑prone. The OpenTelemetry Java agent solves this by injecting byte‑code at JVM startup, automatically wrapping common libraries such as Spring MVC, JDBC, and HTTP clients. The result: a fully‑instrumented application without touching the source code.
Getting Started: One‑liner Command
Place the latest opentelemetry-javaagent.jar in /opt/otel/ and start your Spring Boot jar like this:
java \
-javaagent:/opt/otel/opentelemetry-javaagent.jar \
-jar myapp.jar \
--spring.profiles.active=prod
Key points:
-javaagentmust be the first JVM flag; the agent reads it before any application classes load.- Environment variables control the agent. For example:
OTEL_SERVICE_NAME=orders-service– the service name appears in every exported span.OTEL_TRACES_EXPORTER=otlp– export spans via OTLP (gRPC). Alternatives:jaeger,zipkin,logging.OTEL_TRACES_SAMPLER=parentbased_traceidratio– control sampling to reduce overhead.
Verifying the Agent Works
When the JVM starts, the agent prints a banner:
[opentelemetry] OpenTelemetry Java agent 1.24.0
[opentelemetry] Instrumented modules: spring-web, spring-jdbc, http-client, reactive-web, vertx
1. Send an HTTP request to the app (e.g., curl -X POST http://localhost:8080/orders). 2. Open Jaeger or Tempo and look for a root span named orders-service.orders. You should see child spans:
HTTP GET /orders– inbound controller span.DB SELECT * FROM orders– JDBC span.HTTP GET http://inventory-service/items– outbound call span.
Tracing Asynchronous Flows
Spring Boot often uses CompletableFuture or Reactor’s Mono/Flux. The Java agent preserves context across these boundaries. To confirm, add a header to a downstream service:
// In OrdersController
@GetMapping("/orders")
public CompletableFuture<Order> getOrder(@RequestParam String id) {
return CompletableFuture.supplyAsync(() -> orderService.fetch(id));
}
When orderService.fetch calls an HTTP client, the span exported to OTLP will contain an attribute http.request.header.x-request-id if that header was present in the original request.
Trade‑offs and Limitations
- Runtime overhead: The agent adds ~5–10 % CPU and memory usage in development. In production, enable sampling (e.g.,
OTEL_TRACES_SAMPLER=parentbased_traceidratiowithOTEL_TRACES_SAMPLER_ARG=0.01) to keep cost low. - Compatibility: Requires Java 8+ and OpenTelemetry SDK 1.17+. Older Spring Boot versions (<4.0) may miss newer instrumentation modules.
- Legacy code: Custom JDBC drivers or hand‑rolled HTTP clients that bypass standard libraries may not be automatically instrumented. Verify by inspecting exported spans and add manual
Tracercalls if gaps appear. - Context loss: If your application uses non‑reactive asynchronous frameworks (e.g., plain thread pools) without proper context propagation, spans may break. The agent supports Reactor, Vert.x, and CompletableFuture by default, but not every custom executor.
Actionable Checklist
- Download the latest agent and place it in a shared directory.
- Add
-javaagentto your startup script and setOTEL_SERVICE_NAMEandOTEL_TRACES_EXPORTER. - Run the app and confirm the agent banner appears.
- Send a test request, open your tracing UI, and verify root and child spans.
- Enable sampling for production (
OTEL_TRACES_SAMPLER=parentbased_traceidratio). - Periodically review exported spans; if any expected span is missing, add manual instrumentation.
With these steps, you’ll have end‑to‑end tracing for HTTP, JDBC, and async calls in a Spring Boot service—without touching a single line of application code.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.