Jaeger is an open-source distributed tracing platform. It monitors and troubleshoots transactions in complex distributed systems, helping you find bottlenecks, trace requests across services, and debug latency issues.
What Is Jaeger?
Jaeger is a CNCF graduated project originally built by Uber. It collects distributed traces from microservices and provides a UI to visualize request flows, identify slow services, and analyze dependencies.
Key Features:
- Distributed context propagation
- Service dependency analysis
- Root cause analysis
- Adaptive sampling
- Multiple storage backends (Cassandra, Elasticsearch, Kafka)
- OpenTelemetry native support
- REST and gRPC API
- Service performance monitoring
Quick Start
# All-in-one (dev/testing)
docker run -d --name jaeger -p 16686:16686 -p 4317:4317 -p 4318:4318 \
jaegertracing/all-in-one:latest
# UI at http://localhost:16686
Instrument Your App
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
# Setup
resource = Resource.create({"service.name": "order-service"})
provider = TracerProvider(resource=resource)
provider.add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4317"))
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("order-service")
# Create traces
with tracer.start_as_current_span("process-order") as span:
span.set_attribute("order.id", "ORD-12345")
span.set_attribute("order.total", 99.99)
with tracer.start_as_current_span("validate-payment"):
span.add_event("Payment validated")
with tracer.start_as_current_span("update-inventory"):
span.add_event("Inventory updated")
with tracer.start_as_current_span("send-confirmation"):
span.add_event("Email sent")
Jaeger Query API
import requests
JAEGER = "http://localhost:16686/api"
# List services
services = requests.get(f"{JAEGER}/services").json()
print(f"Services: {services['data']}")
# Get traces for a service
traces = requests.get(f"{JAEGER}/traces", params={
"service": "order-service",
"limit": 20,
"lookback": "1h"
}).json()
for t in traces["data"]:
spans = t["spans"]
duration_ms = spans[0]["duration"] / 1000
print(f"Trace {t['traceID'][:8]}: {len(spans)} spans, {duration_ms:.1f}ms")
# Get specific trace
trace_data = requests.get(f"{JAEGER}/traces/{trace_id}").json()
for span in trace_data["data"][0]["spans"]:
print(f" {span['operationName']}: {span['duration']/1000:.1f}ms")
# Get service dependencies
deps = requests.get(f"{JAEGER}/dependencies", params={
"endTs": int(time.time() * 1000),
"lookback": 86400000 # 24h in ms
}).json()
for dep in deps["data"]:
print(f"{dep['parent']} -> {dep['child']}: {dep['callCount']} calls")
Get Operations for Service
ops = requests.get(f"{JAEGER}/services/order-service/operations").json()
for op in ops["data"]:
print(f"Operation: {op}")
Resources
- Jaeger Docs
- Jaeger GitHub — 20K+ stars
- API Reference
Need to scrape web data for your microservices? Check out my web scraping tools on Apify — production-ready actors for Reddit, Google Maps, and more. Questions? Email me at spinov001@gmail.com
Top comments (0)