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:

  1. Grafana + Tempo für Traces starten (via Docker Compose)
  2. OTel Collector in den Stack aufnehmen
  3. Eine App mit Auto-Instrumentation testen
  4. 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.