OpenTelemetry OpenTelemetry

Dépanner le Collector et les SDK

Une checklist systématique pour quand la télémétrie n'arrive pas : exporter debug, health checks, métriques internes et erreurs courantes.

12 min Intermédiaire

« Je ne vois pas mes données » est le problème OpenTelemetry le plus courant, et la cause est presque toujours l’une d’une courte liste d’erreurs de configuration. Travaillez de l’application vers l’extérieur, un saut à la fois, et prouvez chaque saut avant de passer au suivant.

SDK de l'app ──▶ receiver du Collector ──▶ processors ──▶ exporter ──▶ Backend
     1                    2                     3             4           5

Étape 0 : valider la configuration

otelcol-contrib validate --config=config.yaml

Cela détecte les erreurs YAML, les noms de composants inconnus, les noms d’options incorrects et les pipelines qui référencent des composants non définis. Utilisez le nom de binaire qui correspond à votre distribution (otelcol, otelcol-contrib, otelcol-k8s). Dans un conteneur, exécutez-le avec la même image et la même configuration montée que votre déploiement.

Étape 1 : le SDK envoie-t-il ?

Activez les diagnostics du SDK et un exporter console pour distinguer « l’application n’a rien produit » de « l’application l’a produit mais cela n’est pas arrivé » :

export OTEL_LOG_LEVEL=debug
export OTEL_TRACES_EXPORTER=console   # ou "logging", selon le langage

Vérifiez les causes habituelles :

  • L’endpoint et le protocole ne correspondent pas. OTEL_EXPORTER_OTLP_PROTOCOL doit correspondre au port : grpc va vers 4317, http/protobuf va vers 4318. Envoyer du HTTP vers le port gRPC, ou l’inverse, échoue avec des erreurs qui ressemblent à des problèmes de connexion ou d’analyse.
  • Mauvais chemin avec HTTP. OTEL_EXPORTER_OTLP_ENDPOINT est une URL de base ; le SDK ajoute /v1/traces. Les variables propres à un signal, comme OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, sont utilisées telles quelles et doivent donc inclure le chemin complet.
  • localhost à l’intérieur d’un conteneur. Le localhost de l’application est l’application elle-même. Utilisez le Service ou le nom de conteneur du Collector.
  • Le SDK est désactivé ou l’exporter est none. Cherchez OTEL_SDK_DISABLED=true ou OTEL_TRACES_EXPORTER=none.
  • Pas de service.name. Les données sont acceptées mais apparaissent comme unknown_service, ce qui ressemble à des données manquantes. Définissez OTEL_SERVICE_NAME.
  • Les processus de courte durée se terminent avant l’export. Les exporters par lots envoient périodiquement ; appelez donc le shutdown ou le flush du SDK avant de quitter.

Étape 2 : le receiver est-il joignable ?

curl -i http://collector:4318/v1/traces \
  -H 'Content-Type: application/json' -d '{}'

Une réponse HTTP 200 (un corps JSON vide convient) montre que le receiver HTTP est joignable. Pour gRPC, un outil comme grpcurl ou une vérification TCP (nc -zv collector 4317) prouve que le port est ouvert. Si ce n’est pas le cas :

  • Le receiver est peut-être lié à localhost. Définissez explicitement endpoint: 0.0.0.0:4317.
  • Le Service Kubernetes n’expose peut-être pas le port, ou le containerPort du pod est manquant.
  • Une NetworkPolicy, un pare-feu ou un service mesh bloque peut-être le trafic.

Étape 3 : le pipeline est-il câblé ?

C’est l’erreur de Collector la plus courante : un composant défini mais non utilisé. Définir exporters.otlp/tempo ne fait rien tant qu’il n’apparaît pas dans service.pipelines.<signal>.exporters. Il en va de même pour les receivers, processors, extensions et connectors.

Vérifiez :

  • Le nom du composant dans le pipeline correspond exactement à sa définition, y compris tout suffixe (otlp/tempo, pas otlp).
  • Le type de signal correspond : un pipeline traces ne peut pas utiliser un receiver ou un exporter qui ne prend pas en charge les traces.
  • L’extension est listée sous service.extensions.
  • Dans les values Helm, rappelez-vous que les listes remplacent, de sorte qu’un pipeline que vous avez partiellement redéfini a pu perdre les composants par défaut.

Étape 4 : voir les données à l’intérieur du Collector

Ajoutez l’exporter debug au pipeline :

exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [debug, otlp/tempo]

Lisez les logs du Collector. Voir des spans là prouve que les receivers et processors fonctionnent ; le problème est donc en aval. Ne rien voir signifie que les données n’ont jamais atteint le pipeline ou qu’un processor les a abandonnées (un processor filter ou le tail sampler est le suspect habituel). Retirez debug ou réduisez sa verbosité une fois terminé, car il journalise chaque élément.

Étape 5 : utiliser les signaux propres du Collector

Health check :

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
service:
  extensions: [health_check]

curl http://collector:13133/ renvoie un statut. Utilisez-le pour les probes de liveness et de readiness de Kubernetes.

Les métriques internes sont servies par défaut sur le port 8888 (vérifiez service.telemetry.metrics pour votre version) :

curl -s http://collector:8888/metrics | grep -E 'otelcol_(receiver|processor|exporter)_'

Lisez-les comme un entonnoir :

Famille de métriquesSignification
otelcol_receiver_accepted_*Éléments reçus avec succès
otelcol_receiver_refused_*Rejetés, souvent par memory_limiter
otelcol_processor_dropped_*Abandonnés par un processor
otelcol_exporter_sent_*Livrés au backend
otelcol_exporter_send_failed_*Rejetés par le backend ou injoignable
otelcol_exporter_queue_size et _capacityProfondeur de la file d’attente par rapport à sa limite

Des compteurs accepted qui montent avec des compteurs sent qui stagnent vous indiquent que le problème se situe au niveau de l’exporter. Des compteurs refused pointent vers les limites mémoire. Les noms de métriques ont été ajustés entre les releases ; consultez donc la documentation de télémétrie interne du Collector pour la vôtre.

zPages donnent une vue en direct des pipelines et des traces récentes :

extensions:
  zpages:
    endpoint: localhost:55679

Allez sur /debug/tracez et /debug/pipelinez (via kubectl port-forward sur un cluster). Gardez-le lié à localhost.

Étape 6 : le backend l’accepte-t-il ?

Regardez les erreurs d’exporter dans les logs du Collector :

  • connection refused ou deadline exceeded : mauvais endpoint ou port, ou blocage réseau.
  • certificate signed by unknown authority : ajoutez tls.ca_file, ou corrigez l’endpoint pour utiliser le bon nom d’hôte.
  • 401 ou 403 : le jeton ou l’en-tête est manquant ou incorrect. Confirmez que la variable d’environnement est définie dans le pod (kubectl exec ... -- env), car un ${env:VAR} non défini devient une valeur vide.
  • 415 ou erreurs d’analyse : incohérence de protocole, comme otlp (gRPC) pointé vers un port HTTP.
  • 404 sur HTTP : vérifiez le chemin de base attendu par le backend (Loki utilise /otlp, Prometheus /api/v1/otlp).
  • Prometheus rejette OTLP : son feature flag de receiver OTLP n’est pas activé.

Vérifications de l’auto-instrumentation

Pour l’injection via l’Operator, confirmez que l’Instrumentation existait avant le démarrage du pod, que l’annotation est sur le pod template, et que le pod applicatif possède l’init container opentelemetry-auto-instrumentation. Redémarrez la charge de travail après avoir créé ou modifié la ressource. Pour les configurations basées sur des agents, confirmez que l’option de l’agent ou la variable d’environnement est bien appliquée (-javaagent:, opentelemetry-instrument, --require).

Référence rapide

SymptômePremière chose à vérifier
Rien dans les logs du CollectorEndpoint, protocole, port du SDK ; localhost dans les conteneurs
Le Collector reçoit des données, le backend nonExporter dans le pipeline ; endpoint ; authentification ; protocole
Le Collector ne démarre pasSortie de validate ; composant absent de l’image
Les données apparaissent comme unknown_serviceDéfinir OTEL_SERVICE_NAME
Croissance de la mémoire ou redémarragesmemory_limiter en premier, tailles des files, limites de ressources
Traces partielles après échantillonnageUne trace doit atteindre un seul Collector (couche de répartition de charge)
Des données manquent par intermittenceFile pleine ou limite de retry atteinte ; vérifier send_failed et les métriques de file

Corrigez un saut à la fois, gardez l’exporter debug à portée de main pendant votre travail, et placez les métriques internes du Collector sur un tableau de bord afin que le prochain incident commence avec des preuves.

Guides populaires