RousselTMLEARNING

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

TP : Instruments, vues et exemplars avec le SDK métriques 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
  • Choisir le bon instrument
  • Configurer une vue
  • Utiliser les exemplars

Introduction #

Ce que vous allez apprendre dans cette section
  • Choisir le bon instrument
  • Configurer une vue
  • Utiliser les exemplars

Contexte. La direction veut suivre les commandes, les paniers en cours, le stock et la latence de l'API. Vous produisez ces métriques avec OpenTelemetry et vérifiez qu'elles sont exploitables dans Prometheus.

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 : 50 min

Des métriques bien typées, des histogrammes justes et une métrique reliée à une trace.

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. Produire des métriques avec les quatre familles d'instruments

    Pourquoi ? Le type d'instrument détermine l'agrégation et donc la justesse des graphiques.

    Écrivez boutique.py qui, en boucle, incrémente un Counter de commandes, fait varier un UpDownCounter de paniers, enregistre la durée des requêtes dans un Histogram et expose le stock via un ObservableGauge. Export toutes les 5 secondes.
    Voir la correction
    pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
    cat > boutique.py <<'EOF'
    import random, time
    from opentelemetry import metrics, trace
    from opentelemetry.metrics import Observation
    from opentelemetry.sdk.resources import Resource
    from opentelemetry.sdk.metrics import MeterProvider
    from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
    from opentelemetry.sdk.metrics.view import View, ExplicitBucketHistogramAggregation
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    
    resource = Resource.create({"service.name": "boutique", "service.version": "1.0.0"})
    VUES = []      # étape 4 : ajouter une vue ici
    reader = PeriodicExportingMetricReader(OTLPMetricExporter(), export_interval_millis=5000)
    metrics.set_meter_provider(MeterProvider(resource=resource, metric_readers=[reader], views=VUES))
    tp = TracerProvider(resource=resource); tp.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(tp)
    
    meter = metrics.get_meter("tp.boutique", "1.0.0")
    tracer = trace.get_tracer("tp.boutique")
    commandes = meter.create_counter("shop.orders", unit="{order}", description="Commandes validées")
    paniers = meter.create_up_down_counter("shop.carts.active", unit="{cart}", description="Paniers ouverts")
    duree = meter.create_histogram("http.server.request.duration", unit="s", description="Durée des requêtes")
    
    def lire_stock(options):
        for entrepot in ("lyon", "lille"):
            yield Observation(random.randint(50, 500), {"shop.warehouse": entrepot})
    meter.create_observable_gauge("shop.stock.level", callbacks=[lire_stock], unit="{item}")
    
    while True:
        with tracer.start_as_current_span("POST /orders"):
            d = random.choice([random.uniform(0.02, 0.2)] * 9 + [random.uniform(1, 3)])   # 10 % de requêtes lentes
            time.sleep(d / 10)
            duree.record(d, {"http.request.method": "POST", "http.route": "/orders", "http.response.status_code": 201})
        commandes.add(1, {"shop.payment.method": random.choice(["card", "paypal", "transfer"])})
        paniers.add(random.choice([1, 1, -1]))
    EOF
    python boutique.py &      # laisser tourner
  3. 3. Retrouver les métriques dans Prometheus

    Pourquoi ? La conversion OTLP vers Prometheus renomme les métriques : il faut savoir les retrouver.

    Dans Explore > Prometheus, retrouvez chaque métrique sous son nom Prometheus et écrivez les requêtes : débit de commandes par moyen de paiement, paniers ouverts, stock par entrepôt, latence p95.
    Voir la correction
    sum by (shop_payment_method) (rate(shop_orders_total[1m]))
    shop_carts_active
    shop_stock_level
    histogram_quantile(0.95, sum by (le) (rate(http_server_request_duration_seconds_bucket[1m])))
  4. 4. Corriger les bornes avec une vue

    Pourquoi ? Les bornes par défaut (0, 5, 10, 25… 10000) sont pensées pour des millisecondes : en secondes, presque tout tombe dans le premier intervalle et le p95 est faux.

    Observez les buckets actuels, arrêtez le script, ajoutez une vue avec des bornes en secondes, relancez et comparez le p95.
    Voir la correction
    # avant : sum by (le) (rate(http_server_request_duration_seconds_bucket[1m]))  -> tout dans le=5
    kill %1
    sed -i 's/^VUES = \[\].*/VUES = [View(instrument_name="http.server.request.duration", aggregation=ExplicitBucketHistogramAggregation([0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5]))]/' boutique.py
    python boutique.py &
    # après quelques minutes : le p95 reflète enfin les 10 % de requêtes lentes
  5. 5. Mesurer l'effet de la cardinalité

    Pourquoi ? Chaque valeur d'attribut distincte crée une série : un identifiant sur une métrique fait exploser le stockage.

    Comptez les séries de shop_orders_total, ajoutez temporairement un attribut user.id aléatoire, recomptez, puis retirez-le.
    Voir la correction
    count(shop_orders_total)                                   # 3 séries
    # dans boutique.py : commandes.add(1, {..., "user.id": str(random.randint(1, 5000))})
    count(shop_orders_total)                                   # des centaines, puis des milliers
    # conclusion : identifiants sur les spans et les logs, jamais sur les métriques
  6. 6. Relier une latence à sa trace

    Pourquoi ? Les mesures faites dans un span échantillonné portent un exemplar avec le trace_id : on passe du graphique à la requête exacte.

    Affichez le p95 dans un panneau Grafana avec l'option Exemplars activée, cliquez sur un point élevé et ouvrez la trace correspondante dans Tempo. Si aucun exemplar n'apparaît, vérifiez la version du SDK et OTEL_METRICS_EXEMPLAR_FILTER.
    Voir la correction
    pip show opentelemetry-sdk | grep Version          # exemplars : SDK Python récent
    export OTEL_METRICS_EXEMPLAR_FILTER=trace_based
    kill %1 ; python boutique.py &

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

Mon suivi

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

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

✉️ Poser une question

Articles recommandés

Les métriques OpenTelemetry : instruments, temporalité, histogrammes et exemplars

Maîtriser le signal métrique : MeterProvider, instruments synchrones et asynchrones (Counter, UpD...

Corréler traces, métriques, logs et profils avec OpenTelemetry

Relier les quatre signaux pour diagnostiquer vite : ressource commune, trace_id dans les logs, ex...

Tempo : générer des métriques à partir des traces (service graph, span metrics, exemplars)

Activer le metrics-generator de Tempo : service graphs, span metrics RED, remote write vers Prome...

Corréler traces, logs, métriques et profils dans Grafana

Relier Tempo aux logs (Loki), aux métriques (Prometheus) et aux profils (Pyroscope) : tracesToLog...

OpenTelemetry : Instrumentation Automatique vs Manuelle

Comprenez les différences entre l'instrumentation automatique et manuelle avec OpenTelemetry, leu...

Mesurer des SLI avec Prometheus

Implémenter des SLI de disponibilité et de latence avec Prometheus : métriques nécessaires, requê...

Les concepts fondamentaux d'OpenTelemetry : signaux, ressources, contexte et maturité

Le vocabulaire indispensable d'OpenTelemetry : les quatre signaux, API et SDK, ressource et instr...

Instrumenter ses applications pour Pyroscope : SDK, Alloy et eBPF

Envoyer des profils à Pyroscope depuis Go, Java, Python et Node.js avec les SDK, collecter les po...

Projet fil rouge : les quatre signaux de l'OpenTelemetry Demo dans la stack Grafana

Un projet fil rouge qui traverse les formations d'observabilité : déployer l'OpenTelemetry Demo, ...

Soutenir

♥ SOUTENIR

Soutenez RousselTM Learning

Les formations, articles, TP et attestations restent gratuits et sans publicité intrusive. Une contribution libre, du montant de votre choix, finance l’hébergement, les environnements de TP et l’écriture de nouveaux contenus.

Contribuer avec PayPal Montant libre · carte bancaire ou compte PayPalEn savoir plus
QR code PayPal
Ou scannez ce QR code avec votre téléphone

Merci, chaque contribution compte !