RousselTMLEARNING

TP · Opentelemetry : de la découverte à l'expertise

TP : Logs OpenTelemetry corrélés aux traces et collecte de fichiers avec correction

La correction est intégrée au TP (Voir les encadrés de couleur vert)

Ce que vous allez apprendre dans ce TP
  • Brancher un logger existant sur OpenTelemetry
  • Corréler logs et traces
  • Collecter des fichiers avec filelog

Introduction #

Ce que vous allez apprendre dans cette section
  • Brancher un logger existant sur OpenTelemetry
  • Corréler logs et traces
  • Collecter des fichiers avec filelog

Contexte. Les logs de facturation sont des fichiers texte que personne ne relie aux traces. Vous branchez le service moderne sur OpenTelemetry et récupérez les logs de l'application historique sans la modifier.

Prérequis : Docker et Python 3.10 ou plus ; la pile grafana/otel-lgtm (Collector, Tempo, Loki, Prometheus, Pyroscope et Grafana dans un seul conteneur)  ·  Durée estimée : 45 min

Des logs structurés, corrélés aux traces, issus des deux voies de collecte.

Mise en place #

Étapes guidées, avec leur correction.

  1. 1. Démarrer la pile d'observabilité

    Pourquoi ? Une seule image fournit un Collector OTLP et tous les backends : on se concentre sur le signal.

    Lancez grafana/otel-lgtm, créez un environnement Python et pointez les exportateurs vers le port OTLP/HTTP 4318.
    Voir la correction
    docker run -d --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 -p 4040:4040 grafana/otel-lgtm
    python3 -m venv .venv && . .venv/bin/activate
    export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    # Grafana : http://localhost:3000 (admin / admin)
  2. 2. Brancher le module logging

    Pourquoi ? Le LoggingHandler transforme chaque appel logging en LogRecord OpenTelemetry, avec le contexte de trace actif.

    Écrivez facturation.py : un LoggerProvider avec exportateur OTLP, un handler ajouté au logger racine, un TracerProvider, et des logs INFO et ERROR émis à l'intérieur de spans.
    Voir la correction
    pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
    cat > facturation.py <<'EOF'
    import logging, random, time
    from opentelemetry import trace
    from opentelemetry._logs import set_logger_provider
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
    from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
    from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    
    resource = Resource.create({"service.name": "facturation", "service.version": "2.1.0"})
    logs = LoggerProvider(resource=resource)
    logs.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
    set_logger_provider(logs)
    logging.basicConfig(level=logging.INFO)
    logging.getLogger().addHandler(LoggingHandler(level=logging.INFO, logger_provider=logs))
    traces = TracerProvider(resource=resource)
    traces.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(traces)
    
    log = logging.getLogger("facturation")
    tracer = trace.get_tracer("tp.facturation")
    for n in range(20):
        with tracer.start_as_current_span("emettre facture"):
            log.info("facture émise", extra={"shop.invoice.id": f"F-{n}", "shop.invoice.amount": random.randint(10, 900)})
            if n % 5 == 0:
                log.error("échec d'envoi au client", extra={"shop.invoice.id": f"F-{n}"})
        time.sleep(0.2)
    logs.shutdown() ; traces.shutdown()
    EOF
    python facturation.py
  3. 3. Interroger et corréler dans Grafana

    Pourquoi ? Le trace_id porté par chaque log permet de passer du log à la trace et inversement.

    Dans Explore > Loki, affichez les erreurs du service, dépliez une ligne et repérez trace_id, span_id, la sévérité et vos attributs. Ouvrez la trace liée, puis depuis un span Tempo affichez ses logs.
    Voir la correction
    {service_name="facturation"} | severity_text="ERROR"
    {service_name="facturation"} | shop_invoice_id="F-10"
    sum by (severity_text) (count_over_time({service_name="facturation"}[5m]))
  4. 4. Collecter les logs d'une application historique

    Pourquoi ? Sans toucher au code, le receiver filelog lit les fichiers, parse le JSON, la sévérité et le contexte de trace.

    Générez un fichier de logs JSON, puis lancez un Collector contrib sur le même réseau que la pile, avec filelog, json_parser, trace_parser et un processeur resource qui fixe service.name.
    Voir la correction
    mkdir -p logs
    for i in $(seq 1 30); do
      lvl=$([ $((i % 6)) -eq 0 ] && echo ERROR || echo INFO)
      printf '{"time":"%s","level":"%s","message":"traitement lot %d","trace_id":"%s","span_id":"%s"}\n' \
        "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$lvl" "$i" "$(openssl rand -hex 16)" "$(openssl rand -hex 8)" >> logs/app.log
    done
    cat > collector.yaml <<'EOF'
    receivers:
      filelog:
        include: [/logs/app.log]
        start_at: beginning
        operators:
          - type: json_parser
            severity: { parse_from: attributes.level }
          - type: trace_parser
            trace_id: { parse_from: attributes.trace_id }
            span_id: { parse_from: attributes.span_id }
          - type: move
            from: attributes.message
            to: body
    processors:
      resource:
        attributes: [{ key: service.name, value: facturation-historique, action: upsert }]
      batch: {}
    exporters:
      otlphttp: { endpoint: http://lgtm:4318 }
    service:
      pipelines:
        logs: { receivers: [filelog], processors: [resource, batch], exporters: [otlphttp] }
    EOF
    docker network create otel 2>/dev/null ; docker network connect otel lgtm
    docker run -d --name col-logs --network otel -v "$PWD/collector.yaml:/etc/otelcol-contrib/config.yaml" -v "$PWD/logs:/logs" otel/opentelemetry-collector-contrib:latest
    # Loki : {service_name="facturation-historique"} | severity_text="ERROR"
  5. 5. Réduire et masquer

    Pourquoi ? Le Collector supprime le bruit et les données personnelles avant le stockage.

    Ajoutez un processeur filter qui supprime les logs INFO et un transform qui masque les adresses e-mail dans le corps, puis vérifiez dans Loki.
    Voir la correction
    processors:
      filter/info:
        logs:
          log_record: ['severity_number < SEVERITY_NUMBER_WARN']
      transform/pii:
        log_statements:
          - context: log
            statements:
              - replace_pattern(body, "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+", "***@***")
    # pipeline : processors: [resource, filter/info, transform/pii, batch]
    # docker restart col-logs, puis nettoyage : docker rm -f col-logs

Niveau de difficulté : ●●●○○ (3/5)

Mon suivi

  • ⏱ Durée estimée : ≈ 45 min

Connectez-vous pour suivre votre progression et prendre des notes. Se connecter

✉️ Poser une question

Articles recommandés

Les logs avec OpenTelemetry : modèle de données, appenders, corrélation et collecte

Maîtriser le signal log : modèle de données LogRecord, Logs Bridge API et appenders (Logback, Log...

Comprendre la notion de score

Le concept de score va permettre à Elasticsearch de classer vos documents par pertinence lors d u...

Elastic Common Schema (ECS) : le format standard des données Elastic et son rôle dans Elastic SIEM

Comprendre l'Elastic Common Schema (ECS) : format standard des champs dans Elasticsearch, convent...

Grail : Dynatrace Data Lakehouse

Désormais vous disposez dans Dynatrace (SaaS) d'un Data Lakehouse nommé Grail dont vous pouvez co...

C'est quoi l'observabilité

La capacité à connaître l'état interne d'un système à partir des données que cette dernière émet...

Les types de transactions dans les base de données

Cet article détaille les différences entre trois concepts essentiels dans l'exécution des instruc...

Différences entre Technologies et Services dans Dynatrace

Dans Dynatrace, les concepts de 'Technologie' et de 'Services' aident à organiser et surveiller l...

Dynatrace : Différences entre SQL Modifications, SQL Queries or Procedures, et SQL Transactions

Cet article détaille les différences entre trois concepts essentiels dans l'exécution des instruc...

Licences Dynatrace : modèle par unités et consumption-based licensing (DPS)

Comprendre la facturation Dynatrace : l'ancien modèle de licences segmentées par unités (Host Uni...