Fehler bei Collector und SDKs beheben
Eine systematische Checkliste für den Fall, dass Telemetrie nicht ankommt: Debug-Exporter, Health Checks, interne Metriken und häufige Fehler.
„Ich sehe meine Daten nicht“ ist das häufigste OpenTelemetry-Problem, und die Ursache ist fast immer einer von wenigen Konfigurationsfehlern. Arbeite von der Anwendung nach außen, einen Hop nach dem anderen, und belege jeden Hop, bevor du zum nächsten weitergehst.
App-SDK ──▶ Collector-Receiver ──▶ Prozessoren ──▶ Exporter ──▶ Backend
1 2 3 4 5
Schritt 0: die Konfiguration validieren
otelcol-contrib validate --config=config.yaml
Das fängt YAML-Fehler, unbekannte Komponentennamen, falsche Optionsnamen und Pipelines ab, die nicht definierte Komponenten referenzieren. Nutze den Binary-Namen, der zu deiner Distribution passt (otelcol, otelcol-contrib, otelcol-k8s). In einem Container führe es mit demselben Image und der gemounteten Konfiguration wie dein Deployment aus.
Schritt 1: sendet das SDK?
Aktiviere SDK-Diagnose und einen Console-Exporter, um „die App hat nichts erzeugt“ von „die App hat es erzeugt, aber es kam nicht an“ zu trennen:
export OTEL_LOG_LEVEL=debug
export OTEL_TRACES_EXPORTER=console # oder "logging", je nach Sprache
Prüfe die üblichen Ursachen:
- Endpunkt und Protokoll passen nicht.
OTEL_EXPORTER_OTLP_PROTOCOLmuss zum Port passen:grpcgeht an 4317,http/protobufgeht an 4318. HTTP an den gRPC-Port zu senden oder umgekehrt schlägt mit Fehlern fehl, die wie Verbindungs- oder Parsing-Probleme aussehen. - Falscher Pfad bei HTTP.
OTEL_EXPORTER_OTLP_ENDPOINTist eine Basis-URL; das SDK fügt/v1/traceshinzu. Signalspezifische Variablen wieOTEL_EXPORTER_OTLP_TRACES_ENDPOINTwerden so verwendet, wie sie sind, müssen also den vollständigen Pfad enthalten. localhostinnerhalb eines Containers. Daslocalhostder App ist die App selbst. Nutze den Service- oder Container-Namen des Collectors.- Das SDK ist deaktiviert oder der Exporter ist
none. Suche nachOTEL_SDK_DISABLED=trueoderOTEL_TRACES_EXPORTER=none. - Kein
service.name. Daten werden akzeptiert, erscheinen aber alsunknown_service, was wie fehlende Daten aussieht. SetzeOTEL_SERVICE_NAME. - Kurzlebige Prozesse beenden sich vor dem Export. Batch-Exporter senden periodisch, rufe also vor dem Beenden das Shutdown oder Flush des SDKs auf.
Schritt 2: ist der Receiver erreichbar?
curl -i http://collector:4318/v1/traces \
-H 'Content-Type: application/json' -d '{}'
Eine HTTP-200-Antwort (ein leerer JSON-Body ist in Ordnung) zeigt, dass der HTTP-Receiver erreichbar ist. Für gRPC beweist ein Werkzeug wie grpcurl oder ein TCP-Check (nc -zv collector 4317), dass der Port offen ist. Wenn nicht:
- Der Receiver ist womöglich an
localhostgebunden. Setzeendpoint: 0.0.0.0:4317explizit. - Der Kubernetes-Service stellt den Port womöglich nicht bereit, oder der
containerPortdes Pods fehlt. - Eine NetworkPolicy, Firewall oder ein Service Mesh blockiert womöglich den Traffic.
Schritt 3: ist die Pipeline verdrahtet?
Das ist der häufigste Collector-Fehler: eine definierte, aber nicht genutzte Komponente. exporters.otlp/tempo zu definieren bewirkt nichts, bis es in service.pipelines.<signal>.exporters auftaucht. Dasselbe gilt für Receiver, Prozessoren, Extensions und Connectors.
Prüfe:
- Der Name der Komponente in der Pipeline entspricht exakt ihrer Definition, einschließlich eines Suffixes (
otlp/tempo, nichtotlp). - Der Signaltyp passt: Eine
traces-Pipeline kann keinen Receiver oder Exporter nutzen, der keine Traces unterstützt. - Die Extension ist unter
service.extensionsaufgeführt. - Denke bei Helm-Values daran, dass Listen ersetzen, eine teilweise neu definierte Pipeline kann also die Standardkomponenten verloren haben.
Schritt 4: die Daten im Collector sehen
Füge den debug-Exporter zur Pipeline hinzu:
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [debug, otlp/tempo]
Lies die Logs des Collectors. Siehst du dort Spans, ist bewiesen, dass Receiver und Prozessoren funktionieren, das Problem liegt also weiter unten. Siehst du nichts, erreichten die Daten die Pipeline nie oder ein Prozessor hat sie verworfen (ein filter-Prozessor oder der Tail Sampler ist der übliche Verdächtige). Entferne debug oder senke seine Ausführlichkeit, wenn du fertig bist, da er jeden Eintrag loggt.
Schritt 5: die eigenen Signale des Collectors nutzen
Health Check:
extensions:
health_check:
endpoint: 0.0.0.0:13133
service:
extensions: [health_check]
curl http://collector:13133/ gibt einen Status zurück. Nutze es für Kubernetes-Liveness- und Readiness-Probes.
Interne Metriken werden standardmäßig auf Port 8888 bereitgestellt (prüfe service.telemetry.metrics für deine Version):
curl -s http://collector:8888/metrics | grep -E 'otelcol_(receiver|processor|exporter)_'
Lies sie als Trichter:
| Metrikfamilie | Bedeutung |
|---|---|
otelcol_receiver_accepted_* | Erfolgreich empfangene Einträge |
otelcol_receiver_refused_* | Abgelehnt, oft durch memory_limiter |
otelcol_processor_dropped_* | Von einem Prozessor verworfen |
otelcol_exporter_sent_* | An das Backend geliefert |
otelcol_exporter_send_failed_* | Vom Backend abgelehnt oder nicht erreichbar |
otelcol_exporter_queue_size und _capacity | Queue-Tiefe gegen ihr Limit |
Steigende Accepted-Zahlen bei gleichbleibenden Sent-Zahlen sagen dir, dass das Problem am Exporter liegt. Steigende Refused-Zahlen deuten auf Speicherlimits. Metriknamen wurden zwischen Releases angepasst, prüfe also die Dokumentation zur internen Telemetrie des Collectors für deins.
zPages geben eine Live-Sicht auf Pipelines und aktuelle Traces:
extensions:
zpages:
endpoint: localhost:55679
Rufe /debug/tracez und /debug/pipelinez auf (über kubectl port-forward in einem Cluster). Halte es an localhost gebunden.
Schritt 6: nimmt das Backend es an?
Sieh dir Exporter-Fehler in den Collector-Logs an:
connection refusedoderdeadline exceeded: falscher Endpunkt, Port oder eine Netzwerksperre.certificate signed by unknown authority: fügetls.ca_filehinzu oder korrigiere den Endpunkt auf den richtigen Hostnamen.401oder403: Das Token oder der Header fehlt oder ist falsch. Bestätige, dass die Umgebungsvariable im Pod gesetzt ist (kubectl exec ... -- env), da ein nicht gesetztes${env:VAR}zu einem leeren Wert wird.415oder Parsing-Fehler: Protokollabweichung, etwaotlp(gRPC) auf einen HTTP-Port gerichtet.404bei HTTP: Prüfe den Basispfad, den das Backend erwartet (Loki nutzt/otlp, Prometheus/api/v1/otlp).- Prometheus lehnt OTLP ab: Sein Feature-Flag für den OTLP-Receiver ist nicht aktiviert.
Prüfungen bei Auto-Instrumentierung
Bei Operator-basierter Injection bestätige, dass die Instrumentation vor dem Start des Pods existierte, dass die Annotation auf dem Pod-Template steht und dass der Anwendungs-Pod den Init-Container opentelemetry-auto-instrumentation hat. Starte den Workload nach dem Erstellen oder Ändern der Ressource neu. Bei Agent-basierten Setups bestätige, dass das Agent-Flag oder die Umgebungsvariable tatsächlich angewendet wird (-javaagent:, opentelemetry-instrument, --require).
Kurzreferenz
| Symptom | Zuerst prüfen |
|---|---|
| Nichts in den Collector-Logs | SDK-Endpunkt, Protokoll, Port; localhost in Containern |
| Collector empfängt Daten, Backend nicht | Exporter in der Pipeline; Endpunkt; Authentifizierung; Protokoll |
| Collector startet nicht | Ausgabe von validate; Komponente fehlt im Image |
Daten erscheinen als unknown_service | OTEL_SERVICE_NAME setzen |
| Speicherwachstum oder Neustarts | memory_limiter zuerst, Queue-Größen, Ressourcenlimits |
| Unvollständige Traces nach Sampling | Ein Trace muss einen Collector erreichen (Load-Balancing-Stufe) |
| Manche Daten fehlen sporadisch | Queue voll oder Retry-Limit erreicht; prüfe send_failed und Queue-Metriken |
Behebe einen Hop nach dem anderen, halte den debug-Exporter bei der Arbeit griffbereit und lege die internen Metriken des Collectors auf ein Dashboard, damit der nächste Vorfall mit Belegen beginnt.
Beliebte Anleitungen
-
OpenTelemetry erklärt: SDKs, OTLP und der Collector Verstehe die beweglichen Teile und die drei Orte, an denen Konfiguration lebt, bevor du irgendein YAML schreibst. -
Das Konfigurationsmodell des Collectors: Komponenten, Pipelines und Provider Lerne die Regeln des Collector-YAML: Benennung, Pipelines, Connectors, Zusammenführen von Dateien und Umgebungsvariablen. -
SDKs mit OTEL_*-Umgebungsvariablen konfigurieren Setze Service-Namen, Exporter, Sampling und Limits für jede Sprache mit Standardvariablen. -
Apps ohne Code-Änderungen instrumentieren: Java, Python und Node.js Hänge OpenTelemetry-Agents allein mit Umgebungsvariablen und Kommandozeilen-Flags an. -
Den Collector produktionsreif machen: Speicherlimits, Batching und Retries Konfiguriere Prozessoren, Queues und persistenten Speicher, damit Telemetrie Überlast und Ausfälle übersteht. -
Den Collector auf Kubernetes mit Helm deployen Installiere das offizielle Chart, nutze Presets für Logs und Metriken und überschreibe die Konfiguration über Values-Dateien.