OpenTelemetry: Der vollständige Guide zu Observability 2026

OpenTelemetry hat die Art, wie wir Anwendungen beobachten, grundlegend verändert. Wo früher jedes Monitoring-Tool seinen eigenen Agent, sein eigenes SDK und sein eigenes Datenformat hatte, bietet OpenTelemetry heute einen einheitlichen, vendor-agnostischen Standard. Dieser Guide erklärt die Kernkonzepte und den praktischen Einsatz.

Was ist OpenTelemetry?

OpenTelemetry (kurz: OTel) ist ein CNCF-Projekt (Cloud Native Computing Foundation), das aus der Fusion von OpenCensus und OpenTracing entstanden ist. Es definiert einen Standard für die Erfassung, Verarbeitung und den Export von Telemetrie-Daten.

Die drei Säulen der Observability:

  1. Traces — Verfolgung einzelner Requests durch ein verteiltes System (wer hat was wann aufgerufen?)
  2. Metrics — Numerische Messwerte über Zeit (Anfragen/Sekunde, Latenz, Fehlerrate)
  3. Logs — Strukturierte Ereignis-Aufzeichnungen mit Kontext

OpenTelemetry verbindet alle drei zu einem kohärenten Observability-Bild — und zwar framework- und vendor-agnostisch.

Das OpenTelemetry-Ökosystem

OpenTelemetry SDK

Für jede Programmiersprache gibt es ein offizielle OTel-SDK:

  • JavaScript/TypeScript (@opentelemetry/api, @opentelemetry/sdk-node)
  • Python (opentelemetry-api, opentelemetry-sdk)
  • Go (go.opentelemetry.io/otel)
  • Java (OTel Java Agent — Zero-Code-Instrumentation)
  • Rust (opentelemetry crate)

OpenTelemetry Collector

Der OTel Collector ist das Herzstück vieler OTel-Deployments: Er empfängt Telemetrie-Daten von Anwendungen, verarbeitet sie (Filtering, Sampling, Enrichment) und exportiert sie zu verschiedenen Backends.

App (OTel SDK) → OTel Collector → [Jaeger, Prometheus, Grafana Loki, ...]

Der Collector entkoppelt Anwendung und Backend — das Backend kann gewechselt werden, ohne den Anwendungs-Code zu ändern.

OTLP: Das Protokoll

OTLP (OpenTelemetry Protocol) ist das Übertragungsprotokoll für OTel-Daten. Es basiert auf Protobuf und unterstützt gRPC und HTTP/JSON. Alle modernen Observability-Backends (Jaeger, Tempo, Prometheus, Loki, Datadog, New Relic) unterstützen heute OTLP-Ingestion.

Traces: Distributed Tracing verstehen

Ein Trace repräsentiert den Lebensweg eines einzelnen Requests durch ein System. Er besteht aus Spans — Einheiten von Arbeit mit Start- und Endzeit, Attributen und Statuscode.

Beispiel: Ein HTTP-Request an eine API:

[HTTP Request /api/users] (50ms)
  ├── [Auth Middleware] (2ms)
  ├── [DB Query: SELECT users] (40ms)
  │     └── [TCP Connect to DB] (5ms)
  └── [JSON Serialization] (1ms)

Jeder Span hat:

  • Trace ID — eindeutige ID des gesamten Requests
  • Span ID — eindeutige ID dieses spezifischen Spans
  • Parent Span ID — ID des übergeordneten Spans (für Baumstruktur)
  • Attributes — Key-Value-Metadaten (http.method, db.statement, etc.)
  • Events — zeitgestempelte Ereignisse innerhalb des Spans
  • Status — OK, ERROR, UNSET

Automatische Instrumentierung

Für viele Frameworks gibt es Zero-Code-Instrumentation:

Node.js:

// Automatische Instrumentierung für HTTP, Express, gRPC, etc.
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')

const sdk = new NodeSDK({
  instrumentations: [getNodeAutoInstrumentations()],
})
sdk.start()

Das instrumentiert automatisch: HTTP-Module, Express/Fastify/Koa, gRPC, MySQL, PostgreSQL, Redis, MongoDB und Dutzende weitere Libraries — ohne den eigentlichen Anwendungs-Code zu ändern.

Java:

# Java Agent — keine Code-Änderungen nötig
java -javaagent:opentelemetry-javaagent.jar \
     -Dotel.service.name=my-service \
     -Dotel.exporter.otlp.endpoint=http://collector:4317 \
     -jar myapp.jar

Manuelle Instrumentierung

Für business-spezifische Traces schreibt man Custom Spans:

const { trace } = require('@opentelemetry/api')
const tracer = trace.getTracer('my-service', '1.0.0')

async function processOrder(orderId) {
  return tracer.startActiveSpan('processOrder', async (span) => {
    span.setAttribute('order.id', orderId)
    try {
      const result = await db.fetchOrder(orderId)
      span.setAttribute('order.items', result.items.length)
      return result
    } catch (err) {
      span.setStatus({ code: SpanStatusCode.ERROR, message: err.message })
      span.recordException(err)
      throw err
    } finally {
      span.end()
    }
  })
}

Metrics: Von Prometheus-Format zu OTLP

OpenTelemetry unterstützt gängige Metrik-Typen:

  • Counter — Monoton steigende Werte (Requests, Errors)
  • Gauge — Aktueller Wert (RAM-Verbrauch, aktive Verbindungen)
  • Histogram — Verteilung von Werten (Request-Latenz-Quantile)
const { metrics } = require('@opentelemetry/api')
const meter = metrics.getMeter('my-service')

const requestCounter = meter.createCounter('http_requests_total', {
  description: 'Total HTTP requests',
})

const requestDuration = meter.createHistogram('http_request_duration_ms', {
  description: 'HTTP request duration in milliseconds',
})

// Verwendung
app.use((req, res, next) => {
  const start = Date.now()
  res.on('finish', () => {
    requestCounter.add(1, { method: req.method, status: res.statusCode })
    requestDuration.record(Date.now() - start, { route: req.path })
  })
  next()
})

Der OTel Collector: Konfiguration

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  # Prometheus Scraping auch möglich
  prometheus:
    config:
      scrape_configs:
        - job_name: 'my-service'
          static_configs:
            - targets: ['my-service:8080']

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024

  # Sensible Daten entfernen
  attributes:
    actions:
      - key: db.statement
        action: delete

exporters:
  # Zu Jaeger für Traces
  jaeger:
    endpoint: jaeger:14250

  # Zu Prometheus für Metrics
  prometheus:
    endpoint: "0.0.0.0:8889"

  # Zu Loki für Logs
  loki:
    endpoint: http://loki:3100/loki/api/v1/push

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, attributes]
      exporters: [jaeger]
    metrics:
      receivers: [otlp, prometheus]
      processors: [batch]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [loki]

Exemplars: Traces und Metrics verbinden

Ein mächtiges OTel-Feature: Exemplars verbinden Metrics mit Traces. Wenn die Latenz plötzlich steigt, kann direkt auf einen repräsentativen Trace geklickt werden — ohne separat suchen zu müssen.

In Grafana: Prometheus-Metrik mit Exemplars → Direktlink zu Jaeger/Tempo-Trace. Das verkürzt die Mean Time to Resolution (MTTR) erheblich.

Sampling: Kosten kontrollieren

Tracing jeder Anfrage ist teuer. Sampling-Strategien:

Head-Based Sampling: Entscheidung beim ersten Span — z.B. nur 10% der Traces speichern.

Tail-Based Sampling (im Collector): Erst wenn der Trace vollständig ist, Entscheidung treffen — z.B. alle Error-Traces behalten, aber nur 1% der OK-Traces.

# Tail Sampling im OTel Collector
processors:
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: errors-policy
        type: status_code
        status_code: {status_codes: [ERROR]}
      - name: probabilistic-policy  
        type: probabilistic
        probabilistic: {sampling_percentage: 10}

OTel im Self-Hosting-Stack

Für einen vollständigen Self-Hosted Observability Stack:

Komponente Tool Rolle
Traces Jaeger oder Tempo Trace-Storage & UI
Metrics Prometheus Metric-Storage
Logs Loki Log-Aggregation
Visualisierung Grafana Unified Dashboard
Kollektor OTel Collector Daten-Pipeline

Grafana bietet heute native Integration aller vier Systeme und ermöglicht es, von einer Metric-Anomalie direkt zum zugehörigen Trace zu navigieren — das ist die Stärke von OpenTelemetry als einheitlichem Standard.

Fazit: Warum OpenTelemetry?

OpenTelemetry hat das Observability-Landschaft grundlegend verändert:

  1. Vendor-Agnostisch: Code bleibt unverändert, egal ob Jaeger, Datadog oder New Relic als Backend gewählt wird
  2. Einheitliches Datenmodell: Traces, Metrics und Logs nach einem gemeinsamen Standard
  3. Community-getrieben: CNCF-Projekt mit Support von Google, Microsoft, AWS, Datadog und Hunderten weiterer Unternehmen
  4. Zukunftssicher: OTel ist der defacto-Standard für Cloud-Native Observability

Für jeden, der microservice-basierte Anwendungen betreibt, ist OpenTelemetry heute keine Option mehr — es ist die Grundlage jeder ernsthaften Observability-Strategie.