Logo GH

Distributed Tracing: OpenTelemetry

Distributed Tracing: OpenTelemetry

1) Warum OTel und was es gibt

OpenTelemetry (OTel) ist ein offener Standard und eine Reihe von SDKs/Agenten/Kollektoren für Telemetrie (Traces, Metriken, Protokolle) mit einem einzigen OTLP-Protokoll. Die Ziele sind:
  • Durchgehende Sichtbarkeit der Anforderungspfade (Gateway → Dienste → DB/Cache/Queue).
  • Schnelle RCA/Debugging von Degradationen und Releases (Kanarienvögel/blau-grün).
  • Verknüpfung mit SLOs und Auto-Rollbacks (operative Entscheidungen auf Daten).
  • Vendor-Agnostizität: Export in ein beliebiges Backend, ohne Bindung an ein einziges APM.

Grundlagen: Standardize, sample smart, secure by default, correlate everything.

2) Grundlagen: Kontext, Spans, Attribute

Trace - Baum/Graph der Aufrufe; Span - Operation (RPC, SQL, Warteschlangenaufruf).
Span Kind: `SERVER`, `CLIENT`, `PRODUCER`, `CONSUMER`, `INTERNAL`.
W3C Trace Context: Überschriften „traceparent“, „tracestate“; Der Kontext wird dienstübergreifend übertragen.
Attribute - Schlüsselwert (niedrige Kardinalität!), Ereignisse - Markierungen in der Zeit, Status - Fehlercode/Beschreibung.
Links - Kommunikation von Spans außerhalb einer strengen Hierarchie (wichtig für async/fan-out/fan-in).

Benennung der Spans:
  • HTTP: 'HTTP {METHOD}' ('GET/withdraw' als Attribut)
  • DB: `DB SELECT` / `DB INSERT`
  • Queue: `QUEUE publish topic=X` / `QUEUE consume topic=X`

3) Semantische Konventionen (semconv)

Verwenden Sie stabile Attributschemata:
  • HTTP/GRPC: `http. method`, `http. route`, `http. status_code`, `url. full`.
  • DB: `db. system=postgresql`, `db. statement'(nur sicherer Trester!), 'db. name`.
  • Messaging: `messaging. system=kafka`, `messaging. operation=receive`, `messaging. destination`.
  • Cloud/K8s/Host: `cloud. region`, `k8s. pod. name`, `container. id`.
  • Ressourcenattribute (erforderlich): 'service. name`, `service. version`, `deployment. environment`.

Geben Sie die Stabilität des Schemas über 'schemaUrl' in den SDK/Collector-Ressourcen an.

4) Sampling: Kopf, Schwanz, adaptiv

Kopfbasiert (im SDK): entscheidet im Voraus, günstig; gut für High-QPS, kann aber „interessante“ Strecken verpassen.
Tail-based (in Collector): entscheidet nach Abschluss der Route; erlaubt Regeln nach Status, Latenz, Attributen.
Adaptiv/Dynamisch: Erhöht den Sample-Anteil bei p95-Fehlern/Wachstum.

Prod-Level-Rezept: Kopf 1-5% global + Tail-Selektion „wichtig“: 'status = ERROR', 'latency> p95', „monetäre Routen“, PSP/KYC-Fehler.

5) Korrelation: Metriken, Protokolle, Traces

Beispiele: Markierungen mit 'trace _ id' in den Histogrammen der Metriken (schneller Sprung zur Spur).
Logs: Fügen Sie' trace _ id '/' span _ id 'hinzu und wechseln Sie von logs zu trace.
SpanMetrics (Prozessor): Aggregiert aus den Spuren der RED-Metriken ('requests, errors, duration') für SLO/alert.

6) Bereitstellungsarchitektur

Der Agent (DaemonSet) auf jedem Knoten sammelt von Anwendungen (OTLP) und vorwärts.
Gateway (Cluster/Region) - Zentraler Collector (viele Replikate) mit Pipelines für Routing/Sampling/Anreicherung.
OTLP: gRPC `4317`, HTTP `4318`; Aktivieren Sie TLS/mTLS.

Vorteile von „Agent + Gateway“: Isolation, Pufferung, lokale Backpressure, vereinfachtes Netzwerk.

7) OpenTelemetry Collector - Grundmuster (Gateway)

yaml receivers:
otlp:
protocols:
grpc: { endpoint: 0. 0. 0. 0:4317 }
http: { endpoint: 0. 0. 0. 0:4318 }

processors:
memory_limiter: { check_interval: 5s, limit_percentage: 75 }
batch: { timeout: 2s, send_batch_size: 8192 }
attributes:
actions:
- key: deployment. environment action: upsert value: prod resource:
attributes:
- key: service. namespace action: upsert value: core tail_sampling:
decision_wait: 5s policies:
- name: errors type: status_code status_code: { status_codes: [ERROR] }
- name: slow_traces type: latency latency: { threshold_ms: 800 }
- name: important_routes type: string_attribute string_attribute:
key: http. route values: ["/withdraw", "/deposit"]
- name: baseline_prob type: probabilistic probabilistic: { sampling_percentage: 5 }

exporters:
otlp/apm:
endpoint: apm-backend:4317 tls: { insecure: true }
prometheus:
endpoint: 0. 0. 0. 0:9464

extensions:
health_check: {}
pprof: { endpoint: 0. 0. 0. 0:1777 }
zpages: { endpoint: 0. 0. 0. 0:55679 }

service:
extensions: [health_check, pprof, zpages]
pipelines:
traces:  { receivers: [otlp], processors: [memory_limiter,attributes,resource,batch,tail_sampling], exporters: [otlp/apm] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }
logs:   { receivers: [otlp], processors: [batch], exporters: [] }

8) SpanMetrics und RED für SLO

Fügen Sie einen Prozessor hinzu:
yaml processors:
spanmetrics:
metrics_exporter: prometheus histogram:
explicit:
buckets: [50ms,100ms,200ms,400ms,800ms,1600ms,3200ms]
service:
pipelines:
traces: { receivers: [otlp], processors: [spanmetrics,batch,tail_sampling], exporters: [otlp/apm] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }

Jetzt gibt es' traces _ spanmetrics _ calls {service, route, code} 'und' duration _ bucket 'für SLO/alert.

9) K8s: Collector Deployment (DaemonSet + Deployment)

Agent (DaemonSet) Fragment:
yaml apiVersion: apps/v1 kind: DaemonSet metadata: { name: otel-agent, namespace: observability }
spec:
template:
spec:
containers:
- name: otelcol image: otel/opentelemetry-collector:latest args: ["--config=/conf/agent. yaml"]
ports:
- { containerPort: 4317, name: otlp-grpc }
- { containerPort: 4318, name: otlp-http }

Gateway (Deployment) - mehrere Replikate, Service ClusterIP/Ingress, HPA über CPU/QPS.

10) Sicherheit und Privatsphäre

TLS/mTLS между SDK → Agent → Gateway → Backend.
Authentifizierung (Basic/OAuth/Headers) am Gateway-Eingang; Begrenzen Sie die Ursprünge.
PII Revision: Attribute filtern/maskieren ('user. E-Mail', 'card.') im Collector-Prozessor.
Limits: Begrenzen Sie im SDK die Größe des Events/die Anzahl der Attribute (Kardinalitätsschutz).
RBAC im Backend + ausgewählte Neymspaces von Projekten/Tenanten.

Beispiel für einen Filter in Collector:
yaml processors:
attributes/redact:
actions:
- key: user. email action: delete
- key: payment. card action: delete

11) Instrumentierung: Schnelle Starts

Node. js

js import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes as R } from "@opentelemetry/semantic-conventions";

const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({ url: "http://otel-agent. observability:4317" }),
resource: new Resource({
[R.SERVICE_NAME]: "payments-api",
[R.SERVICE_VERSION]: "1. 14. 2",
[R.DEPLOYMENT_ENVIRONMENT]: "prod"
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk. start();

Java (Spring)

java
// Gradle: io. opentelemetry. instrumentation:opentelemetry-spring-boot-starter
// application. yml otel:
service:
name: orders-api exporter:
otlp:
endpoint: http://otel-agent. observability:4317 traces:
sampler: parentbased_traceidratio sampler-arg: 0. 05

Python (FastAPI)

python from opentelemetry import trace from opentelemetry. sdk. resources import Resource from opentelemetry. exporter. otlp. proto. grpc. trace_exporter import OTLPSpanExporter from opentelemetry. sdk. trace import TracerProvider from opentelemetry. sdk. trace. export import BatchSpanProcessor

provider = TracerProvider(resource=Resource. create({"service. name":"fraud-scoring","deployment. environment":"prod"}))
provider. add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel-agent. observability:4317", insecure=True)))
trace. set_tracer_provider(provider)

Go

go exp, _:= otlptracegrpc. New(ctx, otlptracegrpc. WithEndpoint("otel-agent. observability:4317"), otlptracegrpc. WithInsecure())
res:= resource. NewWithAttributes(semconv. SchemaURL, semconv. ServiceNameKey. String("gateway"), semconv. DeploymentEnvironmentKey. String("prod"))
tp:= sdktrace. NewTracerProvider(sdktrace. WithBatcher(exp), sdktrace. WithResource(res), sdktrace. WithSampler(sdktrace. ParentBased(sdktrace. TraceIDRatioBased(0. 05))))
otel. SetTracerProvider(tp)

12) Asynchron: Warteschlangen, Busse, Cron

PRODUCER/CONSUMER mit Kommunikation über 'links' (Nachrichten haben ihren eigenen Lebenszyklus).
Propagieren Sie den Kontext in Nachrichtenüberschriften ('traceparent '/' baggage').
Erstellen Sie beim Batch-Consume per Span pro Nachricht oder aggregieren Sie mit dem Attribut 'messaging. batch. size`.
Für Cron/Jobs: Neue Starttrace + Links zu primären Ereignissen (falls vorhanden).

13) Baggage und Targeting

Speichern Sie ein Minimum an stabilen Schlüsseln ('tenant _ id', 'region', 'vip _ tier') in baggage; PII verbieten.
Durchsuche den Gateway/Gateway-Logger, um die Metriken anschließend nach Segmenten zu aggregieren.

14) Integration mit Releases und SLO-Gating

Kanarische Schritte → Überprüfen Sie' traces _ spanmetrics _ 'entlang der Routen/yuz-Segmente.
Bei Degradation (5xx/p95) - Auto-Stop und Rollback (Argo Rollouts AnalysisTemplate + PromQL).
Instanzen aus Metriken führen direkt in die „schlechten“ Spuren des Release-Intervalls.

15) Grenzen und Leistung

Ограничивайте: `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`, `OTEL_SPAN_EVENT_COUNT_LIMIT`, `OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT`.
Sample Ausnahmen/Stacktrace nach Wahrscheinlichkeit/Häufigkeit.
Batch-Prozessor im SDK und Sammler; Halten Sie die Warteschlangen, um die Spuren nicht zu verlieren, wenn Sie platzen.

16) Kompatibilität und Migration

Propagandisten: W3C verwenden; Unterstützung beim Lesen von B3/X-Ray während der Migration (Dual-Propagation).
Export: OTLP → APM (Jaeger/Tempo/Elastic/X-Ray usw.).
Stabile Versionen von semconv - fix' schemaUrl 'und planen Upgrades.

17) Anti-Muster

Hohe Kardinalität der Attribute ('user _ id' im Label, dynamische Schlüssel).
Logs ohne' trace _ id '→ keine Korrelation.
Export direkt aus Anwendungen ins Internet APM (kein Gateway, kein TLS/mTLS).
Die Sammlung von „nur“ 100% in der Produktion ist teuer und sinnlos.
Dumps von SQL-Abfragen mit Benutzerdaten in 'db. statement`.
Inkonsistenter Service-/Versionsname - Metriken „bröckeln“.

18) Checkliste Umsetzung (0-45 Tage)

0-10 Tage

Aktivieren Sie SDK/Auto-Tools für 2-3 kritische Dienste.
Konfigurieren Sie Agent (DaemonSet) + Gateway (Deployment), OTLP 4317/4318 mit TLS.
Hinzufügen 'service. name`, `service. version`, `deployment. Umwelt ist überall.

11-25 Tage

Tail-Sampling auf Fehler/Latenz/“ Geld“ Routen.
SpanMetrics → Prometheus, einschließlich Exemplar- und RED/SLO-Dashboards.
Propagieren Sie W3C über das API-Gateway/NGINX/mesh; Protokolle korrelieren.

26-45 Tage

Warteschlangen/DB/Cache abdecken; Links für async.
PII-Revisionsrichtlinien in Collector; Attributgrenzen im SDK.
Integrieren SLO-Gatting Releases und Auto-Rollback.

19) Reifegradkennzahlen

Die Abdeckung eingehender Anfragen durch Tracing ≥ 95% (einschließlich Sampling Head/Tail).
Der Anteil der Metriken mit Beispiels ≥ 80%.
Die RCA-Zeit „von der Metrik zur Strecke“ ≤ 2 Minuten (p50).
0 PII Lecks in Attributen/Ereignissen (Scanner).
Alle Dienste haben 'Service. name/version/environment 'und konsistente Semantik.

20) Anwendungen: nützliche Fragmente

NGINX-Propaganda:
nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;
proxy_set_header baggage   $http_baggage;
Prometheus с Exemplars (Grafana):

histogram_quantile(0. 95, sum(rate(traces_spanmetrics_duration_bucket{route="/withdraw"}[5m])) by (le))

Richtlinie: Verbot von PII-Attributen (Pseudo-Linter)

yaml forbid_attributes:
- user. email
- payment. card
- personal.

21) Schlussfolgerung

OpenTelemetry verwandelt die Beobachtbarkeit in eine standardisierte, überschaubare Kontur: einheitliche Semantik, sichere Propagierung, intelligentes Sampling und starke Korrelation mit Metriken und Protokollen. Bauen Sie Agent + Gateway auf, fügen Sie Tail-Sampling, Spanmetrics und Exemplare hinzu, behalten Sie PII und Kardinalität im Auge - und Tracing wird nicht nur zu einem Werkzeug für Debugging, sondern auch für automatisierte SRE/Release-Lösungen, wodurch MTTR und Risiken bei jeder Veröffentlichung reduziert werden.

Contact

Kontakt aufnehmen

Kontaktieren Sie uns bei Fragen oder Support.Wir helfen Ihnen jederzeit gerne!

Integration starten

Email ist erforderlich. Telegram oder WhatsApp – optional.

Ihr Name optional
Email optional
Betreff optional
Nachricht optional
Telegram optional
@
Wenn Sie Telegram angeben – antworten wir zusätzlich dort.
WhatsApp optional
Format: +Ländercode und Nummer (z. B. +49XXXXXXXXX).

Mit dem Klicken des Buttons stimmen Sie der Datenverarbeitung zu.