1. Le modèle des métriques #
MeterProvider, meters, instruments.
De la mesure au point exporté #
Le code enregistre des mesures sur des instruments créés par un meter. Le SDK les agrège (somme, histogramme, dernière valeur) par combinaison d'attributs, puis un metric reader les exporte périodiquement (60 s par défaut, OTEL_METRIC_EXPORT_INTERVAL).
from opentelemetry import metrics
meter = metrics.get_meter("shop.checkout", "1.4.0")
commandes = meter.create_counter("shop.orders", unit="{order}", description="Commandes validées")
duree = meter.create_histogram("http.server.request.duration", unit="s")
commandes.add(1, {"shop.payment.method": "card"})
duree.record(0.183, {"http.request.method": "POST", "http.route": "/orders", "http.response.status_code": 201})Les instruments #
| Instrument | Synchrone | Asynchrone (observable) | Agrégation par défaut |
|---|---|---|---|
| Counter | add() dans le code | ObservableCounter (lire un total existant) | somme monotone |
| UpDownCounter | add(+1/-1) | ObservableUpDownCounter | somme non monotone |
| Histogram | record() | — | histogramme |
| Gauge | set() | ObservableGauge (callback à chaque export) | dernière valeur |
2. Temporalité et histogrammes #
Deux notions qui surprennent.
Cumulative ou delta #
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative # ou delta, lowmemoryÀ savoir : Le processeur deltatocumulative du Collector convertit le delta en cumulatif avant un envoi vers Prometheus.Histogrammes #
| Type | Principe | Atout |
|---|---|---|
| Explicite | bornes fixées (par défaut 0, 5, 10, 25… 10000) | compatible partout |
| Exponentiel | bornes calculées automatiquement à partir d'une échelle | précis sur toute la plage sans réglage ; correspond aux histogrammes natifs Prometheus |
Erreur Courante : Les bornes par défaut sont en millisecondes « historiques » : pour une durée en secondes (unit="s"), définissez des bornes adaptées par une vue (0.005, 0.01, 0.025… 10) ou utilisez l'histogramme exponentiel.3. Vues et cardinalité #
Contrôler ce qui est produit.
Les vues #
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.view import View, ExplicitBucketHistogramAggregation, DropAggregation
provider = MeterProvider(metric_readers=[reader], views=[
View(instrument_name="http.server.request.duration",
aggregation=ExplicitBucketHistogramAggregation([0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5])),
View(instrument_name="http.server.request.duration", attribute_keys={"http.request.method", "http.route", "http.response.status_code"}),
View(instrument_name="db.client.connection.*", aggregation=DropAggregation()), # supprimer des métriques inutiles
])Cardinalité #
Chaque combinaison distincte d'attributs crée une série. 5 méthodes × 50 routes × 10 codes = 2 500 séries par instance. Un attribut user.id multiplie ce nombre par le nombre d'utilisateurs : le backend sature et la facture explose.
Bonne Pratique : Sur les métriques, n'utilisez que des attributs bornés (route, méthode, code, région). Les identifiants vont sur les spans et les logs.
4. Exemplars et Prometheus #
Relier une métrique à une trace.
Exemplars #
Un exemplar est un point de mesure particulier conservé avec son trace_id : sur un pic de latence p99, on clique sur l'exemplar et on ouvre la trace exacte d'une requête lente. Le filtre OTEL_METRICS_EXEMPLAR_FILTER=trace_based (défaut) n'enregistre que les mesures faites dans un span échantillonné.
Vers Prometheus #
| OpenTelemetry | Prometheus |
|---|---|
shop.orders (Counter, unit {order}) | shop_orders_total |
http.server.request.duration (Histogram, unit s) | http_server_request_duration_seconds_bucket, _sum, _count |
attribut http.route | label http_route |
ressource service.name | labels job / instance et métrique target_info |
# Prometheus 3 accepte l'OTLP nativement
prometheus --web.enable-otlp-receiver # point d'entrée : /api/v1/otlp/v1/metrics
# ou dans le Collector : exportateur prometheusremotewrite, ou prometheus (scrape)Mon suivi
Connectez-vous pour suivre votre progression et prendre des notes. Se connecter
Articles recommandés
Observer le réseau Kubernetes avec Cilium Hubble
Rendre visibles les flux réseau d'un cluster Kubernetes avec Cilium Hubble : architecture, CLI hu...
Profiling continu avec eBPF : Parca, Pyroscope et le profiler OpenTelemetry
Profiler en continu tous les processus d'un hôte grâce à eBPF : principe, Parca et parca-agent, P...
eBPF en production : sécurité, prérequis et limites
Ce qu'il faut savoir avant de déployer des agents eBPF : privilèges et capacités, versions de noy...
Bonnes pratiques eBPF pour l'observabilité
Check-list pour adopter eBPF en observabilité : choix des outils, déploiement progressif, sécurit...
Real User Monitoring (RUM) et Core Web Vitals : mesurer ce que vivent les utilisateurs
Pourquoi observer le front-end, ce que mesure le RUM, les Core Web Vitals (LCP, INP, CLS) et leur...
Grafana Faro : architecture et installation
Installer Grafana Faro : le SDK web (npm ou CDN), le récepteur faro.receiver d'Alloy, l'envoi ver...
Faro : erreurs JavaScript, logs, événements métier et sessions
Exploiter l'API Faro : capture automatique des erreurs, envoi manuel d'erreurs, logs, événements ...
Du clic à la base de données : traces front-end vers back-end avec Faro
Relier les requêtes du navigateur aux traces du back-end : TracingInstrumentation, propagation de...
Exploiter les données Faro : requêtes, dashboards, alertes et RGPD
Interroger les données Faro dans Loki (Web Vitals, erreurs, événements), construire des dashboard...