RousselTMLEARNING

Observabilité

OpenTelemetry Collector : les Processors (transformer, filtrer et protéger la télémétrie)

Maîtriser les processors du Collector OpenTelemetry : batch, memory_limiter, attributes, resource, filter, transform (OTTL), k8sattributes, tail_sampling, ordre dans le pipeline et validation.

1. Le rôle des processors #

Entre la réception et l'export.

Que font-ils ? #

Un processor modifie, filtre ou regroupe la télémétrie (traces, métriques, logs) entre un receiver et un exporter. Il s'exécute dans l'ordre où il est déclaré dans le pipeline : l'ordre est donc significatif.

Ordre recommandé des processors dans un pipeline
Règle d'or : memory_limiter d'abord, batch en dernier.
# Le pipeline relie receivers -> processors (dans l'ordre) -> exporters
service:
  pipelines:
    traces:
      receivers:  [otlp]
      processors: [memory_limiter, k8sattributes, resource, filter, transform, batch]
      exporters:  [otlphttp/tempo]

2. Les processors essentiels #

Stabilité et performance.

memory_limiter et batch #

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80          # refuse les données au-delà de 80 % de la mémoire disponible
    spike_limit_percentage: 25
  batch:
    timeout: 5s
    send_batch_size: 8192
    send_batch_max_size: 10000
Bonne Pratique : Sans memory_limiter, un pic de télémétrie fait tuer le Collector (OOMKilled) et perd tout ce qui était en mémoire. Avec lui, le Collector refuse temporairement les données et l'émetteur réessaie.

attributes et resource #

processors:
  resource:
    attributes:
      - { key: deployment.environment, value: prod, action: upsert }
      - { key: host.name, action: delete }
  attributes/redact:
    actions:
      - { key: http.request.header.authorization, action: delete }
      - { key: user.email, action: hash }
      - { key: db.statement, action: update, value: "[masqué]" }
      - { key: credit_card, pattern: "\\d{12,16}", action: extract }
Erreur Courante : Supprimez ou hachez les données personnelles dans le Collector : c'est le dernier point de contrôle avant le stockage (RGPD).

3. Filtrer et transformer avec OTTL #

Le langage de transformation d'OpenTelemetry.

filter et transform #

processors:
  filter/healthchecks:
    error_mode: ignore
    traces:
      span:
        - 'attributes["http.target"] == "/healthz"'
        - 'IsMatch(attributes["http.target"], "^/(ready|live).*")'
    metrics:
      metric:
        - 'name == "http.server.duration" and resource.attributes["service.name"] == "legacy"'

  transform/normalize:
    error_mode: ignore
    trace_statements:
      - context: span
        statements:
          - set(attributes["env"], resource.attributes["deployment.environment"])
          - replace_pattern(attributes["http.url"], "token=[^&]+", "token=***")
          - truncate_all(attributes, 256)
    log_statements:
      - context: log
        statements:
          - set(severity_text, "ERROR") where body == "panic"
          - set(attributes["team"], "paiement") where resource.attributes["service.name"] == "checkout"

Enrichir dans Kubernetes #

processors:
  k8sattributes:
    auth_type: serviceAccount
    passthrough: false
    extract:
      metadata: [k8s.namespace.name, k8s.pod.name, k8s.node.name, k8s.deployment.name]
      labels:
        - { tag_name: app, key: app.kubernetes.io/name, from: pod }
    pod_association:
      - sources: [{ from: resource_attribute, name: k8s.pod.ip }]
      - sources: [{ from: connection }]
À savoir : Le Collector doit tourner avec un ServiceAccount autorisé à lire pods, namespaces et replicasets (ClusterRole), sinon l'enrichissement échoue silencieusement.

4. Échantillonnage et équivalents Alloy #

Réduire le volume.

tail_sampling #

processors:
  tail_sampling:
    decision_wait: 10s
    num_traces: 50000
    policies:
      - { name: erreurs, type: status_code, status_code: { status_codes: [ERROR] } }
      - { name: lentes,  type: latency,     latency: { threshold_ms: 1000 } }
      - { name: reste,   type: probabilistic, probabilistic: { sampling_percentage: 5 } }

Valider et tester #

otelcol-contrib validate --config=config.yaml
otelcol-contrib components | grep -A20 processors          # processors disponibles dans ce build

# Voir ce que devient la télémétrie : exporter debug temporaire
exporters: { debug: { verbosity: detailed } }

docker run --rm --network host ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest \
  traces --otlp-insecure --traces 5 --otlp-attributes 'user.email="a@b.fr"'
// Équivalent Grafana Alloy
otelcol.processor.memory_limiter "default" { check_interval = "1s"  limit_percentage = 80  output { traces = [otelcol.processor.batch.default.input] } }
otelcol.processor.batch "default" { output { traces = [otelcol.exporter.otlphttp.tempo.input] } }
otelcol.processor.attributes "redact" {
  action { key = "user.email"  action = "hash" }
  output { traces = [otelcol.processor.batch.default.input] }
}

Articles liés

OpenTelemetry Collector : les Exporters (envoyer la télémétrie vers les backends)

Configurer les exporters du Collector OpenTelemetry : OTLP gRPC/HTTP, Prometheus, prometheusremotewrite, Loki…

Tracing distribué : la propagation du contexte (W3C Trace Context et baggage)

Comprendre et mettre en œuvre la propagation de contexte OpenTelemetry : en-tête traceparent, tracestate, bag…

Architecture OpenTelemetry : Comprendre les 3 niveaux

Plongée au cœur de l'architecture OpenTelemetry. Apprenez comment les données circulent de l'application au b…

Pour aller plus loin