OpenTelemetry Deep Dive: Observability für moderne Anwendungen
Wer verteilte Systeme betreibt, kennt das Problem: Wenn etwas schiefläuft, weißt du nicht wo. Logs? Über 3 Services verteilt. Traces? Gibt's nicht. Metriken? Vielleicht, wenn du Glück hast. OpenTelemetry (OTel) ist der Standard, der das ändert.
Was ist OpenTelemetry?
OpenTelemetry ist ein CNCF-Projekt (seit 2019), das drei Observability-Signale vereinheitlicht:
- Traces – der Weg einer Anfrage durch alle Services
- Metrics – Messdaten (CPU, Response-Time, Error-Rate)
- Logs – strukturierte Ereignisaufzeichnungen
Das Besondere: OTel ist vendor-neutral. Einmal instrumentiert, kannst du die Daten zu Jaeger, Grafana Tempo, Datadog, New Relic oder AWS X-Ray schicken – ohne Code-Änderung.
Die drei Komponenten im Überblick
1. OpenTelemetry SDK / API
Die SDKs existieren für nahezu jede Sprache: Python, Go, Java, Node.js, .NET, Rust, PHP und mehr. Sie ermöglichen Auto-Instrumentation (viele Frameworks werden automatisch instrumentiert) und manuelle Instrumentation für eigene Spans.
# Python Auto-Instrumentation – kein Code-Change nötig!
opentelemetry-instrument \
--traces_exporter otlp \
--metrics_exporter otlp \
python app.py
2. OpenTelemetry Collector
Der Collector ist ein eigenständiger Proxy, der Telemetriedaten empfängt, verarbeitet und weiterleitet. Die Architektur:
App (SDK) → OTel Collector → Backend (Jaeger/Prometheus/Grafana)
Der Collector ermöglicht:
- Batching (Netzwerk-Effizienz)
- Sampling (nur % der Traces speichern)
- Transformation (Felder umbenennen, filtern)
- Multi-Export (gleichzeitig zu Jaeger und Datadog schicken)
# docker-compose.yml für OTel Collector
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports:
- 4317:4317 # OTLP gRPC
- 4318:4318 # OTLP HTTP
3. Die Backends
OTel generiert keine Visualisierungen – dafür gibt es spezialisierte Tools:
| Backend | Traces | Metrics | Logs |
|---|---|---|---|
| Grafana Stack (Tempo + Prometheus + Loki) | Ja | Ja | Ja |
| Jaeger | Ja | Nein | Nein |
| Zipkin | Ja | Nein | Nein |
| Datadog | Ja | Ja | Ja |
| New Relic | Ja | Ja | Ja |
Für Self-Hosting ist Grafana + Tempo + Prometheus + Loki die Standardlösung.
Distributed Tracing: Wie Traces funktionieren
Ein Trace besteht aus Spans – einzelnen gemessenen Operationen. Jeder Span hat:
- Eine
trace_id(gleich für alle Spans einer Anfrage) - Eine
span_id(eindeutig pro Span) parent_span_id(für die Baumstruktur)- Start- und End-Zeit
- Attributes (HTTP Status, DB Query, etc.)
Request → Service A (Root-Span: 250ms)
├── DB-Query (Span: 15ms)
├── HTTP → Service B (Span: 180ms)
│ └── Cache-Lookup (Span: 2ms)
└── Cache-Write (Span: 8ms)
Mit einem Trace siehst du auf einen Blick, warum eine Anfrage 250ms gebraucht hat – und genau wo die Zeit verloren gegangen ist.
Praxis: OTel in Kubernetes
In Kubernetes gibt es den OTel Operator, der Auto-Instrumentation per Annotation ermöglicht:
apiVersion: v1
kind: Pod
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: "true"
Kein Rebuild, kein Code-Change – OTel wird automatisch injiziert.
Fazit: Wann OpenTelemetry?
OTel lohnt sich ab: Zwei oder mehr Services, die miteinander kommunizieren. Sobald eine Anfrage mehrere Hops macht, bist du ohne Tracing blind.
Einstiegsempfehlung für Self-Hoster:
- Grafana + Tempo für Traces starten (via Docker Compose)
- OTel Collector in den Stack aufnehmen
- Eine App mit Auto-Instrumentation testen
- Langsam weitere Services instrumentieren
OpenTelemetry ist der Industriestandard geworden – wer heute neu instrumentiert, sollte direkt OTel nutzen und nicht mehr mit proprietären Agents anfangen.