Instrument a Spring Boot Microservice with OpenTelemetry Auto-Instrumentation and Jaeger
A step-by-step guide to adding OpenTelemetry auto-instrumentation to a Java Spring Boot app, exporting spans to Jaeger via OTLP, and verifying distributed traces.
08 Dec 2025, 12:56 UTC

Goal
Enable end-to-end tracing for a Spring Boot microservice without modifying application source code. By using the OpenTelemetry Java agent, you can automatically generate spans for HTTP requests, JDBC queries, and gRPC calls, then export them to a Jaeger backend via the OpenTelemetry Protocol (OTLP) over gRPC.
Prerequisites
- Java 17 or newer installed.
- Spring Boot 2.7+ or 3.x.
- A Jaeger instance reachable on port 14250 (OTLP gRPC endpoint).
- Network access to the Jaeger UI on port 16686.
Setup Procedure
- Download the Java Agent
Download the latest
otel-javaagent.jarfrom the official OpenTelemetry Java instrumentation releases. This JAR acts as a runtime agent that modifies bytecode to inject tracing logic. - Configure Agent Parameters
Configuration can be handled via system properties or a YAML file. Using a YAML file is recommended for complex environments to avoid excessively long startup commands.
otel: service: name: my-spring-service resource: attributes: - service.namespace=demo sampler: type: probability param: 0.1 exporter: otlp: endpoint: http://jaeger-collector:14250 compression: gzip logging: level: infoThe
sampler.param: 0.1setting implements probability sampling, capturing 10% of traces to reduce telemetry overhead and JVM memory pressure. - Launch the Application
Run the application by passing the
-javaagentflag. This must be specified before the-jarargument.# Running via CLI java -javaagent:/path/to/otel-javaagent.jar \ -Dotel.config.file=/path/to/otel-configuration.yaml \ -jar myapp.jarFor containerized deployments, include the agent and config in your Dockerfile:
FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY myapp.jar . COPY otel-javaagent.jar . COPY otel-configuration.yaml . ENTRYPOINT ["java", "-javaagent:/app/otel-javaagent.jar", "-Dotel.config.file=/app/otel-configuration.yaml", "-jar", "myapp.jar"]
Verification
To confirm the instrumentation is active and communicating with the backend:
- Trigger Traffic: Execute a request against your service:
curl -i http://localhost:8080/api/hello. - Inspect Jaeger UI: Navigate to
http://localhost:16686, selectmy-spring-servicefrom the service dropdown, and click Find Traces. - Diagnostic Logs: If traces are missing, restart the app with
-Dotel.logging.level=debug. Search the logs forSpanExporterevents to verify if spans are being sent or if the agent is encountering connection timeouts.
Operational Checks & Limitations
| Check | Expected Result | Risk/Limitation |
|---|---|---|
| Memory Usage | JVM heap increase of ~20-50MB | May cause OOM if -Xmx is too tight |
| Sampling Rate | ~10% of requests traced | Low rates may miss intermittent errors |
| Context Propagation | Continuous trace across services | Custom HTTP clients may require manual propagation |
Recovery & Troubleshooting
Issue: No traces appear in Jaeger
- Verify network connectivity to the OTLP port:
telnet jaeger-collector 14250. - Ensure the
otel.exporter.otlp.endpointis correct. Note that OTLP gRPC typically uses port 4317 or 14250 depending on the Jaeger version.
Issue: High Resource Consumption
- Lower the sampling rate (e.g.,
param: 0.01). - Disable specific instrumentations that are too noisy using
-Dotel.instrumentation.jdbc.enabled=false.
Rollback: To remove instrumentation, remove the -javaagent and -Dotel.config.file flags from the startup command and restart the JVM.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.