RousselTMLEARNING

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

Les métriques en profondeur

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 #

Choisir un instrument
Un mauvais choix d'instrument donne des graphiques faux : une file d'attente n'est pas un Counter.
InstrumentSynchroneAsynchrone (observable)Agrégation par défaut
Counteradd() dans le codeObservableCounter (lire un total existant)somme monotone
UpDownCounteradd(+1/-1)ObservableUpDownCountersomme non monotone
Histogramrecord()—histogramme
Gaugeset()ObservableGauge (callback à chaque export)dernière valeur

2. Temporalité et histogrammes #

Deux notions qui surprennent.

Cumulative ou delta #

Temporalité
Prometheus attend du cumulatif ; certains backends SaaS préfèrent le 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 #

TypePrincipeAtout
Explicitebornes fixées (par défaut 0, 5, 10, 25… 10000)compatible partout
Exponentielbornes calculées automatiquement à partir d'une échellepré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 #

OpenTelemetryPrometheus
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.routelabel http_route
ressource service.namelabels 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)

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

Mon suivi

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

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

✉️ Poser une question

Articles recommandés

Collecter des logs vers Loki : Alloy, Promtail, Docker et OpenTelemetry

Envoyer des logs vers Loki : Grafana Alloy, Promtail, driver Docker, OTLP, bons labels, parsing e...

LogQL (1/2) : requêter les logs (sélecteurs, filtres et parsers)

Apprendre LogQL : sélecteurs de flux, filtres de ligne, parsers json/logfmt/pattern/regexp, filtr...

LogQL (2/2) : transformer les logs en métriques

Créer des métriques à partir des logs avec LogQL : rate, count_over_time, bytes_rate, agrégations...

Loki : stockage, index TSDB, rétention et stockage objet

Configurer le stockage de Loki : chunks, index TSDB, schéma v13, S3/MinIO/GCS, compactor, rétenti...

Alerter sur les logs avec le Ruler de Loki

Mettre en place des alertes et des recording rules LogQL avec le Ruler Loki : configuration, fich...

Exploiter Loki en production : multi-tenant, limites, cardinalité et supervision

Exploiter Loki : multi-tenancy, limites par tenant, protection contre la cardinalité, diagnostics...

Thanos : étendre Prometheus (haute disponibilité, vue globale et rétention longue)

Comprendre pourquoi et comment utiliser Thanos : limites de Prometheus, composants (Sidecar, Quer...

Thanos Sidecar : accoler Thanos à Prometheus et téléverser vers le stockage objet

Mettre en place Thanos Sidecar : réglages Prometheus (external labels, blocs de 2 h), configurati...

Thanos Query et Query Frontend : une vue globale et dédupliquée

Configurer Thanos Query : endpoints StoreAPI, déduplication par replica label, partial response, ...