Introduction
Grafana Tempo est un système de traçabilité distribuée (distributed tracing) open-source, conçu par Grafana Labs pour analyser les performances des applications microservices. Contrairement à Jaeger ou Zipkin, Tempo se distingue par sa simplicité : il indexe uniquement les IDs de traces (128 bits), stocke les traces brutes de manière immuable, et recherche via une requête par ID. Cela le rend scalable à l'infini sans bases de données coûteuses.
Pourquoi l'utiliser en 2026 ? Avec la montée des architectures cloud-native et Kubernetes, tracer les latences entre services est essentiel pour le debugging. Tempo s'intègre nativement avec Grafana pour des visualisations intuitives, Prometheus pour les métriques, et OpenTelemetry pour l'instrumentation standard. Ce tutoriel débutant vous guide pour une installation locale complète avec Docker Compose, incluant une démo fonctionnelle. À la fin, vous tracerez des requêtes réelles et les explorerez visuellement. Temps estimé : 20 minutes. (128 mots)
Prérequis
- Docker et Docker Compose installés (version 20+).
- Port 3000 (Grafana), 3200 (Tempo HTTP), 4317/4318 (OTLP) libres.
- Connaissances basiques en YAML et ligne de commande.
- Navigateur web pour l'interface Grafana.
Créer le fichier Docker Compose
version: "3"
services:
tempo:
image: grafana/tempo:latest
command: [ "-config.file=/etc/tempo.yaml" ]
volumes:
- ./tempo.yaml:/etc/tempo.yaml
- tempo-data:/tmp/tempo
ports:
- "3200:3200" # http
- "4317:4317" # otlp grpc
- "4318:4318" # otlp http
- "9411:9411" # zipkin
- "14268:14268" # jaeger ingest
networks:
- tempo
grafana:
image: grafana/grafana:latest
volumes:
- ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
ports:
- "3000:3000"
networks:
- tempo
otelcol:
image: otel/opentelemetry-collector-contrib:latest
command: [ "--config=/etc/otelcol-config.yaml" ]
volumes:
- ./otelcol-config.yaml:/etc/otelcol-config.yaml
ports:
- "8889:8889" # prometheus metrics
depends_on:
- tempo
networks:
- tempo
hotrod:
image: grafana/hotrod:latest
ports:
- "8080:8080"
environment:
- OTEL_SERVICE_NAME=hotrod
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otelcol:4318
- OTEL_RESOURCE_ATTRIBUTES=service.name=hotrod
depends_on:
- otelcol
networks:
- tempo
volumes:
tempo-data: {}
grafana-data: {}
networks:
tempo:
driver: bridgeCe fichier Docker Compose déploie un stack complet : Tempo pour le stockage des traces, Grafana pour la visualisation, OpenTelemetry Collector comme passerelle OTLP, et HotROD comme application de démo instrumentée. Les ports sont exposés pour l'accès externe. Créez un dossier projet, copiez ce code dedans, et il lancera tout en un docker compose up -d. Évitez les conflits de ports en vérifiant netstat avant.
Lancer le stack Tempo
Créez un dossier pour le projet : mkdir tempo-demo && cd tempo-demo. Collez le docker-compose.yml ci-dessus. Créez ensuite les fichiers de configuration manquants (prochaines étapes). Lancez avec docker compose up -d. Vérifiez les logs : docker compose logs -f. L'application HotROD sera disponible sur http://localhost:8080. Grafana sur http://localhost:3000 (admin/admin).
Configuration Tempo (local)
server:
http_listen_port: 3200
distributor:
receivers: # Receveurs configurés
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
jaeger:
protocols:
grpc:
endpoint: 0.0.0.0:14250
thrift_http:
endpoint: 0.0.0.0:8080
zipkin:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:9411
storage:
trace:
backend: local # Stockage local (fichier)
local:
path: /tmp/tempo/blocks
wal:
path: /tmp/tempo/wal
compactor:
compaction:
block_retention: 1h
compaction_window: 1h
max_compaction_objects: 1000000
metrics_generator:
registry:
external_labels:
source: tempo
cluster: local
overrides:
defaults:
metrics_generator_processors: [service-graphs, span-metrics]
receiver:
otlp:
protocols:
grpc:
http:
cleanup:
period: 1mCette config active les receveurs OTLP, Jaeger et Zipkin pour Tempo en mode local (stockage fichier WAL + blocks). Le compactor nettoie les anciennes traces après 1h. Pour la prod, passez à S3/MinIO. Piège : sans WAL, les traces se perdent au redémarrage ; ici, il assure la durabilité.
Configurer l'OTEL Collector
HotROD génère des traces automatiquement via OpenTelemetry vers l'OTEL Collector, qui forwarde vers Tempo. Accédez à HotROD : http://localhost:8080 et cliquez sur des boutons (ex: 'Frontend'). Les traces apparaissent en temps réel.
Configuration OTEL Collector
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
otlp:
endpoint: tempo:4317
tls:
insecure: true
logging:
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp, logging]
telemetry:
logs:
level: "debug"L'OTEL Collector reçoit les traces OTLP de HotROD, les batch et forwarde vers Tempo. Le logging aide au debug. En prod, ajoutez des processors comme 'spanmetrics' pour générer des métriques. Vérifiez les logs si pas de traces : docker compose logs otelcol.
Intégrer Grafana et explorer les traces
Connectez-vous à Grafana (admin/admin). Le datasource Tempo est provisionné automatiquement (prochaine config). Allez dans Explore > sélectionnez Tempo. Recherchez par service 'hotrod', ou collez un Trace ID depuis HotROD logs. Visualisez le waterfall des spans : latences, erreurs, liens vers logs/métriques.
Provisioning datasource Grafana
apiVersion: 1
datasources:
- name: Tempo
type: tempo
uid: tempo
url: http://tempo:3200
access: proxy
basicAuth: false
isDefault: true
jsonData:
tracesToLogsV2:
datasourceUid: "false"
tracesToMetricsV2:
datasourceUid: "false"
nodeGraph:
enabled: true
editable: trueCe fichier provisionne automatiquement le datasource Tempo dans Grafana. URL pointe vers le service interne Docker. Active Node Graph pour visualiser les graphes de services. Redémarrez Grafana après modification ; évitez 'proxy' si firewall strict.
Exemple instrumentation Python simple
import requests
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource
# Config
trace.set_tracer_provider(TracerProvider(resource=Resource.create({"service.name": "python-app"})))
tracer = trace.get_tracer(__name__)
otlp_exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces", insecure=True)
provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
# Exemple trace
with tracer.start_as_current_span("http-request"):
response = requests.get("http://localhost:8080/checkout")
print(f"Status: {response.status_code}")
print("Trace envoyée vers Tempo. Vérifiez dans Grafana.")Ce script Python instrumente une requête vers HotROD avec OpenTelemetry, exporte vers Tempo via OTLP HTTP. Installez pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc requests. Lancez-le pour générer des traces croisées. Piège : utilisez 'insecure=True' seulement en local.
Query traces via API Tempo
Testez l'API : curl -g 'http://localhost:3200/api/search?orgID=1&q=%7B.service.name%3D%22hotrod%22%7D'. Copiez un Trace ID dans Grafana Explore pour le détail.
Query API Tempo (Bash)
#!/bin/bash
curl -s -G "http://localhost:3200/api/traces/$1" | jq '.'
# Usage: ./query-traces.sh <trace-id>
# Exemple: ./query-traces.sh 1234567890abcdef1234567890abcdefCe script query une trace spécifique par ID hexadécimal. Utile pour scripts d'automatisation. jq formate le JSON. Obtenez l'ID depuis logs HotROD ou Grafana.
Bonnes pratiques
- Stockage scalable : Passez à MinIO/S3 pour >1TB traces/jour ; local WAL pour dev seulement.
- Instrumentation : Adoptez OpenTelemetry partout, évitez vendor-lock (Jaeger native).
- Sécurité : Activez auth Grafana, mTLS pour OTLP en prod ; limitez ports exposés.
- Rétention : Configurez compactor par tenant/orgID pour multi-tenant.
- Métriques : Activez 'span-metrics' pour corrélir traces/métriques Prometheus.
Erreurs courantes à éviter
- Pas de traces visibles : Vérifiez logs OTEL Collector ; endpoint OTLP mal configuré (4317 GRPC vs 4318 HTTP).
- Grafana vide : Datasource non provisionné ou URL erronée (utilisez 'tempo:3200' en Docker).
- Perte traces au restart : Sans WAL configuré, traces volatiles ; toujours activer.
- Performance : Index bloqué sur local ; migrez vers object storage dès >100GB.
Pour aller plus loin
- Documentation officielle : Grafana Tempo.
- Intégrez Loki/ Prometheus pour logs/métriques : Stack observabilité.
- Formation avancée : Découvrez nos formations Learni sur l'observabilité.
- Kubernetes : Helm chart Tempo pour prod.