DEV Community

Alex Spinov
Alex Spinov

Posted on

Jaeger Has a Free API: Distributed Tracing for Microservices

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
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

Get Operations for Service

ops = requests.get(f"{JAEGER}/services/order-service/operations").json()
for op in ops["data"]:
    print(f"Operation: {op}")
Enter fullscreen mode Exit fullscreen mode

Resources


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)