L'une des caractĂ©ristiques de base du langage de requĂŞte Prometheus est l' agrĂ©gation en temps rĂ©el des sĂ©ries chronologiques . Vous pouvez Ă©galement utiliser le langage de requĂŞte Prometheus pour dĂ©tecter les anomalies dans les donnĂ©es de sĂ©ries chronologiques. L'Ă©quipe Mail.ru Cloud Solutions a traduit un article de l'ingĂ©nieur de l'Ă©quipe d'infrastructure GitLab , oĂą vous trouverez des exemples de code que vous pouvez essayer sur vos systèmes.Ă€ quoi sert la dĂ©tection des anomalies?
Il existe quatre raisons principales qui déterminent l'importance de la détection d'anomalies pour GitLab:- Diagnostic des incidents : nous pouvons détecter les services qui ont dépassé leur portée normale en réduisant le temps de détection des incidents (MTTD) et, en conséquence, offrir une solution plus rapide au problème.
- Détection de la dégradation des performances : par exemple, si une régression est introduite dans un service qui lui fait accéder trop souvent à un autre service, nous pouvons rapidement détecter et résoudre ce problème.
- Détection et élimination des abus : GitLab fournit des mécanismes de livraison et d'intégration ( GitLab CI / CD ) et d'hébergement (GitLab Pages) et un nombre limité d'utilisateurs qui peuvent utiliser ces mécanismes.
- Sécurité : la détection des anomalies est importante pour détecter les tendances inhabituelles dans la série chronologique GitLab.
Pour ces raisons et d'autres, l'auteur de l'article a décidé de comprendre comment configurer la définition des anomalies dans la série temporelle GitLab à l'aide des requêtes et des règles de Prometheus.Quel est le niveau d'agrégation correct?
Tout d'abord, les séries chronologiques doivent être correctement agrégées. Dans l'exemple ci-dessous, nous avons utilisé le compteur http_requests_total standard pour récupérer des données, bien que de nombreuses autres mesures le fassent également.http_requests_total{
 job="apiserver",
 method="GET",
 controller="ProjectsController",
 status_code="200",
 environment="prod"
}
Cette mesure de test comporte plusieurs paramètres: méthode, contrôleur, code d'état (code_état), environnement, ainsi que des paramètres ajoutés par Prometheus lui-même, par exemple, travail et instance.Vous devez maintenant choisir le bon niveau d'agrégation de données. Trop, trop peu - tout cela est important pour détecter les anomalies. Si les données sont trop agrégées, il y a deux problèmes potentiels:- Vous pouvez ignorer l'anomalie car l'agrégation masque les problèmes qui se produisent dans des sous-ensembles de vos données.
- Si vous trouvez une anomalie, il est difficile de la relier à une partie distincte de votre système sans effort supplémentaire.
Si les données ne sont pas suffisamment agrégées, cela peut conduire à une augmentation du nombre de faux positifs, ainsi qu'à une interprétation incorrecte des données valides comme erronées.D'après notre expérience, le niveau d'agrégation le plus correct est le niveau de service, c'est-à-dire que nous incluons l'étiquette de travail (travail) et d'environnement (environnement) et rejetons toutes les autres étiquettes.L'agrégation, dont nous parlerons tout au long de l'article, comprend: travail - http_request, agrégation - cinq minutes, qui est calculé sur la base du travail et de l'environnement en cinq minutes.- record: job:http_requests:rate5m
expr: sum without(instance, method, controller, status_code)
(rate(http_requests_total[5m]))
# --> job:http_requests:rate5m{job="apiserver", environment="prod"}  21321
# --> job:http_requests:rate5m{job="gitserver", environment="prod"}  2212
# --> job:http_requests:rate5m{job="webserver", environment="prod"}  53091
D'après l'exemple ci-dessus, il est clair que dans la série http_requests_total, les sous-ensembles sont sélectionnés dans le contexte du travail et de l'environnement, puis leur nombre est considéré pendant cinq minutes.Utilisation du score Z pour détecter les anomalies
Les principes de base des statistiques peuvent ĂŞtre appliquĂ©s pour dĂ©tecter des anomalies.Si vous connaissez la moyenne et l' Ă©cart type de la sĂ©rie Prometheus, vous pouvez utiliser n'importe quel Ă©chantillon de la sĂ©rie pour calculer le z-score. Un Z-score est une mesure de l'Ă©cart relatif de la valeur observĂ©e ou mesurĂ©e, qui montre combien d' Ă©carts-types son Ă©cart par rapport Ă  la valeur moyenne est . Autrement dit, le score z = 0 signifie que le score z est identique Ă  la valeur moyenne dans l'ensemble de donnĂ©es avec la distribution standard, et le score z = 1 signifie que l'Ă©cart type = 1,0 de la moyenne.Nous supposons que les donnĂ©es de base ont une distribution normale, ce qui signifie que 99,7% des Ă©chantillons ont un score z de 0 Ă  3. Plus le score z est Ă©loignĂ© de zĂ©ro, moins il est probable qu'il existe. Nous appliquons cette propriĂ©tĂ© pour dĂ©tecter les anomalies dans la sĂ©rie de donnĂ©es Prometheus:- Nous calculons la moyenne et l'Ă©cart type de la mĂ©trique Ă  l'aide de donnĂ©es avec un Ă©chantillon de grande taille. Pour cet exemple, nous utilisons des donnĂ©es hebdomadaires. Si nous supposons que les enregistrements sont Ă©valuĂ©s une fois par minute, alors dans une semaine, nous aurons un peu plus de 10 000 Ă©chantillons.
 
 # Long-term average value for the series
- record: job:http_requests:rate5m:avg_over_time_1w
expr: avg_over_time(job:http_requests:rate5m[1w])
# Long-term standard deviation for the series
- record: job:http_requests:rate5m:stddev_over_time_1w
expr: stddev_over_time(job:http_requests:rate5m[1w])
 
 
- Nous pouvons calculer le z-score pour la requête Prometheus dès que nous obtenons la moyenne et l'écart-type pour l'agrégation.
 
 # Z-Score for aggregation
(
job:http_requests:rate5m -
job:http_requests:rate5m:avg_over_time_1w
) /  job:http_requests:rate5m:stddev_over_time_1w
 
 
Sur la base des principes statistiques des distributions normales, supposons que toute valeur en dehors de la plage de +3 à -3 sera une anomalie. En conséquence, nous pouvons créer un avertissement concernant de telles anomalies. Par exemple, nous recevrons une alerte lorsque notre agrégation dépasse cette plage pendant plus de cinq minutes.Graphique du nombre de requêtes par seconde au service GitLab Pages pendant 48 heures. Le score Z compris entre +3 et -3 est surligné en vert. Lescore Z peut être difficile à interpréter sur les graphiques, car cette valeur n'a pas d'unité de mesure. Mais les anomalies de ce graphique sont très simples à déterminer. Tout ce qui va au-delà de la zone verte, qui montre un couloir de valeurs avec un z-score de -3 à +3, sera une valeur anormale.Que faire si la distribution des données n'est pas normale
Nous supposons que la distribution des données est normale. Sinon, notre z-score sera faux.Il existe de nombreuses astuces statistiques pour déterminer la normalité de la distribution des données, mais le meilleur moyen est de vérifier que le score z de vos données se situe dans la plage de -4,0 à +4,0.Deux requêtes Prometheus montrant les scores z minimum et maximum:(
max_over_time(job:http_requests:rate5m[1w]) - avg_over_time(job:http_requests:rate5m[1w])
) / stddev_over_time(job:http_requests:rate5m[1w])
# --> {job="apiserver", environment="prod"}  4.01
# --> {job="gitserver", environment="prod"}  3.96
# --> {job="webserver", environment="prod"}  2.96
(
 min_over_time(job:http_requests:rate5m[<1w]) - avg_over_time(job:http_requests:rate5m[1w])
) / stddev_over_time(job:http_requests:rate5m[1w])
# --> {job="apiserver", environment="prod"}  -3.8
# --> {job="gitserver", environment="prod"}  -4.1
# --> {job="webserver", environment="prod"}  -3.2
Si vos résultats sont compris entre -20 et +20, cela signifie que trop de données ont été utilisées et les résultats sont déformés. N'oubliez pas également que vous devez travailler avec des lignes agrégées. Les mesures qui n'ont pas de distribution normale incluent des paramètres tels que le taux d'erreur, le retard, la longueur des files d'attente, etc. Mais bon nombre de ces mesures fonctionneront mieux avec des seuils d'alerte fixes.Détection statistique d'anomalies saisonnières
Bien que le calcul des scores z fonctionne bien avec la distribution normale des donnĂ©es de sĂ©ries chronologiques, il existe une deuxième mĂ©thode qui peut donner des rĂ©sultats de dĂ©tection d'anomalies encore plus prĂ©cis. C'est l'utilisation de la saisonnalitĂ© statistique. La saisonnalitĂ© est une caractĂ©ristique d'une mĂ©trique de sĂ©rie chronologique lorsque cette mĂ©trique subit des changements rĂ©guliers et prĂ©visibles qui se rĂ©pètent Ă  chaque cycle.Graphique des demandes par seconde (RPS) du lundi au dimanche pendant quatre semaines consĂ©cutives Legraphique ci-dessus illustre le RPS (nombre de demandes par seconde) pendant sept jours - du lundi au dimanche, pendant quatre semaines consĂ©cutives. Cette plage de sept jours est appelĂ©e «dĂ©calage», c'est-Ă -dire le motif qui sera utilisĂ© pour la mesure.Chaque semaine sur le graphique est d'une couleur diffĂ©rente. La saisonnalitĂ© des donnĂ©es est indiquĂ©e par la sĂ©quence des tendances indiquĂ©es sur le graphique - chaque lundi matin, nous observons une augmentation similaire du RPS, et le soir, le vendredi, nous observons toujours une diminution du RPS.En utilisant la saisonnalitĂ© dans nos donnĂ©es de sĂ©ries chronologiques, nous pouvons prĂ©dire avec plus de prĂ©cision l'occurrence des anomalies et leur dĂ©tection. Comment utiliser la saisonnalitĂ©
Prométhée utilise plusieurs mécanismes statistiques différents pour calculer la saisonnalité.Tout d'abord, nous faisons un calcul, en ajoutant une tendance de croissance pour la semaine aux résultats de la semaine précédente. La tendance de croissance est calculée comme suit: soustrayez la moyenne mobile de la semaine dernière de la moyenne mobile de la semaine dernière.- record: job:http_requests:rate5m_prediction
  expr: >
    job:http_requests:rate5m offset 1w          # Value from last period
    + job:http_requests:rate5m:avg_over_time_1w # One-week growth trend
    — job:http_requests:rate5m:avg_over_time_1w offset 1w
La première itĂ©ration s'avère quelque peu «étroite» - nous utilisons la fenĂŞtre de cinq minutes de cette semaine et de la semaine prĂ©cĂ©dente pour obtenir nos prĂ©visions.Ă€ la deuxième itĂ©ration, nous Ă©largissons notre couverture en prenant la moyenne de la pĂ©riode de quatre heures pour la semaine prĂ©cĂ©dente et en la comparant avec la semaine en cours. Ainsi, si nous essayons de prĂ©dire la valeur mĂ©trique Ă  huit heures du matin le lundi, au lieu de la mĂŞme fenĂŞtre de cinq minutes la semaine prĂ©cĂ©dente, nous prenons la valeur moyenne de la mesure de six Ă  dix le matin du lundi prĂ©cĂ©dent.- record: job:http_requests:rate5m_prediction
  expr: >
    avg_over_time(job:http_requests:rate5m[4h] offset 166h) # Rounded value from last period
    + job:http_requests:rate5m:avg_over_time_1w    # Add 1w growth trend
    - job:http_requests:rate5m:avg_over_time_1w offset 1w
La demande indiquait 166 heures, soit deux heures de moins qu'une semaine complète (7 * 24 = 168), car nous voulons utiliser une pĂ©riode de quatre heures en fonction de l'heure actuelle, nous avons donc besoin que le dĂ©calage soit de deux heures infĂ©rieur Ă  une semaine complète. RPS rĂ©el (jaune) et prĂ©vu (bleu) dans deux semainesUne comparaison du RPS rĂ©el avec nos prĂ©visions montre que nos calculs Ă©taient assez prĂ©cis. Cependant, cette mĂ©thode prĂ©sente un inconvĂ©nient. Par exemple, le 1er mai, GitLab a Ă©tĂ© utilisĂ© moins que d'habitude le mercredi, car ce jour Ă©tait un jour de congĂ©. Étant donnĂ© que la tendance de croissance estimĂ©e dĂ©pend de la façon dont le système a Ă©tĂ© utilisĂ© la semaine prĂ©cĂ©dente, nos prĂ©visions pour la semaine prochaine, c'est-Ă -dire le mercredi 8 mai, ont donnĂ© un RPS infĂ©rieur Ă  la rĂ©alitĂ©.Cette erreur peut ĂŞtre corrigĂ©e en faisant trois prĂ©visions pour trois semaines consĂ©cutives avant le mercredi 1er mai, c'est-Ă -dire les trois mercredi prĂ©cĂ©dent. La demande reste la mĂŞme, mais le dĂ©calage est ajustĂ©.- record: job:http_requests:rate5m_prediction
  expr: >
   quantile(0.5,
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 166h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 1w
       , "offset", "1w", "", "")
     or
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 334h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 2w
       , "offset", "2w", "", "")
     or
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 502h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 3w
       , "offset", "3w", "", "")
   )
   without (offset)
Il y a trois prĂ©visions sur le graphique pour trois semaines avant le 8 mai, par rapport au RPS rĂ©el du mercredi 8 mai. Vous pouvez voir que les deux prĂ©visions sont très prĂ©cises, mais les prĂ©visions pour la semaine du 1er mai restent inexactes.De plus, nous n'avons pas besoin de trois prĂ©visions, nous avons besoin d'une seule prĂ©vision. La valeur moyenne n'est pas une option, car elle sera floue par nos donnĂ©es RPS dĂ©formĂ©es du 1er mai. Au lieu de cela, vous devez calculer la mĂ©diane. PromĂ©thĂ©e n'a pas de requĂŞte mĂ©diane, mais nous pouvons utiliser l'agrĂ©gation quantile au lieu de la mĂ©diane.Le seul problème est que nous essayons d'inclure trois sĂ©ries dans l'agrĂ©gation, et ces trois sĂ©ries sont en fait la mĂŞme sĂ©rie en trois semaines. En d'autres termes, ils ont les mĂŞmes Ă©tiquettes, il est donc difficile de les assembler. Pour Ă©viter toute confusion, nous crĂ©ons une Ă©tiquette appelĂ©e dĂ©calage et utilisons la fonction de remplacement d'Ă©tiquette pour ajouter un dĂ©calage Ă  chacune des trois semaines. Ensuite, dans l'agrĂ©gation quantile, nous rejetons ces Ă©tiquettes, ce qui nous donne une moyenne de trois.- record: job:http_requests:rate5m_prediction
  expr: >
   quantile(0.5,
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 166h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 1w
       , "offset", "1w", "", "")
     or
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 334h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 2w
       , "offset", "2w", "", "")
     or
     label_replace(
       avg_over_time(job:http_requests:rate5m[4h] offset 502h)
       + job:http_requests:rate5m:avg_over_time_1w — job:http_requests:rate5m:avg_over_time_1w offset 3w
       , "offset", "3w", "", "")
   )
   without (offset)
Maintenant, nos prévisions avec une médiane de trois agrégations sont devenues plus précises.Prévision médiane par rapport au RPS réelComment savoir si nos prévisions sont vraiment précises
Pour vérifier l'exactitude des prévisions, nous pouvons revenir au z-score. Il est utilisé pour mesurer l'écart de l'échantillon avec sa prévision en écarts-types. Plus l'écart-type est important par rapport à la prévision, plus la probabilité qu'une valeur particulière soit une valeur aberrante est élevée.La plage d'écart projetée est de +1,5 à -1,5.Vous pouvez modifier notre graphique Grafana pour utiliser une prévision saisonnière, plutôt qu'une moyenne mobile hebdomadaire. La plage de valeurs normales pour une heure spécifique de la journée est ombrée en vert. Tout ce qui dépasse la zone verte est considéré comme une valeur aberrante. Dans ce cas, la valeur aberrante s'est produite dimanche après-midi, lorsque notre fournisseur de cloud a eu des problèmes de réseau.Il est recommandé d'utiliser un score z ± 2 pour les prévisions saisonnières.Comment configurer des alertes avec Prometheus
Si vous souhaitez configurer une alerte pour les événements anormaux, vous pouvez appliquer la règle assez simple de Prométhée, qui vérifie si le score z d'un indicateur est compris entre +2 et -2.- alert: RequestRateOutsideNormalRange
  expr: >
   abs(
     (
       job:http_requests:rate5m - job:http_requests:rate5m_prediction
     ) / job:http_requests:rate5m:stddev_over_time_1w
   ) > 2
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: Requests for job {{ $labels.job }} are outside of expected operating parameters
Dans GitLab, nous utilisons une règle de routage personnalisée qui envoie une alerte via Slack lorsqu'il détecte des anomalies, mais ne contacte pas notre équipe d'assistance.Comment détecter les anomalies dans GitLab en utilisant Prometheus
- Prométhée peut être utilisé pour détecter certaines anomalies.
- Une bonne agrégation est la clé pour trouver des anomalies.
- Le score Z est efficace si vos données ont une distribution normale.
- La saisonnalité statistique est un puissant mécanisme de détection des anomalies.
Traduit avec le support de Mail.ru Cloud Solutions .Toujours utile :- Méthodes de mise en cache simples dans GitLab CI: un guide d'images .
- Outils GitLab CE prĂŞts Ă  l'emploi et personnalisĂ©s sur le marchĂ© MCS . 
- Notre chaîne Telegram sur la transformation numérique .