La correction est intégrée au TP (Voir les encadrés de couleur vert)
Ce que vous allez apprendre dans ce TP
- Auto-instrumenter tous les signaux
- Garantir une ressource commune
- Naviguer entre les signaux
Introduction #
Ce que vous allez apprendre dans cette section
- Auto-instrumenter tous les signaux
- Garantir une ressource commune
- Naviguer entre les signaux
Contexte. Une boutique de deux services renvoie des erreurs par intermittence. Vous instrumentez sans toucher au code et menez l'enquête en naviguant d'un signal à l'autre.
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
Mise en place #
Étapes guidées, avec leur correction.
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.
Lancezgrafana/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. Écrire les deux services
Pourquoi ? Le code ne contient aucune ligne OpenTelemetry : tout viendra de l'auto-instrumentation.
Créezfront.py(port 8001) qui appellestock.py(port 8002) ; le service stock échoue sur 15 % des requêtes avec un log d'erreur.Voir la correction
pip install flask requests opentelemetry-distro opentelemetry-exporter-otlp opentelemetry-bootstrap -a install # installe les instrumentations Flask, requests, logging… cat > stock.py <<'EOF' import logging, random, time from flask import Flask app = Flask(__name__) log = logging.getLogger("stock") @app.get("/stock/<sku>") def stock(sku): time.sleep(random.uniform(0.01, 0.08)) if random.random() < 0.15: log.error("pool de connexions épuisé pour %s", sku) return {"error": "indisponible"}, 503 return {"sku": sku, "qty": random.randint(0, 40)} app.run(port=8002) EOF cat > front.py <<'EOF' import logging, random, requests from flask import Flask app = Flask(__name__) log = logging.getLogger("front") @app.get("/produit") def produit(): sku = f"SKU-{random.randint(1, 50)}" r = requests.get(f"http://localhost:8002/stock/{sku}", timeout=2) if r.status_code != 200: log.warning("stock indisponible pour %s", sku) return {"error": "réessayez"}, 502 return r.json() app.run(port=8001) EOF3. Démarrer avec une ressource commune
Pourquoi ? Les mêmes variables pour les trois signaux garantissent la même ressource : c'est la clé de la corrélation.
Lancez chaque service avecopentelemetry-instrument, les trois exportateurs OTLP, la capture des logs et des attributs de ressource communs, puis générez du trafic.Voir la correction
export OTEL_TRACES_EXPORTER=otlp OTEL_METRICS_EXPORTER=otlp OTEL_LOGS_EXPORTER=otlp export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true OTEL_METRIC_EXPORT_INTERVAL=5000 export OTEL_RESOURCE_ATTRIBUTES=service.namespace=boutique,service.version=1.3.0,deployment.environment.name=tp OTEL_SERVICE_NAME=stock opentelemetry-instrument python stock.py & OTEL_SERVICE_NAME=front opentelemetry-instrument python front.py & sleep 3 ; for i in $(seq 1 400); do curl -s -o /dev/null localhost:8001/produit; done4. Partir de la métrique
Pourquoi ? L'enquête commence comme une alerte : une métrique d'erreurs issue des conventions HTTP, identique pour tous les services.
Dans Prometheus, calculez le taux d'erreurs 5xx par service à partir de l'histogrammehttp.server.request.duration(ou de son équivalent selon la version d'instrumentation). Activez les exemplars et ouvrez une trace depuis un point.Voir la correction
sum by (job) (rate(http_server_request_duration_seconds_count{http_response_status_code=~"5.."}[1m])) / sum by (job) (rate(http_server_request_duration_seconds_count[1m])) # anciennes conventions : http_server_duration_milliseconds_count{http_status_code=~"5.."}5. De la trace aux logs
Pourquoi ? La trace montre quel service a échoué ; ses logs disent pourquoi.
Dans Tempo, cherchez les traces en erreur, ouvrez-en une, constatez que le span serveur destockest en 503 et utilisez Logs for this span pour trouver le message « pool de connexions épuisé ». Faites le chemin inverse depuis Loki.Voir la correction
{ resource.service.namespace = "boutique" && status = error } { resource.service.name = "front" } >> { resource.service.name = "stock" && span.http.response.status_code = 503 } # Loki : {service_name="stock"} | severity_text="ERROR" -> champ trace_id -> lien Tempo6. Carte des services et métriques de spans
Pourquoi ? Les métriques calculées depuis les spans donnent débit, erreurs et durée par service et une carte des dépendances.
Ouvrez l'onglet Service Graph de Tempo dans Explore : vérifiez l'arêtefrontversstocket son taux d'erreur. Notez la ligne de configuration (connecteurservicegraphou générateur de métriques de Tempo) qui la rend possible.Voir la correction
traces_service_graph_request_failed_total{client="front", server="stock"} traces_spanmetrics_calls_total{service="stock", status_code="STATUS_CODE_ERROR"} # selon la version de l'image, ces métriques viennent du generator de Tempo ou des connecteurs du Collector7. Casser puis réparer la corrélation
Pourquoi ? Une ressource différente suffit à couper tous les liens : on le vérifie pour s'en souvenir.
RedémarrezstockavecOTEL_LOGS_EXPORTER=none, regénérez du trafic et constatez que Logs for this span ne renvoie plus rien. Remettez la configuration et arrêtez tout.Voir la correction
pkill -f "python stock.py" OTEL_LOGS_EXPORTER=none OTEL_SERVICE_NAME=stock opentelemetry-instrument python stock.py & for i in $(seq 1 100); do curl -s -o /dev/null localhost:8001/produit; done pkill -f "opentelemetry-instrument python" ; pkill -f "python front.py" ; pkill -f "python stock.py"
Niveau de difficulté : ●●●○○ (3/5)
Mon suivi
Connectez-vous pour suivre votre progression et prendre des notes. Se connecter
Articles recommandés
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...
Les métriques OpenTelemetry : instruments, temporalité, histogrammes et exemplars
Maîtriser le signal métrique : MeterProvider, instruments synchrones et asynchrones (Counter, UpD...
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...