investigating-metric-anomalies

Par posthog · skills

Enquête sur les anomalies de métriques serveur/infrastructure dans PostHog Metrics — depuis « cette métrique monte/chute/pique » ou une alerte déclenchée jusqu'à une cause probable avec preuves à l'appui. À utiliser lorsqu'on cherche pourquoi une métrique semble anormale (lag d'ingestion en hausse, taux d'erreur qui explose, latence qui se dégrade, profondeur de file qui grossit, débit qui chute), lorsqu'une alerte se déclenche sur une métrique OTel/Prometheus, ou pour tout triage d'incident qui part d'un symptôme métrique. Compose `characterize-metric-anomaly`, `query-metrics` et `metric-names-list` avec les logs (`query-logs`) et les traces (outils APM span) pour la corrélation cross-signal de la cause racine.

npx skills add https://github.com/posthog/skills --skill investigating-metric-anomalies

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_peak vs baseline_mean. Si direction est flat, ta fenêtre ou ta métrique est mal choisie — élargis la fenêtre, ou compare au même créneau hier via baselineFrom/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 interval pour 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é au service.name impliqué et à la fenêtre, sévérité error en premier, puis warn. 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-spans etc.) pour le même service/fenêtre — les spans lentes ou en erreur montrent quelle dépendance s'est dégradée, et un trace_id d'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 ?"

  1. metric-names-list avec value: "lag" → logs_rate_limiter_message_lag_seconds (histogram) et collègues.
  2. characterize-metric-anomaly dessus avec anomalyFrom = heure de l'alerte → direction up, ratio de changement 40x, onset_time 20:10, top mover service_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.
  3. query-metrics : rate du 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.
  4. query-logs pour service.name = logs-ingestion (et ses voisins) autour de 20:00–20:15 → lignes de sortie de processus + redémarrage aux limites du gap.
  5. 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/increase gè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 series avec top_movers montrant 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 avg plate peut cacher un p95 criard. 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".

Skills similaires