Integrate OpenTelemetry with Spring Boot in 5 Minutes for Microservice Monitoring and Tracing
This guide shows how to quickly add OpenTelemetry to a Spring Boot microservice, covering Docker‑based Jaeger setup, Maven dependencies, YAML configuration, automatic instrumentation, custom spans, production tuning, e‑commerce tracing examples, and common pitfalls to avoid.
Why OpenTelemetry?
In a microservice architecture, diagnosing cross‑service failures—such as a payment error or slow response—can be extremely hard. OpenTelemetry (OTel), a CNCF project, unifies tracing, metrics, and logs, and a 2024 DevOps report says it can cut fault‑location time by 67%.
1. Quick Local Setup
Start Jaeger
Run the all‑in‑one Jaeger container with a single Docker command:
docker run -d -p 16686:16686 -p 4317:4317 \
-e COLLECTOR_OTLP_ENABLED=true \
jaegertracing/all-in-oneAccess the UI at http://localhost:16686 to view traces.
2. Add Spring Boot Dependency
Include the OpenTelemetry starter in pom.xml (or Gradle):
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>3. Configure application.yml
opentelemetry:
service.name: payment-service
traces.exporter: otlp
metrics.exporter: none
logs.exporter: none
protocol: grpc
endpoint: http://localhost:43172. Automatic Instrumentation
OTel automatically captures key operations without code changes:
HTTP requests (method, path, status)
JDBC queries (parameterized SQL, no sensitive data)
Kafka/RabbitMQ message send/receive
For example, a simple controller needs no extra annotations:
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
// Span name generated automatically: GET /orders/{id}
@GetMapping("/{id}")
public Order getOrder(@PathVariable Long id) {
return orderService.findById(id);
}
}3. Custom Spans for Business Details
When deeper insight is required (e.g., payment amount, risk‑check results), create spans manually:
@Service
public class PaymentService {
public Payment processPayment(PaymentRequest request) {
Span span = Span.current()
.setAttribute("payment.amount", request.getAmount())
.setAttribute("payment.currency", "CNY");
span.addEvent("risk_check_start");
riskService.check(request);
span.addEvent("risk_check_complete");
try (Scope scope = span.makeCurrent()) {
return paymentGateway.charge(request);
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR);
throw e;
}
}
}4. Production‑Ready Configuration
After development validation, tune the following settings to balance performance and observability:
sampling.probability : 0.1‑0.2 (recommended for 10k QPS to avoid full‑sample overload)
batch.export.delay : 500 ms (trade‑off between latency and throughput)
max.export.batch : 512 (prevent memory spikes)
5. E‑Commerce Use‑Case
Trace Visualization
A typical payment flow—order → payment → risk check → bank gateway—appears as a single trace in Jaeger, allowing you to spot slow stages such as a 200 ms risk‑check latency.
Metrics with Grafana & Prometheus
# Payment success rate (1‑minute window)
sum(rate(payment_completed_total[1m])) by (method) /
sum(rate(payment_started_total[1m]))Creating a Grafana panel for this query provides real‑time success‑rate monitoring and early alerts.
6. Pitfalls to Avoid
Thread‑Pool Context Loss
When using a thread pool, traces can break. Add an OTel context decorator:
@Configuration
public class ThreadPoolConfig {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setTaskDecorator(new OtelContextDecorator());
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
return executor;
}
}Span Naming Rules
Wrong: /orders/123 (dynamic, prevents aggregation)
Correct: /orders/{id} (template‑based, aggregates automatically)
7. Recommended Toolchain
Development: Jaeger All‑in‑One (lightweight, zero‑config)
Production: SigNoz + Prometheus (scalable storage and advanced analysis)
8. Official Resources
OpenTelemetry Java docs: https://opentelemetry.io/docs/instrumentation/java/
Spring Boot integration examples: https://github.com/open-telemetry/opentelemetry-java-instrumentation
Conclusion
Integrating OpenTelemetry with Spring Boot provides a simple, efficient way to achieve full‑stack tracing and monitoring for microservices, turning vague fault‑location into precise, actionable insight.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
