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
Sécurité avancée Elasticsearch : TLS, certificats, clés d'API, FLS, DLS et audit
Sécuriser Elasticsearch en profondeur : TLS transport et HTTP, gestion des certificats avec elast...
Kibana avancé : data views, Lens, dashboards, alerting et reporting
Exploiter Kibana en profondeur : data views et champs runtime, Discover, Lens et formules, dashbo...
Elasticsearch sur Kubernetes avec ECK : déploiement, stockage persistant et mises à jour
Déployer Elasticsearch et Kibana sur Kubernetes avec Elastic Cloud on Kubernetes (ECK) : opérateu...
Recherche vectorielle et RAG avec Elasticsearch : dense_vector, kNN, recherche hybride et RRF
Construire une recherche sémantique avec Elasticsearch : embeddings, champ dense_vector, recherch...
Automatisation et infrastructure as code pour Elasticsearch : API, Terraform, Ansible et CI/CD
Automatiser l'administration d'Elasticsearch : API REST et clients, fournisseur Terraform elastic...
Cross-cluster search et cross-cluster replication : architectures multi-clusters Elasticsearch
Concevoir des architectures multi-clusters Elasticsearch : clusters distants, cross-cluster searc...
Monitoring de site web : disponibilité, surveillance HTTPS, certificats et performances
Mettre en place le monitoring d'un site web : surveillance de la disponibilité et du HTTPS, expir...
La stack LGTM (Loki, Grafana, Tempo, Mimir) : architecture et mise en place
Comprendre la stack LGTM de Grafana Labs : Loki pour les logs, Grafana pour la visualisation, Tem...
Prometheus sur Kubernetes et l'interface web de Prometheus
Déployer Prometheus sur Kubernetes avec kube-prometheus-stack (Prometheus Operator, ServiceMonito...