Distributed Tracing with Sleuth and Zipkin [Java Spring Boot Mastery Series – Part 18]
In a microservices architecture, tracing a single request that flows across multiple services is essential for debugging, monitoring, and performance analysis.
Spring Cloud Sleuth and Zipkin help trace and visualize requests across services.
🔍 What is Distributed Tracing?
Distributed tracing allows you to track a request as it moves through multiple microservices. It helps answer:
- Which services were involved?
- How much time did each take?
- Where are the bottlenecks or failures?
🛠️ Key Tools
| Tool | Purpose |
|---|---|
| Sleuth | Automatically adds trace & span IDs to logs |
| Zipkin | Aggregates traces and provides a UI to analyze them |
🧱 Architecture
[Client] → [Service A] → [Service B] → [Service C]
\_________ Sleuth sends data to Zipkin _________/
⚙️ Step-by-Step Setup
🔹 1. Add Dependencies (Each Microservice)
In pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
🔁 Make sure your
spring-cloud.versionmatches your Spring Boot version.
🔹 2. Basic Configuration
In application.yml:
spring:
application:
name: service-a
zipkin:
base-url: http://localhost:9411
enabled: true
sleuth:
sampler:
probability: 1.0 # 100% of requests will be traced (for development)
🔹 3. Run Zipkin Server
Option 1: Use Docker
docker run -d -p 9411:9411 openzipkin/zipkin
Zipkin UI: http://localhost:9411
Option 2: Run from JAR
Download the Zipkin JAR from https://zipkin.io and run:
java -jar zipkin-server.jar
🔗 How Sleuth Works (Behind the Scenes)
- Trace ID: A unique identifier for the entire request flow.
- Span ID: Represents a single unit of work (e.g., a method or service call).
- Parent Span ID: Refers to the calling span.
Sleuth injects these into logs and headers automatically:
[TraceId=abc123] [SpanId=def456] Calling Service B
HTTP Headers:
| Header | Meaning |
|---|---|
X-B3-TraceId | ID of the trace |
X-B3-SpanId | ID of the current span |
X-B3-ParentSpanId | Parent span |
X-B3-Sampled | Whether it should be traced |
🧪 Test: Simulate a Multi-Service Call
- Service A calls Service B
- Both log their trace and span info
Controller in Service A
@RestController
@RequestMapping("/a")
public class ServiceAController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/callB")
public String callB() {
return restTemplate.getForObject("http://localhost:8082/b/hello", String.class);
}
}
Controller in Service B
@RestController
@RequestMapping("/b")
public class ServiceBController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from B!";
}
}
Logs in both services will include the same trace ID.
🔧 RestTemplate + Sleuth (Auto-propagation)
Sleuth automatically injects tracing headers in RestTemplate and WebClient.
Make sure RestTemplate is a Spring Bean:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
🔎 View in Zipkin UI
- Visit http://localhost:9411
- Search by service name
- Explore request timelines and call chains
🛡️ Best Practices
| Tip | Why It Matters |
|---|---|
| Use lower sample rate in production | Reduce performance overhead |
| Always use beans for HTTP clients | Enables auto-injection of trace headers |
| Combine with ELK/Grafana | For complete observability stack |
🧰 Alternatives
| Tool | Description |
|---|---|
| Jaeger | OpenTracing-compatible distributed tracer |
| OpenTelemetry | Modern standard, supports multiple exporters |
📦 Summary
- Sleuth adds trace IDs to logs and headers.
- Zipkin visualizes traces across services.
- Helps debug, monitor, and optimize microservice chains.
➡️ Next Up: Part 19 – Spring Cloud Config & Centralized Configuration Management
