OpenTelemetry hat sich in kurzer Zeit zu einem der wichtigsten Infrastruktur-Projekte im Cloud-Native-Ökosystem entwickelt. Ob SRE, Backend-Entwickler, Platform Engineer oder DevOps-Praktiker — wer heute in der Softwareentwicklung arbeitet, kommt um OpenTelemetry nicht mehr herum. Es ist der neue Industriestandard dafür, wie moderne Teams Observability-Daten instrumentieren, sammeln und exportieren.
Dieser Leitfaden erklärt, was OpenTelemetry ist, wie es funktioniert und wie du es in Production bringst. Wir decken die vollständige Architektur von API bis Wire-Protokoll ab, zeigen konkrete Code-Beispiele in Python, Node.js und Java und stellen Referenztabellen für Semantic Conventions und SDK-Stabilität über alle Sprachen bereit. Am Ende hast du alles, was du brauchst, um OpenTelemetry für deinen Stack zu bewerten und eine fundierte Entscheidung zur Adoption zu treffen.
1. Was ist OpenTelemetry?
OpenTelemetry (oft als OTel abgekürzt) ist ein Open-Source-Observability-Framework — eine vendor-neutrale Sammlung von APIs, SDKs, Tools und einem Wire-Protokoll — zum Erzeugen, Sammeln und Exportieren von Telemetriedaten aus Software-Systemen. Es unterstützt drei Kategorien von Telemetrie-Signalen: Distributed Traces, Metriken und Logs.
Es ist ein graduiertes Projekt der CNCF (Cloud Native Computing Foundation) und gemessen an Contributor-Zahlen und Release-Velocity das aktivste CNCF-Projekt überhaupt — nach Kubernetes. Über 1.000 individuelle Contributors aus Hunderten von Organisationen — darunter Google, Microsoft, AWS, Datadog, Splunk, Elastic und Lightstep — pflegen und entwickeln das Projekt weiter.
Das Kernversprechen lässt sich in einem Satz formulieren: Instrumentiere deine Applikation einmal und sende die resultierende Telemetrie an jedes Backend, das OTLP versteht. Konkret bedeutet das: Du schreibst Instrumentierungs-Code einmal gegen die stabile OTel-API. Die resultierende Telemetrie kannst du heute an obseria.io senden, nächstes Jahr zu einem anderen Backend wechseln — ohne eine Zeile Applikations-Code zu ändern.
Diese Portabilität ist das, was OpenTelemetry grundlegend von allen proprietären Agenten unterscheidet, die zuvor existierten. Bei Datadog-, New-Relic- oder Dynatrace-Agenten ist dein Instrumentierungs-Code eng an den Vendor gekoppelt. Ein Wechsel bedeutet Monate der Neu-Instrumentierung über alle Services. Mit OpenTelemetry gehört die Investition in Instrumentierung dauerhaft dir.
2. Die Geschichte: Von OpenCensus und OpenTracing zu OpenTelemetry
Um zu verstehen, warum OpenTelemetry so designed ist, wie es ist, lohnt ein Blick auf seine Entstehungsgeschichte. Sie beginnt mit zwei separaten Open-Source-Initiativen aus dem Jahr 2016, die trotz überlappender Problemstellungen inkompatibel miteinander waren.
Google open-sourced OpenCensus — eine Bibliothekssammlung für das Sammeln von Distributed Traces und Metriken — basierend auf internen Erfahrungen mit Googles Dapper-Tracing-Infrastruktur. Zur gleichen Zeit veröffentlichten Ben Sigelman und Kollegen bei Lightstep OpenTracing, eine CNCF-gehostete API-Spezifikation, die sich ausschließlich auf Distributed Tracing mit einem API-first-Ansatz konzentrierte.
Beide Projekte gewannen signifikante Adoption, aber die Duplizierung der Arbeit schuf echte Probleme für das Ökosystem. Library-Autoren mussten sich für einen Standard entscheiden oder zwei separate Instrumentierungspfade pflegen. Vendor-Backends mussten beide Formate unterstützen. Teams mussten evaluieren, auf welchen Standard sie standardisieren sollten.
| Jahr | Ereignis | Bedeutung |
|---|---|---|
| 2016 | Google open-sourced OpenCensus | Erstes SDK für Metriken + Traces, basierend auf Dapper-Erfahrung |
| 2016 | OpenTracing vom Lightstep-Team veröffentlicht | CNCF-gehosteter Tracing-API-Standard; sprachagnostisches Design |
| 2017–18 | Paralleles Ökosystem-Wachstum | Zwei Standards, inkompatible Wire-Formate, fragmentierte Library-Unterstützung |
| Mai 2019 | Fusion auf der KubeCon Barcelona angekündigt | OpenCensus + OpenTracing → OpenTelemetry (CNCF Sandbox) |
| Aug 2021 | OTel zu CNCF Incubating befördert | Breite Industry-Adoption bestätigt; Governance formalisiert |
| Nov 2021 | OTel Tracing GA | Tracing-SDKs für 11 Sprachen gleichzeitig als stabil erklärt |
| 2022 | OTel Metrics GA | Metrics-SDK stabil; Prometheus-Kompatibilitätsschicht verfügbar |
| 2023 | OTel Logs GA | Logs Bridge API stabil; vollständige Abdeckung aller drei Signale |
| 2024 | OTel Profiling-Signal | Profiling-Spezifikation in den Standard aufgenommen |
| 2025 | CNCF Graduated Project | OpenTelemetry erreicht höchsten CNCF-Reifegrad |
Die Fusionsankündigung im Mai 2019 war ein Wendepunkt für die gesamte Observability-Industrie. Statt zwei halbfertiger, inkompatibler Standards hat die Branche jetzt ein einzelnes, gut verwaltetes Framework, das gleichzeitig von praktisch jedem großen Vendor und Cloud-Provider unterstützt wird. Die Wettbewerbsdynamik, die zuvor inkompatible Telemetrie-Formate produzierte, wurde durch ein kollaboratives Modell ersetzt — auch Wettbewerber tragen zum selben Standard bei, weil alle davon profitieren.
3. OpenTelemetry-Architektur: Vier Schichten, die zusammenarbeiten
OpenTelemetry ist keine einzelne Library oder Binärdatei. Es ist eine Spezifikation, die vier separate Schichten definiert, jede mit einer eigenen Verantwortlichkeit. Wer versteht, welche Schicht was tut, vermeidet die häufigsten Integrationsfehler.
API
Das sprachspezifische Interface, das Applikations- und Library-Code aufruft, um Telemetrie zu erfassen. Die API ist bewusst dünn — wenn du sie ohne installiertes SDK aufrufst, produziert sie keine Daten und erzeugt null Overhead. Library-Autoren können ihre Bibliotheken gegen die OTel-API instrumentieren, ohne eine Abhängigkeit auf ein spezifisches SDK zu erzwingen. Die API ist über Major-Versionen hinweg stabil.
SDK
Die konkrete Implementierung der API für jede Sprache. Das SDK übernimmt die schwere Arbeit: Sampling-Entscheidungen, Batching, Context Propagation, Resource Detection und konfigurierbare Exporter-Konfiguration. Application-Teams konfigurieren und initialisieren das SDK beim Start. Das SDK hat Meinungen — hier entscheidest du, wie viele Daten du sammelst, wohin du sie sendest und wie du Back-Pressure handhabst.
Collector
Eine eigenständige Infrastrukturkomponente — ein Proxy und eine Processing-Pipeline — die zwischen deinen Applikationen und deinem Observability-Backend sitzt. Er akzeptiert Daten aus mehreren Quellen (OTel-SDKs, Prometheus-Scraper, Fluent Bit, Jaeger), wendet Processing an (Attribut-Manipulation, Tail-Based Sampling, PII-Redaktion, Batching) und exportiert zu einem oder mehreren Backends. Der Collector ist optional für einfache Deployments, aber essenziell bei Scale.
OTLP
Das OpenTelemetry Protocol — die Wire-Format- und Transport-Spezifikation, die alle Teile verbindet. OTLP ist über gRPC und HTTP/JSON definiert, unterstützt alle drei Signale (Traces, Metriken, Logs) über eine einzige Verbindung und wird nativ von jedem größeren Observability-Backend unterstützt. Es ersetzt den Flickenteppich aus Jaeger Thrift, Zipkin JSON, Prometheus Exposition Format und vendor-spezifischen Ingest-APIs.
Ein typischer Production-Flow sieht so aus: Dein Applikations-Code ruft die OTel-API auf, das SDK verarbeitet und batcht die resultierende Telemetrie, sendet sie über OTLP an einen lokalen Collector-Agenten, der Collector wendet Tail-Based Sampling und Fan-out-Routing an, und die verarbeitete Telemetrie wird an dein Observability-Backend exportiert. Für Development und einfachere Workloads ist der Collector optional — du kannst direkt vom SDK an ein OTLP-kompatibles Backend exportieren.
ingest.obseria.io:4317 zu exportieren, und du bist fertig. Füge den Collector nur hinzu, wenn du Tail-Based Sampling, Multi-Backend Fan-out oder Signal-Transformation bei Scale benötigst.4. Die drei Observability-Signale: Traces, Metriken und Logs
OpenTelemetry deckt alle drei Signale ab, die moderne Observability-Praktiker als essenziell betrachten. Jedes Signal beantwortet eine andere Klasse von Fragen über dein System, und sie sind am stärksten, wenn sie zusammen verwendet und über denselben Request-Kontext korreliert werden.
Distributed Traces
Ein Trace zeichnet die vollständige Ende-zu-Ende-Reise einer einzelnen Anfrage durch dein System auf — über Service-Grenzen hinweg, Datenbankaufrufe, Message-Queue-Interaktionen und externe API-Aufrufe. Jede diskrete Arbeitseinheit innerhalb eines Traces heißt Span. Spans sind in einer Eltern-Kind-Baumstruktur angeordnet, die Kausalität darstellt: Wenn Span B durch Span A ausgelöst wurde, ist B ein Kind von A.
Jeder Span trägt einen Timing-Record (Startzeit und Dauer), einen Status (OK, Error oder Unset), einen lesbaren Namen und eine beliebige Menge von Key-Value-Attributen. Die Kombination aus Span-Baum und seinen Attributen ist das, was dir ermöglicht, Fragen zu beantworten wie: "Welcher Downstream-Service hat dazu geführt, dass diese Anfrage 3,2 Sekunden dauerte?" oder "Welche Datenbankabfrage ist für den Latenz-Spike auf unserem Checkout-Endpunkt verantwortlich?"
Context Propagation ist das, was Distributed Tracing über Service-Grenzen hinweg funktionsfähig macht. Wenn Service A Service B über HTTP oder gRPC aufruft, injiziert er Trace-Kontext (eine Trace-ID und Parent-Span-ID) in die Request-Header unter Verwendung des W3C-TraceContext-Standards. Service B extrahiert diesen Kontext und verwendet ihn, um Kind-Spans zu erstellen, die zum selben Trace gehören. Diese Propagation geschieht automatisch, wenn du OTel Auto-Instrumentation verwendest.
from opentelemetry import trace
tracer = trace.get_tracer("checkout-service", "2.1.0")
with tracer.start_as_current_span("zahlung-verarbeiten") as span:
span.set_attribute("payment.method", "stripe")
span.set_attribute("payment.amount_cents", 4999)
span.set_attribute("user.tier", "premium")
span.set_attribute("order.id", order_id)
ergebnis = stripe_client.charge(amount=4999, currency="eur")
span.set_attribute("payment.status", ergebnis.status)
span.set_attribute("payment.transaction_id", ergebnis.id)
if ergebnis.status != "succeeded":
span.set_status(trace.StatusCode.ERROR, ergebnis.error_message)
span.record_exception(ZahlungsFehler(ergebnis.error_message))Metriken
Metriken erfassen aggregierte numerische Messungen über Zeit. Im Gegensatz zu Traces — die individuelle Anfragen aufzeichnen — fassen Metriken das Verhalten vieler Anfragen in statistischen Aggregaten zusammen: Request-Raten, Fehlerquoten, Latenz-Perzentile, Queue-Tiefen und Ressourcenauslastung.
OpenTelemetry unterstützt vier Metrik-Instrument-Typen: Counter (monoton steigende Werte, wie verarbeitete Anfragen), Gauge (Point-in-Time-Messungen, wie aktueller Speicherverbrauch), Histogram (Verteilungen mit konfigurierbaren Bucket-Grenzen, wie Request-Latenz) und UpDown-Counter (Werte, die steigen oder fallen können, wie aktive Verbindungen). Alle vier Instrumente teilen dieselbe API in allen unterstützten Sprachen.
Metriken sind essenziell für Alerting und Kapazitätsplanung, weil sie billig zu speichern und bei Scale abzufragen sind. Ein Trace für jede Anfrage bei 100.000 RPS ist teuer; ein Histogramm der Request-Latenzen, das 100.000 Mal pro Sekunde aktualisiert wird, ist trivial. Die richtige Observability-Strategie verwendet Metriken für Alerting und Dashboards sowie Traces für Deep-Dive-Untersuchungen, sobald ein Alert auslöst.
from opentelemetry import metrics
meter = metrics.get_meter("order-service", "1.0.0")
# Counter: Gesamtzahl der Bestellungen seit Servicestart
bestellungen_zaehler = meter.create_counter(
name="bestellungen.verarbeitet",
unit="1",
description="Gesamtanzahl erfolgreich verarbeiteter Bestellungen",
)
# Histogram: Latenzverteilung der Verarbeitung
latenz_histogramm = meter.create_histogram(
name="bestellung.verarbeitungsdauer",
unit="ms",
description="Zeit für die vollständige Verarbeitung einer Bestellung",
)
# Verwendung: mit Attributen für dimensionale Aufteilung aufzeichnen
bestellungen_zaehler.add(1, {"region": "eu-west-1", "tier": "premium", "zahlungsmethode": "stripe"})
latenz_histogramm.record(142, {"region": "eu-west-1", "tier": "premium"})Logs
Logs sind die älteste Form von Telemetrie und diejenige, die die meisten Engineers bereits produzieren. OpenTelemetry's Ansatz zu Logs ist bewusst pragmatisch: Statt dich zu bitten, deine bestehende Logging-Library durch einen OTel-nativen Logger zu ersetzen, bietet es eine Logs Bridge API, die dein bestehendes Framework wrappet (Pythons logging-Modul, SLF4J in Java, Winston oder Pino in Node.js, Serilog in .NET) und OTel-Kontext — konkret die aktive trace_id und span_id — automatisch zu jedem Log-Record hinzufügt.
Das Ergebnis: Jede Log-Zeile, die deine Applikation ausgibt, ist automatisch mit der Anfrage korreliert, die sie produziert hat. In deinem Observability-Backend kannst du auf einen Trace-Span klicken und sofort alle Logs sehen, die während der Ausführung dieses Spans erzeugt wurden — ohne eine einzige Zeile Custom-Instrumentierung zu deinen Logging-Calls hinzuzufügen.
5. OpenTelemetry vs. Proprietäre Vendor-Agenten
Jeder große APM-Vendor — Datadog, New Relic, Dynatrace, AppDynamics — liefert einen proprietären Agenten. Diese Agenten können schnell einzurichten sein und bieten oft Auto-Instrumentation, die out-of-the-box gut funktioniert. Aber es gibt grundlegende Trade-offs, die mit zunehmender Größe der Organisation und reiferen Observability-Anforderungen immer bedeutsamer werden.
Der wichtigste Trade-off ist Portabilität. Ein proprietärer Agent baut vendor-spezifische Instrumentierungslogik in deine Applikation ein. Wenn du Backends wechselst — ob aufgrund von Preisen, Features oder organisatorischen Anforderungen — musst du typischerweise jeden Service von Grund auf neu instrumentieren. Für ein Unternehmen mit Dutzenden Services über mehrere Sprachen ist das ein Engineering-Projekt von mehreren Monaten.
| Kriterium | OpenTelemetry SDK | Proprietärer Agent |
|---|---|---|
| Vendor Lock-in | Keiner — Backend wechseln ohne Änderungen am Applikations-Code | Hoch — Instrumentierung ist an Vendor-Format gekoppelt |
| Auto-Instrumentation | 50+ Framework-Integrationen über alle Hauptsprachen | Oft breitere out-of-the-box Abdeckung bei etablierten Agenten |
| Datenportabilität | Voll — OTLP ist ein offener, publizierter Standard | Vendor-proprietäres Wire-Format, ETL für Migration erforderlich |
| Governance | CNCF Graduated Project, 1.000+ Contributors | Einzelner Vendor kontrolliert die Roadmap |
| Sprachunterstützung | 11 stabile SDKs; 15+ Sprachen in verschiedenen Stabilitätsstufen | Variiert stark je nach Vendor |
| Lizenzkosten | Kostenlos und Open Source (Apache 2.0) | Agent meist kostenlos; Backend-Kosten variieren |
| Semantic Conventions | Standardisierte Attributnamen über alle Signale und Backends | Proprietäres Schema; Cross-Vendor-Vergleich erfordert ETL |
| Custom-Instrumentierung | Stabile, idiomatische API je Sprache | Vendor-SDK-Calls; Breaking Changes möglich |
| Community-Ökosystem | Massiv; Hunderte von beigetragenen Receivers und Processors | Vendor-gesteuert, begrenzte Drittanbieter-Erweiterungen |
| Migrationspfad | Einmal instrumentieren; Backend durch Collector-Config wechseln | Vollständige Neu-Instrumentierung beim Vendor-Wechsel |
Der klarste Weg, diesen Trade-off zu denken: Proprietäre Agenten bieten etwas niedrigere initiale Setup-Kosten im Austausch für dauerhaft und stetig steigende Zukunftskosten in Form von Vendor-Abhängigkeit. OpenTelemetry kehrt das um — die initiale Einrichtung kann etwas länger dauern, aber die langfristigen Kosten sind dramatisch niedriger, weil du deine Instrumentierung dauerhaft besitzt.
6. Sprach- und SDK-Unterstützung
OpenTelemetry bietet offizielle SDKs für alle gängigen Programmiersprachen. Die Stabilität wird pro Signal (Traces, Metriken, Logs) verfolgt und variiert je Sprache. Die folgende Tabelle gibt den Stand von August 2026 wieder.
| Sprache | Traces | Metriken | Logs | Auto-Instrumentation |
|---|---|---|---|---|
| Java | GA | GA | GA | Javaagent — 150+ Frameworks inkl. Spring, Quarkus, Micronaut, JDBC |
| Python | GA | GA | GA | opentelemetry-distro — Django, Flask, FastAPI, SQLAlchemy, requests |
| JavaScript / Node.js | GA | GA | GA | @opentelemetry/auto-instrumentations-node — Express, Fastify, http, pg |
| Go | GA | GA | Beta | Begrenzt; eBPF-basierte Zero-Code-Instrumentation in Entwicklung |
| .NET / C# | GA | GA | GA | OpenTelemetry.AutoInstrumentation — ASP.NET Core, HttpClient, SqlClient |
| Ruby | GA | GA | Beta | opentelemetry-instrumentation-* Gems — Rack, Rails, Sinatra, Faraday |
| PHP | GA | Beta | Beta | Teilweise — Symfony, Laravel-Integrationen verfügbar |
| Rust | Beta | Beta | Beta | Nur manuelle Instrumentierung; keine Auto-Instrumentation |
| Swift / iOS | Beta | Beta | Beta | Teilweise — URLSession und einfaches HTTP abgedeckt |
| Erlang / Elixir | GA | Beta | Beta | Teilweise — Plug, Phoenix, Ecto-Integrationen verfügbar |
| C++ | Beta | Beta | Beta | Nur manuelle Instrumentierung |
Stand August 2026. Immer opentelemetry.io/docs/languages für den aktuellsten Stand prüfen.
Für die meisten Production-Workloads — Java, Python, Node.js, Go und .NET — gibt es vollständig stabile GA-Implementierungen über alle drei Signale. Auto-Instrumentation verdient besondere Erwähnung: Für Sprachen, die sie unterstützen (vor allem Java, Python, Node.js und .NET), erhältst du production-taugliche Distributed Traces, Metriken und Logs aus deiner Applikation ohne eine einzige Änderung am Applikations-Code.
7. Semantic Conventions: Warum konsistente Attributnamen entscheidend sind
Semantic Conventions sind einer der am meisten unterschätzten Teile von OpenTelemetry — und die häufigste Quelle von Problemen für Teams, die sie überspringen. Sie definieren ein standardisiertes Vokabular von Attributnamen, das alle OTel-instrumentierten Systeme für gängige Konzepte verwenden sollen: HTTP-Methoden, Datenbankabfragen, Messaging-Topics, Cloud-Provider-Details und mehr.
Das Problem, das Semantic Conventions lösen, ist Fragmentierung. Ohne Standard würde ein Team eine Datenbankabfrage als sql.query erfassen, ein anderes als db.query_text und ein drittes als query. Dein Observability-Backend kann diese nicht automatisch als dasselbe Konzept erkennen, also scheitern Cross-Service-Abfragen, automatische Dashboards brechen, und KI-gestützte Analysen liefern falsche Ergebnisse.
| Bereich | Wichtige Attribute | Beispielwerte |
|---|---|---|
| HTTP (Server) | http.request.method, url.path, http.response.status_code, http.route | GET, /api/orders/{id}, 200, /api/orders/:id |
| HTTP (Client) | http.request.method, url.full, http.response.status_code | POST, https://stripe.com/v1/charges, 201 |
| Datenbank | db.system, db.name, db.operation.name, db.query.text | postgresql, orders_db, SELECT, SELECT * FROM orders WHERE id=$1 |
| Messaging | messaging.system, messaging.destination.name, messaging.operation.type | kafka, payment-events, publish |
| AI / LLMs | gen_ai.system, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens | openai, gpt-4o, 1024, 312 |
| RPC / gRPC | rpc.system, rpc.service, rpc.method, rpc.grpc.status_code | grpc, PaymentService, Charge, 0 |
| Exceptions | exception.type, exception.message, exception.stacktrace | ValueError, Betrag muss positiv sein, ... |
| Cloud-Resource | cloud.provider, cloud.region, cloud.account.id | aws, eu-west-1, 123456789012 |
| Kubernetes | k8s.namespace.name, k8s.pod.name, k8s.deployment.name | payments, checkout-5d8b9-xk2p7, checkout |
| Service-Identität | service.name, service.version, deployment.environment | checkout-api, 2.1.4, production |
service.name, service.version und deployment.environment als Resource-Attribute auf jedem Service. Diese drei Attribute treiben automatische Service-Maps, versionsbasiertes Alerting und Environment-Filterung in deinem gesamten Observability-Backend.8. Der OpenTelemetry Collector
Der OpenTelemetry Collector ist eine eigenständige Binärdatei, die als vendor-agnostische Telemetrie-Pipeline fungiert. Er empfängt Daten von deinen Applikations-SDKs oder anderen Quellen, wendet konfigurierbares Processing an und exportiert die verarbeiteten Daten an ein oder mehrere Observability-Backends. Du kannst ihn als DaemonSet-Agent auf jedem Kubernetes-Node deployen, als zentrales Deployment für Tail-Based Sampling oder beides gleichzeitig.
Receivers
Telemetrie von beliebigen Quellen akzeptieren. OTLP (gRPC und HTTP), Prometheus Scrape, Fluent Bit, Jaeger, Zipkin, StatsD, CloudWatch und 100+ weitere. Ein einzelner Collector kann aus allen gleichzeitig ingestieren.
Processors
Daten im Flug transformieren, filtern und anreichern. Memory Limiting, Batch-Aggregation, Attribut-Manipulation, PII-Redaktion, Tail-Based Sampling, Schema-Transformation und Resource Detection.
Exporters
Verarbeitete Daten an Backends senden. OTLP zu obseria.io, Prometheus Remote Write, S3/GCS für Archivierung, BigQuery, Splunk, Jaeger und 60+ weitere. Mehrere Exporter können in einer Pipeline laufen.
Einer der wichtigsten Use Cases für den Collector ist Tail-Based Sampling. Head-Based Sampling — wo du entscheidest, einen Trace zu behalten oder zu verwerfen, in dem Moment, in dem der erste Span startet — bedeutet, dass du Sampling-Entscheidungen triffst, bevor du weißt, ob der Trace interessant ist. Ein 10%-Head-Based-Sample verwirft 90% deiner langsamen Anfragen, fehlgeschlagenen Transaktionen und ungewöhnlichen Traces. Tail-Based Sampling wartet, bis der vollständige Trace zusammengesetzt ist, dann trifft er die Behalten/Verwerfen-Entscheidung basierend auf dem vollständigen Bild.
# Production Collector Config: SDK → Collector → obseria.io
receivers:
otlp:
protocols:
grpc: { endpoint: "0.0.0.0:4317" }
http: { endpoint: "0.0.0.0:4318" }
processors:
memory_limiter:
check_interval: 1s
limit_mib: 1500
spike_limit_mib: 400
batch:
timeout: 5s
send_batch_size: 8000
send_batch_max_size: 10000
transform/bereinigen:
trace_statements:
- context: span
statements:
- delete_key(attributes, "user.id")
- delete_key(attributes, "http.request.header.authorization")
exporters:
otlp/obseria:
endpoint: ingest.obseria.io:4317
compression: gzip
headers:
Authorization: "Bearer ${env:OBSERIA_API_KEY}"
sending_queue:
enabled: true
queue_size: 5000
retry_on_failure:
enabled: true
initial_interval: 5s
max_elapsed_time: 300s
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, transform/bereinigen, batch]
exporters: [otlp/obseria]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/obseria]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/obseria]9. Schnellstart: Ersten Service in 5 Minuten instrumentieren
Der schnellste Weg zu Production-Traces ist Auto-Instrumentation. Du musst keinen einzigen Span manuell schreiben. Für Python, Node.js und Java bringen dich die folgenden Befehle in weniger als fünf Minuten von null zu live sendenden Traces.
Alle drei Beispiele verwenden OTEL_*-Umgebungsvariablen zur SDK-Konfiguration. Das bedeutet null Konfigurations-Code in deiner Applikation — setze die Variablen einfach in deiner Container-Spec, deiner systemd Unit oder deiner CI/CD-Pipeline.
# ── Python ──────────────────────────────────────────────────────
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap --action=install # installiert Framework-Integrationen
OTEL_SERVICE_NAME=mein-python-service \
OTEL_SERVICE_VERSION=1.0.0 \
OTEL_DEPLOYMENT_ENVIRONMENT=production \
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.obseria.io \
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <api-key>" \
opentelemetry-instrument python app.py
# Instrumentiert automatisch: Django, Flask, FastAPI, SQLAlchemy,
# psycopg2, redis, requests, httpx, celery, boto3.# ── Node.js ─────────────────────────────────────────────────────
npm install @opentelemetry/auto-instrumentations-node
OTEL_SERVICE_NAME=mein-node-service \
OTEL_SERVICE_VERSION=1.0.0 \
OTEL_DEPLOYMENT_ENVIRONMENT=production \
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.obseria.io \
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <api-key>" \
node --require @opentelemetry/auto-instrumentations-node/register app.js
# Instrumentiert automatisch: Express, Fastify, Koa, http/https,
# pg, mysql2, ioredis, mongodb, grpc, aws-sdk.# ── Java ────────────────────────────────────────────────────────
curl -Lo opentelemetry-javaagent.jar \
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
java -javaagent:opentelemetry-javaagent.jar \
-DOTEL_SERVICE_NAME=mein-java-service \
-DOTEL_SERVICE_VERSION=1.0.0 \
-DOTEL_DEPLOYMENT_ENVIRONMENT=production \
-DOTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.obseria.io \
-DOTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <api-key>" \
-jar my-app.jar
# Instrumentiert automatisch: Spring Boot, Quarkus, Micronaut,
# Vert.x, Jetty, JDBC, Hibernate, Kafka, RabbitMQ, gRPC.10. Best Practices und häufige Fehler
Nach der Arbeit mit Hunderten von Teams, die ihre Systeme mit OpenTelemetry instrumentieren, haben wir dieselben Fehler immer wieder beobachtet. Die folgende Tabelle dokumentiert die häufigsten und die empfohlene Lösung.
| Häufiger Fehler | Warum es wichtig ist | Richtiger Ansatz |
|---|---|---|
| service.name nicht gesetzt | Traces und Metriken sind nicht zugeordnet — keine Service-Maps, kein per-Service-Alerting | OTEL_SERVICE_NAME auf jedem Prozess, Container und Lambda-Function setzen |
| Nur Traces, keine Metriken oder Logs | Kein Alerting auf Fehlerraten oder Latenzen ohne Metriken; Logs liefern fehlenden Kontext für einzelne Fehler | Alle drei Signale von Anfang an instrumentieren |
| Eigene Attributnamen statt Semantic Conventions | Backend-Auto-Features (Service-Maps, DB-Dashboards, KI-Analyse) erfordern Standard-Attributnamen | OTel Semantic Conventions für alle Standard-Konzepte befolgen |
| 10% Head-Based Sampling in Production | Du verlierst 90% der Fehler-Traces und Slow-Request-Traces — genau die Daten, die du am meisten brauchst | Tail-Based Sampling über den Collector; Fehler-Traces immer behalten |
| Kein Collector in Production | Direkter SDK-Export zum Backend: kein Retry bei Backend-Ausfall, kein Tail Sampling, kein Fan-out | Collector als DaemonSet betreiben; Retry-Queues und Tail Sampling konfigurieren |
| High-Cardinality-Attribute auf Metriken | user_id oder request_id als Metrik-Label erzeugt Millionen von Zeitreihen und lässt die Kosten explodieren | Metrik-Labels niedrig-kardinal halten; hochkardiale Daten auf Trace-Spans |
| Fehlende Cloud- und K8s-Resource-Attribute | Dashboards und Alerts können nicht nach Cloud-Provider, Region, Namespace oder Pod gefiltert werden | Resource-Detektoren (cloud, k8s_node) in SDK- oder Collector-Config aktivieren |
| Context Propagation in asynchronen Workern vergessen | Hintergrundjobs und Queue-Consumer erscheinen als getrennte Traces statt als Kinder der auslösenden Anfrage | W3C TraceContext-Header in jeden Queue-Message-Envelope injizieren und extrahieren |
service.name, service.version oder deployment.environment fehlen. Siehe die Getting-Started-Dokumentation für die vollständige Checkliste.11. Häufig gestellte Fragen
Brauche ich den Collector, oder kann ich direkt vom SDK exportieren?
Direkter Export vom SDK zum Backend funktioniert gut für Development und für Production-Services bei niedrigem bis mittlerem Scale. Füge den Collector hinzu, wenn du Tail-Based Sampling benötigst (erfordert einen Collector, weil er den vollständigen Trace sehen muss, bevor er die Sampling-Entscheidung trifft), wenn du Daten gleichzeitig an mehrere Backends senden möchtest, wenn du Transformationen oder PII-Redaktion vor dem Export anwenden musst, oder wenn du Retry und Queue-Buffering benötigst, um Backend-Ausfälle ohne Datenverlust zu überbrücken.
Ist OpenTelemetry reif genug für den Production-Einsatz?
Ja. OpenTelemetry ist ein CNCF Graduated Project — der höchste Reifegrad. Traces, Metriken und Logs sind in den Java-, Python-, Node.js-, Go- und .NET-SDKs alle GA (generally available). Fortune-500-Unternehmen, große Cloud-Provider und Tausende von Engineering-Organisationen betreiben OTel in Production bei Scale. obseria.io's gesamter Ingest- und Processing-Layer ist nativ auf OTLP aufgebaut.
Ersetzt OpenTelemetry Prometheus?
Nicht zwangsläufig — sie sind komplementär. OTel kann bestehende Prometheus-/metrics-Endpunkte über den Prometheus-Receiver im Collector scrapen und über den prometheusremotewrite-Exporter an Prometheus-kompatible Backends exportieren. Die meisten Organisationen betreiben beides: OTel für Applikations-level-Traces, Metriken und Logs (besonders für neue Services) und Prometheus für bestehende Infrastruktur-Metriken, wo das Scrape-basierte Modell gut etabliert ist.
Wie hoch ist der Performance-Overhead von OpenTelemetry?
Mit der Standard-BatchSpanProcessor-Konfiguration liegt der Overhead typischerweise unter 1% zusätzlicher CPU-Nutzung und unter 50 MB zusätzlichem Speicher pro Service-Instanz. Auto-Instrumentation fügt 5–30 ms zur Startup-Zeit hinzu (der JVM-Javaagent liegt am oberen Ende wegen Bytecode-Manipulation). Es gibt keinen messbaren Einfluss auf die per-Request-Latenz in Production-Workloads — das SDK verarbeitet Spans asynchron in einem Hintergrund-Thread.
Wie gehe ich mit personenbezogenen Daten (PII) in Spans und Logs um?
Es gibt zwei Schutzschichten. Erstens: Verwende den Transform-Processor des Collectors, um sensible Attribute zu löschen oder zu hashen, bevor sie deine Infrastruktur verlassen — das ist der robusteste Ansatz, weil die Daten nie ein externes System erreichen. Zweitens: obseria.io bietet einen Sensitive Data Scanner auf der Ingest-Schicht, der PII-Muster (E-Mail-Adressen, Kreditkartennummern, nationale IDs usw.) in Echtzeit erkennt und maskiert — als Sicherheitsnetz für Daten, die die Collector-Verarbeitungsstufe passieren.
Kann ich OpenTelemetry mit einer monolithischen Applikation verwenden?
Absolut. Distributed Tracing ist am bekanntesten für Microservices, aber es ist gleichermaßen wertvoll in Monolithen. Ein Trace innerhalb eines Monolithen zeigt dir den vollständigen internen Call-Baum: welcher Controller die Anfrage verarbeitet hat, welche Service-Layer-Methoden aufgerufen wurden, wie viele Datenbankabfragen ausgeführt wurden und wie lange jede dauerte, und wo im Code die Latenz entstand. Das ist weit aktionsfähiger als das manuelle Durchlesen von Log-Dateien.
Wie instrumentiere ich einen Kafka-Consumer oder einen Hintergrund-Worker?
Für Kafka-Consumer und andere nachrichtengesteuerte Worker musst du Trace-Kontext durch den Message-Payload oder die Header propagieren. Die OTel-Instrumentierungsbibliotheken für Java, Python und Node.js handhaben Kafka-Context-Propagation automatisch, wenn du die offiziell unterstützten Kafka-Client-Libraries verwendest. Für eigene Queue-Implementierungen: Extrahiere den W3C-TraceContext-Header aus dem Message-Envelope und verwende ihn als Eltern-Kontext beim Start des Root-Spans des Consumers.
Was ist der Unterschied zwischen OpenTelemetry und OpenTracing?
OpenTracing war eine Vorgänger-Tracing-API-Spezifikation, die jetzt archiviert ist. OpenTelemetry ersetzt und übertrifft OpenTracing vollständig. Das OTel-Projekt liefert OpenTracing-Shims in den meisten Sprachen, die OpenTracing-API-Calls in OTel-API-Calls übersetzen, sodass bestehender Code, der mit OpenTracing instrumentiert wurde, weiter funktioniert, während du in eigenem Tempo zur nativen OTel-Instrumentierung migrierst. Alle neuen Instrumentierungen sollten direkt die OTel-API verwenden.
Marco Bietti
Platform Engineer · obseria.io
Marco betreibt obseria.io's Collector-Fleet und Ingest-Infrastruktur. Er ist Contributor am OpenTelemetry Collector und pflegt mehrere Community-Receiver-Plugins.
Weitere Artikel
