OpenTelemetry OpenTelemetry

Collecter les logs et les métriques d'infrastructure avec des receivers

Utilisez les receivers filelog, hostmetrics, kubeletstats et prometheus, et dérivez des métriques à partir des traces.

14 min Intermédiaire

Les applications qui utilisent un SDK OpenTelemetry envoient elles-mêmes leur télémétrie, mais une grande partie de ce que vous devez observer ne le fait pas : fichiers de logs, ressources de l’hôte, kubelet, et services qui exposent déjà des métriques Prometheus. Le Collector récupère tout cela grâce aux receivers. Ce guide présente les plus utiles, uniquement sous forme de configuration. Les noms d’options des composants changent d’une release à l’autre ; consultez le README de chaque receiver pour la version que vous exécutez. Tous sont présents dans les distributions contrib et Kubernetes.

Fichiers de logs avec filelog

Le receiver filelog suit (tail) des fichiers et transforme les lignes en enregistrements de logs.

receivers:
  filelog:
    include:
      - /var/log/myapp/*.log
    exclude:
      - /var/log/myapp/*.gz
    start_at: end            # ou "beginning" pour lire le contenu existant
    include_file_path: true
    operators:
      - type: json_parser
        timestamp:
          parse_from: attributes.time
          layout: '%Y-%m-%dT%H:%M:%S.%LZ'
        severity:
          parse_from: attributes.level

Les operators forment un petit pipeline d’analyse appliqué à chaque entrée. Les plus courants sont json_parser, regex_parser, move, add, remove et recombine (pour rassembler en un seul enregistrement les stack traces multilignes). Un exemple multiligne :

    operators:
      - type: recombine
        combine_field: body
        is_first_entry: body matches "^\\d{4}-\\d{2}-\\d{2}"
        source_identifier: attributes["log.file.path"]

Pour survivre aux redémarrages sans relire ni sauter de données, donnez au receiver une extension de stockage :

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

receivers:
  filelog:
    include: [/var/log/myapp/*.log]
    storage: file_storage

service:
  extensions: [file_storage]

Sur Kubernetes, les logs des conteneurs se trouvent sous /var/log/pods/*/*/*.log. Le preset logsCollection du chart Helm configure ce receiver, monte le chemin de l’hôte et analyse pour vous le format du runtime de conteneurs ; préférez-le donc à une écriture manuelle du receiver.

Métriques de l’hôte avec hostmetrics

Sur une VM ou un nœud, le receiver hostmetrics lit les chiffres de CPU, mémoire, disque, système de fichiers et réseau depuis le système d’exploitation :

receivers:
  hostmetrics:
    collection_interval: 30s
    scrapers:
      cpu:
      memory:
      load:
      disk:
      filesystem:
        exclude_mount_points:
          mount_points: [/dev/*, /proc/*, /sys/*, /run/*]
          match_type: regexp
      network:
      paging:

Exécutez-le dans un agent sur chaque hôte. Dans un conteneur, il rapporte la vue du conteneur, sauf si vous montez le système de fichiers de l’hôte et définissez root_path ; consultez donc le README du receiver avant de vous y fier. Ajoutez le processor resourcedetection pour étiqueter les métriques avec des informations sur l’hôte, le cloud ou Kubernetes :

processors:
  resourcedetection:
    detectors: [env, system]
    timeout: 5s
    override: false

Métriques Kubernetes

L’utilisation des ressources des nœuds et des pods provient du kubelet via kubeletstats, exécuté en DaemonSet :

receivers:
  kubeletstats:
    collection_interval: 30s
    auth_type: serviceAccount
    endpoint: ${env:K8S_NODE_NAME}:10250
    insecure_skip_verify: true
    metric_groups: [node, pod, container]

Transmettez le nom du nœud via la downward API :

env:
  - name: K8S_NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName

insecure_skip_verify est courant car les certificats du kubelet sont souvent auto-signés ; utilisez une configuration d’autorité de certification correcte lorsque vous le pouvez. Le service account doit avoir la permission de lire nodes/stats, ce que le preset Helm accorde.

L’état au niveau du cluster (réplicas des deployments, phase des pods, conditions des nœuds) provient du receiver k8s_cluster, et les événements Kubernetes de k8sobjects. Exécutez les deux une seule fois par cluster, dans un Deployment à un seul réplica, sinon vous collecterez des doublons. Les deux sont disponibles sous forme de presets Helm (clusterMetrics et kubernetesEvents).

Scraper des endpoints Prometheus

Le receiver prometheus accepte une configuration de scrape Prometheus standard, ce qui permet de migrer les cibles existantes sans les réécrire :

receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: node-exporter
          scrape_interval: 30s
          static_configs:
            - targets: ["node-exporter:9100"]
        - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
              action: keep
              regex: "true"

Deux pièges : dans une configuration de Collector, écrivez un signe dollar littéral dans une regex ou un remplacement Prometheus sous la forme $$, car le Collector essaie sinon de l’étendre comme une variable ; et si vous exécutez plusieurs réplicas qui scrapent tous les mêmes cibles, vous obtiendrez des doublons. Le Target Allocator de l’OpenTelemetry Operator existe pour répartir les cibles entre les réplicas du Collector, tout comme le fait d’exécuter un seul réplica de scraping.

Plusieurs receivers, un seul pipeline

Les receivers alimentent des pipelines du même type de signal :

service:
  pipelines:
    metrics:
      receivers: [otlp, hostmetrics, kubeletstats, prometheus]
      processors: [memory_limiter, resourcedetection, batch]
      exporters: [otlphttp/prometheus]
    logs:
      receivers: [otlp, filelog]
      processors: [memory_limiter, batch]
      exporters: [otlphttp/loki]

Vous pouvez aussi séparer en plusieurs pipelines par signal (metrics/infra, metrics/apps) pour appliquer des processors différents à chaque source.

Des métriques à partir des traces avec le connector spanmetrics

Si vos services émettent des traces mais pas de métriques de requêtes, le connector spanmetrics dérive à partir des spans le nombre de requêtes, le nombre d’erreurs et des histogrammes de latence. Un connector est un exporter dans un pipeline et un receiver dans un autre :

connectors:
  spanmetrics:
    histogram:
      explicit:
        buckets: [10ms, 50ms, 100ms, 250ms, 500ms, 1s, 2.5s, 5s]
    dimensions:
      - name: http.request.method
      - name: http.response.status_code

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo, spanmetrics]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors: [batch]
      exporters: [otlphttp/prometheus]

Chaque dimension multiplie le nombre de séries temporelles ; n’ajoutez donc que des attributs dont l’ensemble de valeurs est réduit et borné. N’utilisez jamais d’identifiants d’utilisateurs ni d’URL contenant des identifiants. Placez le connector avant tout échantillonnage afin que les chiffres reflètent l’ensemble du trafic (voir le guide sur l’échantillonnage).

Vérifier

Ajoutez l’exporter debug avec verbosity: detailed à une copie du pipeline et exécutez le Collector au premier plan. Vous devriez voir des enregistrements de logs avec la sévérité analysée, ou des noms de métriques tels que system.cpu.time, k8s.pod.cpu.usage ou traces.span.metrics.calls (le nommage peut varier selon la version). Si rien n’apparaît, vérifiez les permissions de fichiers pour filelog, la variable du nom de nœud pour kubeletstats, et que chaque receiver est bien listé dans un pipeline.

Guides populaires