Jaeger β Distributed tracing
:::caution Status: Deferred to a future phase The original Phase 21 plan called for Loki + Jaeger + Alertmanager. We deliberately scoped Phase 21 down to Loki + Alertmanager configuration only β same pattern as Phase 11 (deferred Crossplane), Phase 13 (deferred GitLab), Phase 15 (deferred Vault), Phase 16 (deferred n8n/Temporal/Airflow), Phase 18 (deferred Backstage plugins), Phase 19 (deferred MLflow + Kubeflow), Phase 20 (deferred NodeChaos + automated GameDays).
Why Jaeger is deferred:
- No microservice topology to trace through. Distributed tracing shows the call graph of a request as it traverses multiple services. Our workloads (podinfo, whoami, platform-demo, Open WebUI) are single-service β each request enters one pod, executes one handler, returns. A Jaeger UI under those conditions shows single-span boxes β the tool exists, but its value isn't visible.
- Without instrumented multi-service apps, Jaeger can't demonstrate what makes it valuable: latency attribution across services, finding the slow span in a chain of 8, or root-causing a timeout to a DB call three hops downstream.
- The metrics + logs pair already covers request-flow observability for our scale. We have request rate / error rate / latency from Prometheus, and detailed request logs from Loki β the "two of three legs" cover the visible bottlenecks.
The likely future home is when we deploy a real microservices demo β e.g., an API gateway β auth service β business logic service β database that actually emits traces via OpenTelemetry. At that point Jaeger (or Grafana Tempo) earns its keep because there's a multi-span trace tree to look at.
This page is kept as conceptual reference. The implementation has not been done. :::
What Jaeger would solveβ
Distributed tracing follows a single request as it flows through multiple services. Each service emits spans (start time, end time, parent span ID, attributes); spans assemble into a trace tree that shows where time was spent, where errors occurred, and which service introduced latency.
Without traces, you debug "why is this user's request slow?" by correlating timestamps across logs from N services. With traces, you look at one trace ID and see the full waterfall.
When Jaeger earns its keepβ
WITHOUT TRACING (single-service apps β what we have today):
user β ingress β podinfo β response
|
'-- a single span, easy to debug from logs alone
WITH TRACING (multi-service apps β what would justify Jaeger):
user β ingress β API gateway β auth β user service β DB
'-- trace shows: which service was slow,
which service errored, total wall-clock
vs sum-of-services time
Architecture (when implemented)β
Application pods (instrumented with OpenTelemetry SDK)
β
β OTLP traces over gRPC (port 4317)
βΌ
otel-collector (DaemonSet, batches + filters)
β
βΌ
Jaeger collector (or Grafana Tempo)
β
βΌ
Storage backend (Cassandra / ES / Badger / S3 for Tempo)
β
βΌ
Jaeger UI / Tempo Grafana datasource
Future install sketchβ
helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
# Or, more likely: Grafana Tempo (lighter, integrates with Loki + Prometheus)
helm repo add grafana https://grafana.github.io/helm-charts
helm install tempo grafana/tempo \
-n observability \
--set storage.trace.backend=local \
--set tempo.retention=72h
Then wire Tempo as a Grafana datasource alongside Prometheus + Loki.
Done When (not yet β deferred)β
β Multi-service demo workload exists and is instrumented with OpenTelemetry
β Tempo / Jaeger collector running in observability namespace
β At least one trace ID visible in Grafana β Explore β Tempo
β Trace tree shows >= 3 distinct services involved in a single request
β Latency attribution: ability to identify the slowest span in a trace