Enquêter sur les anomalies de métriques
Le job : passer d'un symptôme de métrique ("le lag d'ingestion augmente") à une cause probable avec preuves, rapidement. La métrique te dit quoi et quand ; les logs et traces te disent pourquoi. Suis la boucle ci-dessous — elle priorise les appels bon marché et informatifs, et ne s'étend que si le rayon de souffle est flou.
La boucle
1. Cerner la métrique
Si tu as le nom exact de la métrique, passe à l'étape suivante. Sinon, appelle metric-names-list avec une sous-chaîne du symptôme (lag, error, latency, queue). Le metric_type retourné décide de la perspective : les compteurs (sum) n'ont de sens que comme rate/increase, les gauges comme avg, les histogrammes comme histogram_quantile.
2. Caractériser d'abord — un appel, trois réponses
Appelle characterize-metric-anomaly avec le nom de la métrique et anomalyFrom (l'heure du déclenchement de l'alerte, ou quand l'utilisateur dit que c'est devenu anormal ; soustrais une marge si tu hésites). Elle compare à la fenêtre précédente par défaut et répond à :
- Gravité :
direction,change_ratio,anomaly_peakvsbaseline_mean. Sidirectionestflat, ta fenêtre ou ta métrique est mal choisie — élargis la fenêtre, ou compare au même créneau hier viabaselineFrom/baselineTo(les métriques avec un pattern quotidien semblent souvent "anomales" face aux heures précédentes). - Quand :
onset_time— traite ce timestamp comme le pivot pour tout ce qui suit. - Où :
top_movers— les valeurs d'étiquette dont le comportement a changé. Un seul mouvant (un pod, shard ou endpoint unique) indique un coupable localisé ; tout qui bouge ensemble indique une cause partagée (une dépendance amont, un déploiement, infra).
3. Affiner avec des requêtes de métriques ciblées
Utilise query-metrics pour tester les hypothèses que le rapport soulève :
- Détailler un mouvant : réinterroger avec
filtersépinglant la valeur d'étiquette suspecte, groupé par une deuxième clé, pour localiser davantage (pod → conteneur, endpoint → code de statut). - Normaliser : un compteur d'erreurs croissant ne veut rien dire si le trafic a doublé — utilise
clauses+formula(errors / requests) pour séparer les changements de taux des changements de volume. - Vérifier les voisins : interroger les métriques compagnes évidentes sur le même créneau (pour lag : débit et compteurs d'erreurs du même service ; pour latency : taux de requêtes et jauges de saturation). Utilise le même
intervalpour que les grilles s'alignent visuellement.
4. Corréler les signaux à l'onset
Pivote vers les logs et traces en utilisant le même service et une fenêtre encadrant onset_time (quelques buckets avant, jusqu'au pic) :
- Logs : utilise
query-logs(suis son propre workflow discover-first) filtré auservice.nameimpliqué et à la fenêtre, sévéritéerroren premier, puiswarn. Les redémarrages, crash loops, erreurs de connexion et marqueurs de déploiement juste avant onset sont les causes classiques. Élargis aux autres services dans le chemin de requête si les logs du service lui-même sont propres. - Traces : utilise les outils de span APM (
query-apm-spansetc.) pour le même service/fenêtre — les spans lentes ou en erreur montrent quelle dépendance s'est dégradée, et untrace_idd'un exemplar ou ligne de log relie une requête concrète à travers les trois signaux.
5. Conclure avec des preuves, pas des impressions
Énonce : le symptôme (métrique, ampleur, onset), la cause probable (ce que tu as trouvé dans logs/traces et comment son timing s'aligne avec onset), le rayon de souffle (quels services/étiquettes sont touchés, d'après les mouvants et requêtes groupées), et le niveau de confiance. Si la cause reste ambiguë, dis quelle hypothèse les preuves favorisent et ce qui lèverait l'ambiguïté (p. ex. "le lag a commencé à s'écouler à 20:12 — cohérent avec un redémarrage du consommateur ; vérifie qui l'a redémarré").
Exemple concret : "le lag d'ingestion augmente — pourquoi ?"
metric-names-listavecvalue: "lag"→logs_rate_limiter_message_lag_seconds(histogram) et collègues.characterize-metric-anomalydessus avecanomalyFrom= heure de l'alerte → directionup, ratio de changement 40x,onset_time20:10, top moverservice_name = logs-ingestion(le lag des autres services est resté plat) — donc le consommateur de logs spécifiquement est en retard, pas tout le pipeline.query-metrics:ratedu compteur de débit du consommateur sur la même fenêtre → le débit était zéro pendant le gap et a augmenté après onset : le consommateur n'était pas lent, il était down, et le "lag croissant" est le drainage du backlog.query-logspourservice.name = logs-ingestion(et ses voisins) autour de 20:00–20:15 → lignes de sortie de processus + redémarrage aux limites du gap.- Conclusion : outage consommateur 20:01–20:10 (redémarrage visible dans logs) ; pic de lag est drainage du backlog, auto-récupération ; signal affecté : fraîcheur des logs uniquement — pas de perte de données (conservation des messages du topic). Preuves : débit zéro pendant la fenêtre, pic de message-age égal à la durée d'outage, lignes de log de redémarrage.
Pièges
- Les compteurs réinitialisent au redémarrage du processus —
rate/increasegèrent déjà cela ; ne regarde jamais les valeurs brutes cumulatives du compteur à l'œil nu. - Une métrique qui arrête de rapporter n'est pas "zéro" — un gap dans
seriesavectop_moversmontrant une valeur d'étiquette disparue signifie que l'émetteur est mort ; pivote vers les logs immédiatement. - Ne fais pas confiance à une seule agrégation : une
avgplate peut cacher unp95criard. Pour les gauges et histogrammes de type latency, caractérise la queue aussi. - Les métriques Prometheus scrapées arrivent ~15–60s en retard sur le temps réel ; ne lis pas le dernier bucket d'une série comme "courant".