OpenTelemetry OpenTelemetry

Préparer le Collector pour la production : limites mémoire, batching et retries

Configurez processors, files d'attente et stockage persistant pour que la télémétrie survive aux surcharges et aux pannes.

12 min Intermédiaire

Un Collector qui fonctionne sur un portable peut s’effondrer en production : un pic de trafic épuise la mémoire, une panne de backend fait perdre des données, ou un redémarrage perd tout ce qui était en cours. Les remèdes relèvent tous de la configuration. Ce guide couvre les processors et les paramètres d’exporter que tout Collector de production devrait avoir, ainsi que l’ordre dans lequel les placer.

Le pipeline de base

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20
  batch:
    timeout: 5s
    send_batch_size: 8192

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

L’ordre compte : les processors s’exécutent dans l’ordre où ils sont listés. memory_limiter va en premier afin que la contre-pression atteigne les receivers avant que quoi que ce soit d’autre ne consomme de la mémoire. batch va en dernier, après tout filtrage ou enrichissement, afin que les lots soient construits à partir des données finales.

memory_limiter

Il surveille la mémoire du Collector et refuse de nouvelles données lorsque l’utilisation devient trop élevée, de sorte que le processus ralentit au lieu d’être tué par le système d’exploitation.

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 4000
    spike_limit_mib: 800
  • check_interval est la fréquence de mesure de la mémoire. Une valeur de 1s est recommandée, et la valeur par défaut de 0s désactive la vérification périodique.
  • limit_mib est la limite stricte pour la mémoire du heap. L’ensemble du processus en utilise généralement un peu plus.
  • spike_limit_mib est le saut maximal attendu entre deux vérifications, et vaut par défaut 20 pour cent de la limite. La limite souple est limit_mib moins spike_limit_mib (ici 3200 MiB).
  • limit_percentage et spike_limit_percentage expriment les mêmes limites en part de la mémoire disponible (Linux avec cgroups). Elles conviennent aux conteneurs dont la limite mémoire est définie par Kubernetes. Si limit_mib est aussi défini, il a priorité.

Au-dessus de la limite souple, le processor refuse les données en renvoyant une erreur au composant précédent, et les émetteurs bien conçus réessaient ou ralentissent. Au-dessus de la limite stricte, il force aussi le garbage collection. Réglez-le un peu en dessous de la limite mémoire du conteneur afin qu’il agisse avant le noyau.

batch

Le batching regroupe les éléments afin que les exports soient moins nombreux et plus volumineux, ce qui économise du réseau et du travail côté backend.

processors:
  batch:
    timeout: 5s            # envoie après ce délai même si le lot n'est pas plein
    send_batch_size: 8192  # taille cible du lot
    send_batch_max_size: 0 # 0 signifie aucune borne supérieure

Réglez timeout pour la latence et send_batch_size pour le débit. Les versions récentes du Collector peuvent aussi effectuer le batching à l’intérieur de la file d’attente d’un exporter ; consultez la documentation de l’exporter helper pour votre version.

File d’attente et retries de l’exporter

Les exporters qui envoient via le réseau disposent d’une file d’attente d’envoi (sending queue) et d’une politique de retry. Ils se trouvent dans l’exporter, pas dans un processor, et ce sont eux qui vous protègent des courtes pannes de backend :

exporters:
  otlp/backend:
    endpoint: backend.example.com:4317
    sending_queue:
      enabled: true
      queue_size: 5000        # la valeur par défaut est 1000
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 10m   # la valeur par défaut est 300s

Comment raisonner sur les chiffres :

  • La file d’attente met les lots en tampon pendant que le backend est lent ou indisponible. Une file plus grande absorbe des incidents plus longs mais utilise plus de mémoire.
  • retry_on_failure réessaie avec des délais croissants, jusqu’à max_elapsed_time. Passé ce délai, les données sont abandonnées.
  • Dimensionnez les deux en fonction de votre volume et de la plus longue panne que vous voulez survivre sans perte.

File d’attente persistante : survivre aux redémarrages

Par défaut, la file d’attente vit en mémoire ; un crash perd donc ce qui était en file. Adossez-la au disque avec l’extension file_storage :

extensions:
  file_storage:
    directory: /var/lib/otelcol/storage

exporters:
  otlp/backend:
    endpoint: backend.example.com:4317
    sending_queue:
      storage: file_storage

service:
  extensions: [file_storage]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/backend]

Trois éléments sont requis : définir l’extension, la référencer dans l’exporter, et l’activer sous service.extensions. Montez un volume persistant à ce répertoire, par exemple un PersistentVolumeClaim pour un StatefulSet. Des données peuvent encore être perdues si le disque se remplit ou tombe en panne, ou si le backend reste indisponible au-delà de la limite de retry ; surveillez donc l’utilisation du disque.

Processors utiles au-delà des bases

Ajouter ou modifier des attributs :

processors:
  resource/env:
    attributes:
      - key: deployment.environment.name
        value: production
        action: upsert
  attributes/scrub:
    actions:
      - key: http.request.header.authorization
        action: delete
      - key: user.email
        action: hash

resource modifie les attributs qui décrivent le producteur (appliqués à tout un lot), et attributes modifie les attributs par span, par point de métrique ou par enregistrement de log. Utilisez-les pour ajouter des étiquettes d’environnement et pour supprimer ou hacher les valeurs sensibles avant que les données ne quittent votre réseau.

Éliminer le bruit avec le processor filter, écrit en OpenTelemetry Transformation Language (OTTL) :

processors:
  filter/health:
    error_mode: ignore
    traces:
      span:
        - 'attributes["url.path"] == "/healthz"'
        - 'attributes["url.path"] == "/ready"'

Transformer les données avec le processor transform :

processors:
  transform/normalize:
    error_mode: ignore
    trace_statements:
      - context: span
        statements:
          - set(attributes["team"], "payments") where resource.attributes["service.name"] == "checkout"

OTTL est puissant ; testez donc les instructions avec l’exporter debug sur une copie de vos données avant de les activer en production. La syntaxe des instructions et les contextes disponibles changent selon les versions ; consultez le README du processor pour la vôtre. Ces processors se trouvent dans la distribution contrib.

Protéger le Collector lui-même

  • Définissez des requests et limits de ressources Kubernetes, et gardez memory_limiter sous la limite.
  • Ajoutez health_check et utilisez-le pour les probes de liveness et de readiness.
  • Surveillez les métriques propres du Collector sur le port 8888 pour la taille des files, les éléments perdus et les données refusées. Alertez lorsque otelcol_exporter_queue_size approche de sa capacité ou lorsque les exporters signalent des échecs d’envoi.
  • Exécutez plus d’un réplica derrière un Service pour les gateways, et dimensionnez un seul réplica pour la rafale que vous attendez.

Checklist

  • memory_limiter est le premier processor de chaque pipeline.
  • batch est le dernier processor.
  • Les exporters réseau ont une file d’attente d’envoi et une politique de retry dimensionnées selon votre tolérance aux pannes.
  • Une file d’attente persistante est configurée là où la perte de données est inacceptable.
  • Les attributs sensibles sont supprimés ou hachés en périphérie.
  • Les health checks, les limites de ressources et les métriques du Collector sont en place.

Guides populaires