BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Articles Comment Utiliser Prometheus Pour Surveiller Des Applications À Grande Échelle

Comment Utiliser Prometheus Pour Surveiller Des Applications À Grande Échelle

Points Clés

  • Comment détecter les anomalies à partir de données en streaming en utilisant les technologies Prometheus, Apache Kafka et Apache Cassandra.
  • Les composants Prometheus comprennent le serveur Prometheus, un modèle de données de mesures, une interface graphique utilisateur intégrée et la prise en charge native de Grafana.
  • Grâce à Prometheus, vous pouvez surveiller les statistiques des applications telles que le débit (TPS) et les temps de réponse du générateur de charge Kafka (Kafka producer), du consommateur Kafka et du client Cassandra.
  • Le Node Exporter peut être utilisé pour surveiller le matériel hôte et les métriques du noyau.
  • Les capacités graphiques intégrées de Prometheus sont limitées; l'ajout de Grafana offre des capacités étendues.

Anomalia Machina, une application qui associe Apache Kafka et Apache Cassandra pour détecter les anomalies à partir de données en streaming, est un projet expérimental que nous avons développé pour une utilisation sur notre plate-forme reposant sur des technologies Open Source. Le projet nécessite que nous exécutions l'application (c.-à-d. Un générateur de charge et un pipeline de détecteurs) sur plusieurs instances EC2. Mais avant d'arriver à cela, nous avions besoin d'un moyen de collecter et d'afficher des métriques spécifiques à une application à partir d'instances distribuées afin de pouvoir exécuter notre application déployée par Kubernetes comme prévu. Dans cet article, je détaillerai comment Prometheus, un outil de surveillance open source particulièrement puissant, nous a aidés à accomplir cette tâche.

Comprendre le système de surveillance et d’alertes de Prometheus

Développé à l'origine par SoundCloud, puis mis en open source et accepté en 2016 comme deuxième projet de la CNCF (Cloud Native Computing Foundation), Prometheus est un outil de plus en plus populaire permettant une surveillance et des alertes pour les applications et les serveurs.

L'architecture de Prometheus ressemble à ceci :

Les components

Les principaux composants de Prometheus incluent le serveur Prometheus (qui gère la découverte de services, la récupération des métriques à partir d'applications surveillées, le stockage de ces métriques et l'analyse de données de séries chronologiques à l'aide du langage de requête PromQL), un modèle de données pour métriques, un système graphique simple intégré et le support natif de Grafana. Des composants facultatifs supplémentaires incluent un gestionnaire d'alertes (dans lequel les alertes peuvent être définies dans le langage de requêtes) et une passerelle Push utile pour la surveillance des applications de courte durée.

Généralement, les outils de surveillance des applications capturent des métriques via l’une des trois méthodes suivantes :

  • Instrumentation : ajout de code personnalisé au code source de l'application surveillée.
  • Agents : ajout d'un code à usage général spécial à l'environnement pour applications conçu pour capturer automatiquement les métriques standard.
  • Espionnage : utiliser des intercepteurs ou des prises réseau pour surveiller les appels ou le flux de données entre les systèmes.

Prometheus prend en charge l’utilisation d’une combinaison d’instruments et d’agents (qu’il appelle «exporters»). L'instrumentation nécessite un accès au code source et permet de capturer des métriques personnalisées. Il est également indépendant du langage de programmation et dispose de bibliothèques de clients officiellement prises en charge disponibles pour Go, Java/Scala, Python et Ruby. De nombreuses bibliothèques non officielles sont également disponibles (LISP, etc.), ou vous pouvez écrire les vôtres.

De nombreux exporters tiers sont disponibles pour permettre l’instrumentation automatique de logiciels spécifiques, notamment les bases de données, le matériel, les systèmes de messagerie, le stockage, HTTP, les API cloud, la journalisation, les systèmes de surveillance, etc. L'exporter JMX disponible peut exporter des métriques pour des applications basées sur la JVM, telles que Kafka et Cassandra. En même temps, certains logiciels exposeront des métriques au format Prometheus, rendant les exportateurs inutiles.

Un node exporter est disponible pour la surveillance du matériel hôte et des métriques du noyau. Le client Java de Prometheus contient des collecteurs pour les activités du ramasse-miettes, les zones de mémoires, JMX, le classloading, et le nombres de threads, qui peuvent être ajoutés un par un ou enregistrés tous à la fois à l'aide de DefaultExports.initialize();.

Ce que Prometheus fait bien (et ce qu’il ne fait pas du tout)

Prometheus est idéal pour surveiller les métriques - et c'est tout. Ce n'est pas un outil efficace de gestion des performances d'application (APM), car il se concentre uniquement sur les métriques côté serveur. Il ne propose pas de traçage d'appels distribués, de découverte et de visualisation de la topologie de service, d'analyse de performances ou de surveillance de l'expérience utilisateur (bien qu'il existe une extension github pouvant pousser les métriques du navigateur de l'utilisateur vers Prometheus). Le flux d'informations avec Prometheus est unidirectionnel, il ne peut donc pas être utilisé pour un contrôle actif. Enfin, Prometheus s'exécute en tant que serveur unique par défaut, mais il peut être mis à l'échelle à l'aide d'une fédération de serveurs.

Modélisation de données avec Prometheus


Fig 420 000 années de données chronologiques sur les carottes de glace antarctiques

Prometheus stocke les métriques sous forme de données chronologiques, de sorte qu'elles incluent des flux de valeurs (floattant 64 bits) horodatés à la milliseconde. Chaque métrique a un nom (une chaîne de caractères) et utilise une convention de dénomination qui inclut le nom de ce qui est surveillé, le type logique et les unités de mesure. Chaque métrique a également un ensemble de paires clé : valeur (les labeled dimensions). Par exemple, une métrique nommée http_requests_total pourrait inclure des étiquettes pour «méthode» («GET», «PUT») et pour «gestionnaire» (par exemple: «/login», «/search»). Prometheus ajoute également certaines étiquettes aux métriques automatiquement, notamment :

  • job : nom du job configuré auquel la cible appartient.
  • Instance : La partie <hôte>:<port> de l'URL extraite de la cible.

Les unités n'étant pas explicites, les conversions d'une unité à une autre ne peuvent être effectuées que manuellement dans le langage de requête (et doivent être effectuées avec une extrême prudence).

Les types de métriques

Prometheus propose quatre types de métriques différents :

  1. Compteur : un compteur est utile pour les valeurs qui peuvent seulement augmenter (les valeurs peuvent être remises à zéro au redémarrage).
  2. Jauge : une métrique de type jauge peut être utilisée pour les compteurs qui montent et descendent, et également utile pour les valeurs mesurées qui peuvent monter et descendre.
  3. Histogramme : un histogramme échantillonne les observations, telles que la durée des demandes ou la taille des réponses. Il les compte dans des compartiments que vous pouvez configurer, tout en offrant la somme de toutes les valeurs observées.
  4. Résumé : tout comme un histogramme, un résumé d’échantillons d’observations offre un décompte total des observations et la somme des valeurs observées, tout en calculant des quantiles configurables sur une fenêtre temporelle glissante.

Mettre Prometheus au service du monitoring pour Anomalia Machina

Pour comprendre ce que nous voulions récemment contrôler avec l'expérience Anomalia Machina, examinons son diagramme d'architecture fonctionnelle :

À l'aide de Prometheus, nous avons cherché à surveiller les métriques «génériques» de l'application, y compris le débit (TPS) et les temps de réponse du générateur de charge Kafka (Kafka producer), du consommateur Kafka et du client Cassandra (qui détecte les anomalies). De plus, nous voulions surveiller certaines métriques spécifiques à l'application, notamment le nombre de lignes renvoyées pour chaque lecture de Cassandra et le nombre d'anomalies détectées. Nous devions également surveiller les métriques matérielles telles que le processeur pour chacune des instances AWS EC2 sur lesquelles l'application était exécutée, et centraliser la surveillance en y ajoutant également les métriques Kafka et Cassandra.

Pour faire cela, nous avons commencé par créer un pipeline de tests simple utilisant trois méthodes (producer, consumer et detector). Nous avons ensuite utilisé un compteur nommé «prometheusTest_requests_total», qui mesurait le nombre de fois que chaque étape du pipeline s'exécutait avec succès, et une étiquette appelée «stage» permettant de différencier les différents comptes d'étapes (en utilisant «total» pour le nombre total de pipelines). Nous avons ensuite utilisé un deuxième compteur appelé «prometheusTest_anomalies_total» pour compter les anomalies détectées. Et nous avons utilisé une jauge nommée «prometheusTest_duration_seconds» pour enregistrer la durée de chaque étape en secondes (en utilisant une étiquette «stage» pour distinguer les étapes et une étiquette «total» pour la durée totale du pipeline).

Les méthodes disposent d'instruments qui incrémentent les métriques de compteurs chaque fois qu'une étape est exécutée avec succès ou qu'une anomalie est détectée (à l'aide de la méthode inc()), et définissent la valeur temporelle de la métrique de jauge pour chaque étape (à l'aide de la méthodesetToTime()).

Voici un exemple de code :

import java.io.IOException;
import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.exporter.HTTPServer;
import io.prometheus.client.hotspot.DefaultExports;
 
// https://github.com/prometheus/client_java
// Demo of how we plan to use Prometheus Java client to instrument Anomalia Machina.
// Note that the Anomalia Machina application will have Kafka Producer and Kafka consumer and rest of pipeline running in multiple separate processes/instances.
// So metrics from each will have different host/port combinations.
public class PrometheusBlog {  
static String appName = "prometheusTest";
// counters can only increase in value (until process restart)
// Execution count. Use a single Counter for all stages of the pipeline, stages are distinguished by labels
static final Counter pipelineCounter = Counter.build()
    .name(appName + "_requests_total").help("Count of executions of pipeline stages")
    .labelNames("stage")
    .register();
// in theory could also use pipelineCounter to count anomalies found using another label
// but less potential for confusion having another counter. Doesn't need a label
static final Counter anomalyCounter = Counter.build()
    .name(appName + "_anomalies_total").help("Count of anomalies detected")
    .register();
// A Gauge can go up and down, and is used to measure current value of some variable.
// pipelineGauge will measure duration in seconds of each stage using labels.
static final Gauge pipelineGauge = Gauge.build()
    .name(appName + "_duration_seconds").help("Gauge of stage durations in seconds")
    .labelNames("stage")
    .register();
 
public static void main(String[] args) {
// Allow default JVM metrics to be exported
   DefaultExports.initialize();
 
   // Metrics are pulled by Prometheus, create an HTTP server as the endpoint
   // Note if there are multiple processes running on the same server need to change port number.
   // And add all IPs and port numbers to the Prometheus configuration file.
HTTPServer server = null;
try {
server = new HTTPServer(1234);
} catch (IOException e) {
e.printStackTrace();
}
// now run 1000 executions of the complete pipeline with random time delays and increasing rate
int max = 1000;
for (int i=0; i < max; i++)
{
// total time for complete pipeline, and increment anomalyCounter
pipelineGauge.labels("total").setToTime(() -> {
producer();
consumer();
if (detector())
anomalyCounter.inc();
});
// total pipeline count
pipelineCounter.labels("total").inc();
System.out.println("i=" + i);
 
// increase the rate of execution
try {
Thread.sleep(max-i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
server.stop();
}
// the 3 stages of the pipeline, for each we increase the stage counter and set the Gauge duration time
public  static void producer() {
class Local {};
String name = Local.class.getEnclosingMethod().getName();
pipelineGauge.labels(name).setToTime(() -> {
try {
Thread.sleep(1 + (long)(Math.random()*20));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
pipelineCounter.labels(name).inc();
   }
public  static void consumer() {
class Local {};
String name = Local.class.getEnclosingMethod().getName();
pipelineGauge.labels(name).setToTime(() -> {
try {
Thread.sleep(1 + (long)(Math.random()*10));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
pipelineCounter.labels(name).inc();
   }
// detector returns true if anomaly detected else false
public  static boolean detector() {
class Local {};
String name = Local.class.getEnclosingMethod().getName();
pipelineGauge.labels(name).setToTime(() -> {
try {
Thread.sleep(1 + (long)(Math.random()*200));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
pipelineCounter.labels(name).inc();
return (Math.random() > 0.95);
   }
}

Avec un exemple de code préparé, il est important de comprendre comment exécuter Prometheus et comment Prometheus obtient les valeurs de mesure du code. Contrairement aux solutions APM d’entreprise auxquelles des métriques sont transmises, Prometheus reçoit des métriques en interrogeant par polling («scraping») le code instrumenté. Cela nécessite simplement l’exécution d’un serveur HTTP dans le code de l’application : le code ci-dessus crée un serveur HTTP sur le port 1234 qui permet à Prometheus d'obtenir des métriques.

Pour télécharger et exécuter Prometheus, suivez ce «guide de démarrage».

Ensuite, nous devons aborder les dépendances Maven :

<!-- The client -->
<dependency>
 <groupId>io.prometheus</groupId>
 <artifactId>simpleclient</artifactId>
 <version>LATEST</version>
</dependency>
<!-- Hotspot JVM metrics-->
<dependency>
 <groupId>io.prometheus</groupId>
 <artifactId>simpleclient_hotspot</artifactId>
 <version>LATEST</version>
</dependency>
<!-- Exposition HTTPServer-->
<dependency>
 <groupId>io.prometheus</groupId>
 <artifactId>simpleclient_httpserver</artifactId>
 <version>LATEST</version>
</dependency>
<!-- Pushgateway exposition-->
<dependency>
 <groupId>io.prometheus</groupId>
 <artifactId>simpleclient_pushgateway</artifactId>
 <version>LATEST</version>
</dependency>

Et enfin, nous devons dire à Prometheus d’où il obtient les données. Pour des déploiements simples ou à des fins de test, il est approprié d’ajouter ces informations au fichier de configuration (par défaut c'est le fichier prometheus.yml):

global:
 scrape_interval:     15s # By default, scrape targets every 15 seconds.
 
# scrape_configs has jobs and targets to scrape for each.
scrape_configs:
 # job 1 is for testing prometheus instrumentation from multiple application processes.
 # The job name is added as a label job=<job_name> to any timeseries scraped from this config.
 - job_name: 'testprometheus'
 
   # Override the global default and scrape targets from this job every 5 seconds.
   scrape_interval: 5s
   
   # this is where to put multiple targets, e.g. for Kafka load generators and detectors
   static_configs:
     - targets: ['localhost:1234', 'localhost:1235']
     
 # job 2 provides operating system metrics (e.g. CPU, memory etc).
 - job_name: 'node'
 
  # Override the global default and scrape targets from this job every 5 seconds.
   scrape_interval: 5s
   
   static_configs:
     - targets: ['localhost:9100']

Le fichier de configuration comprend également un job appelé «node» utilisant le port 9100. Ce job fournit des métriques de noeuds. Pour l'utiliser, vous devez télécharger le node exporter de Prometheus et l'exécuter sur le même serveur que l'application. Il existe des avantages et des inconvénients au polling de métriques : une interrogation trop fréquente peut surcharger les applications, mais une interrogation insuffisante peut produire des décalages inquiétants entre le moment où les événements se produisent et celui où ils sont détectés.

Dans le même temps, ce système est robuste et relativement faiblement couplé, car les applications peuvent s'exécuter sans Prometheus et Prometheus continuera simplement d'essayer d'interroger les applications non disponibles jusqu'à ce qu'elles soient disponibles. Il est également possible d'interroger une seule application avec plusieurs serveurs Prometheus. Toutefois, si pour une raison quelconque, il n'est pas possible d'interroger les statistiques de l'application ou si l'application est très transitoire, Prometheus propose une push gateway pouvant être utilisée à la place.

Premiers résultats avec Prometheus

Prometheus n'incluant pas de tableaux de bord par défaut, nous avons donc initialement utilisé des expressions dans notre expérimentation. Dans l'interface Prometheus, vous trouverez un menu déroulant dans lequel vous pouvez sélectionner des noms de métriques (vous pouvez également le faire via un navigateur à l'adresse http://localhost:9090/metrics). Vous pouvez ensuite entrer ces métriques dans la zone d'expression et les exécuter. Ne vous découragez pas si vous rencontrez un message d'erreur et que vous avez besoin de résoudre un problème à ce stade (il s'agit d'une expérience courante).

Une fois que l'expression est en place, vous pouvez afficher les résultats dans un tableau ou un graphique, le cas échéant, pour ce type de résultat. Par défaut, les expressions ne récupèrent que les données des cinq dernières minutes. Si les données ne sont pas disponibles, vous recevez une erreur. Dans le but d’essayer Prometheus, vous pouvez tirer parti du fait que Prometheus se surveille lui-même pour explorer la solution sans avoir besoin d’une application instrumentée disponible.

Les données graphiques

Comme une métrique de compteur augmente simplement en valeur, la représentation graphique d'un compteur produira simplement une ligne:

Pour obtenir un graphique de taux basé sur une métrique de compteur, utilisez la fonction irate ou rate.

Dans l'exemple ci-dessous, le graphique affiche les durées des étapes du pipeline et ne nécessite pas de fonction rate car il s'agit d'une jauge au lieu d'un compteur:

Bien que les capacités graphiques intégrées de Prometheus soient limitées (par exemple, vous ne pouvez pas représenter plus d'une métrique sur le même graphique), Grafana offre des fonctionnalités bien plus étendues. Grafana offre une prise en charge intégrée de Prometheus et est indispensable pour les utilisations graphiques sérieuses. Les sites de Prometheus et Grafana offrent tous les deux une documentation utile sur l’utilisation conjointe de ces outils.

Pour utiliser Grafana, installez-le et naviguez sur votre navigateur vers l'url http://localhost:3000/. Créez une source de données Prometheus, puis ajoutez un graphique Prometheus, en utilisant une expression comme d'habitude. Par exemple, le graphique ci-dessous peut afficher les mesures de durée et de taux :

Un conseil : si rien n’est visible sur le graphique, le problème est probablement que vous ne voyez pas la plage de temps correcte. Une solution rapide consiste à utiliser un «Quick range» - le réglage «5 dernières minutes» devrait suffire. Vous pouvez également utiliser des règles pour précalculer les taux, afin d'accélérer potentiellement l'agrégation.

Il est également possible de représenter graphiquement les métriques de nœud, telles que l'utilisation du processeur (ce blog fournit des conseils à cet égard). Par exemple, vous pouvez calculer l'utilisation de la CPU sous forme de pourcentage avec cette expression:

100 - (avg by (instance)
(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) * 100)

Enfin, ceux qui utilisent Cassandra avec ces outils peuvent également trouver un intérêt à utiliser Cassandra Exporter for Prometheus d'Instaclustr, ce qui est idéal pour intégrer les métriques Cassandra d'un cluster auto-géré à la surveillance de votre application en utilisant Prometheus. L’outil est bien documenté et constitue un point de départ utile pour approfondir la compréhension de Prometheus.

Après avoir acquis nos connaissances sur l'utilisation de Prometheus pour surveiller un exemple d'application, nous sommes en mesure de surveiller le code de l'application Anomalia Machina et de le mettre en production en toute confiance.

About the Author

Paul Brebner est Chief Technology Evangelist chez Instaclustr, qui fournit une plate-forme de services utilisant des technologies open source telles que Apache Cassandra, Apache Spark, Elasticsearch et Apache Kafka.

 

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT