Lors des 2 premiers articles de notre saga sur le Monitoring applicatif, nous avons découvert les enjeux du Monitoring, avant de présenter les différentes solutions dans un second article.
Dans cette dernière partie, nous vous proposons un retour d’expérience de la mise en place d’une solution de monitoring au sein d’une entreprise de gestion d’actifs de renom. Le monitoring a été déployé sur un ensemble de modules applicatifs couvrant la gestion de portefeuilles jusqu’au passage d’ordres de bourse.
Nous allons parcourir les différents besoins de monitoring rencontrés et comment ils ont été adressés. Nous parlerons principalement des outils déployés. Ceux-ci ont été choisis en raison de leur popularité, de leur coût et de leur capacité à répondre au mieux aux besoins de trouver en un minimum de temps la racine d’un problème.
Contexte
Migration d’un monolithe à des micro-services
L’état de départ initial est un monolithe écrit en java regroupant tous les modules applicatifs répliqués sur 6 serveurs weblogic. Aujourd’hui, cet énorme monolithe est en cours de découpage en modules fonctionnels déployés dans leur propre serveur tomcat hébergé dans leur propre machine virtuelle.
Le nombre de serveurs tomcat grandit à chaque mise en production et il est essentiel d’avoir les outils adaptés pour maitriser et surveiller ce parc applicatif.
Contexte en chiffres :
- 4 équipes agiles soit env. 40 personnes
- Première mise en prod (Monolithe) > 15 ans
- Nombre de war déployés > 100
- Nombre de Virtual Machine > 60
- Nombre de modules fonctionnels > 40
Monitoring existant
Pour ces nouveaux serveurs tomcat, seuls les besoins de base en termes de monitoring étaient recensés avec la centralisation des logs applicatifs avec Kibana-ElasticSearch et le monitoring infra de la VM (CPU, Memory, Network, Disk) avec Grafana-ElasticSearch.
Comme nous allons le voir par la suite, ce déploiement nous donnait une vision très limitée du comportement des applications, et insuffisante pour analyser des disfonctionnements.
Quel est l’état de santé de mon application ?
La surveillance existante (c’est-à-dire les journaux d’application et les métriques des machines virtuelles) n’était pas suffisante pour répondre à ces questions :
- Mon serveur est-il correctement configuré en termes de ressources ?
- A-t-il suffisamment de mémoire (Xmx) ?
- Le dimensionnement de mon cache, du pool de connexion à la base de données et des autres threadpools est-il adapté aux besoins de l’application ?
- Avons-nous des traitements en attente à cause d’un manque de ressources ? etc.
Métriques
Nous avions besoin de connaitre l’état de santé de l’application pour savoir si elle était en pleine forme ou si elle montrait des signes de fatigue et de faiblesses. Il nous fallait donc pouvoir mesurer son état de santé, et pour cela, il était primordial de collecter différentes de ses métriques. Le couple d’outil Grafana et Prometheus répondait parfaitement à ce besoin : Prometheus pour la récupération et le stockage des métriques auprès de chaque application et Grafana pour la visualisation et la construction de dashboard (Tableau de bord) basé sur ces métriques.
Dans le code applicatif nous avons ajouté des sondes pour exposer ces métriques applicatives, par exemple :
- Le temps de pause du garbage collector,
- Le nombre d’élément dans le near-cache hazelcast,
- Le nombre de thread en attente d’une connexion à la base de donnée,
- Le nombre de threads utilisés,
- etc…
La plupart sont fournis par micrometer.io Il faut savoir qu’il est facile d’activer le module actuator avec spring boot pour exposer à Prometheus la plupart de ces métriques essentielles.
Dashboards (Tableau de bord)
L’étape suivante a consisté à créer des dashboards dans Grafana pour visualiser ces métriques. Un dashboard est une page web qui regroupe un ensemble de graphiques affichant des données et des informations. Dans cette optique, Grafana offre un ensemble de dashboards à télécharger. C’est un bon point de départ, mais il faut s’assurer de bien comprendre la signification de chaque métrique affichée afin d’accélérer l’analyse lors d’un problème en production. La quantité de métriques qui sont exposées peut être impressionnante et déroutante.
Nos dashboards sont régulièrement mis à jour pour mieux répondre à nos besoins et toujours dans le but d’optimiser le temps d’analyse en cas de problème. La création de dashboard est un processus itératif et propre à chaque type d’application.
Plusieurs stratégies sur le contenu des dashboards peuvent être adaptées. En effet, il est impossible de tout afficher sur un seul dashboard et il faut choisir comment catégoriser l’information : par application, par type de métrique, par serveur, etc… Nous avons opté pour l’approche de faire un dashboard par catégorie de métriques, par exemple les métriques de la JVM, et de fournir un filtre par applications et serveurs avec un graphique par instance de serveurs.
Cela dit, il peut s’avérer utile d’avoir un dashboard global qui regroupe l’ensemble des métriques importantes avec un graphique par métriques contenant tous les serveurs afin d’offrir une vue transversale à toutes les applications. C’est ce que nous avons fait pour créer un dashboard d’alerte dont nous reparlerons plus tard.
Une dernière recommandation est d’éviter l’utilisation de graphiques de type jauge qui affiche la valeur courante de la métrique. C’est joli et cool mais pas très utile. Pour analyser une métrique dans la grande majorité du temps, il faut connaitre son historique. Avec un graphique de type jauge il est impossible de répondre à ces questions :
- Depuis combien de temps cette métrique est dans le rouge ?
- Est-ce la première fois que nous avons une valeur si élevée ? Est-ce normal ? etc…
Les valeurs du passé sont essentielles à la bonne compréhension de la valeur actuelle de la métrique. Par exemple, en cas de visualisation d’un pic de 100 requêtes http par secondes, est-ce un disfonctionnement ou un comportement normal ? L’historique permettra de répondre à cette question.
A ce stade, nous étions donc aptes à mesurer l’état de santé de nos serveurs à ajuster les ressources en fonction des besoins. Par exemple, nous constations facilement qu’un serveur était ralenti à cause d’un long Garbage Collector dû à la mémoire « heap » trop petite. En revanche, nous n’avions aucune information précise sur ce qui consommait de la mémoire. Pour cela, nous avions besoin d’un autre outil plus proche du code : un APM (Application Performance Monitoring).
Besoin d’un scanner pour comprendre les problèmes
Chez les êtres vivants, la mesure du pouls, de la tension ou de la température n’est souvent pas suffisante pour savoir de quoi souffre un patient. Nous allons donc faire appel à d’autres outils tel que le scanner, l’IRM ou la radio pour aller voir à l’intérieur du corps et permettre de diagnostiquer une maladie, une fracture ou une anomalie. Vous l’aurez compris, l’approche est exactement la même pour nos applications. Nous avons besoin de savoir ce qu’il se passe à l’intérieur en cas de problème.
Un APM (Application Performance Monitoring) va permettre de profiler le code de l’application durant l’exécution. Concrètement, il va instrumenter le code applicatif pour le monitorer. Nous connaitrons ainsi le temps passé dans chaque méthode. Dans ce cas précis, nous avons choisi d’utiliser l’APM open source Glowroot. Cet APM n’a rien à envier aux grands acteurs du marché tant il est simple d’utilisation et pertinent dans les informations remontées avec un impact sur les performances très faible. Un ensemble de plugins pré-installés, tel que Hibernate et Spring, permettent de très rapidement localiser la source du problème. Contrairement à des outils comme JProfiler qui sont activés à la demande, les APM sont destinés à être actifs en permanence. Il est ainsi facile de les consulter à postériori lorsqu’un problème est survenu.
La plupart des APM, tel que Glowroot, permettent d’ajouter de l’instrumentation dynamiquement dans le code sans redémarrage du serveur. Nous pouvons donc préciser les zones de code à monitorer et compléter l’information extraite avec les paramètres de méthode, la valeur retournée, la durée et le nombre d’appel, etc.
Une fois cette étape effectuée, il nous restait encore toutefois un problème à résoudre puisque Glowroot ne nous offrait pas une vision transversale à toutes les applications, mais seulement une vision centrée sur une application. Il était donc difficile de suivre un traitement impliquant plusieurs microservices et de déterminer facilement dans quel microservice le temps était passé.
Microservices, comment avoir une vision transversale ?
Comme expliqué au début de cet article, nous étions dans une démarche de migration d’un monolithe en une multitude de microservices. Un traitement déclenché par un utilisateur va appeler en cascade une multitude de microservices, et dans certains cas du parallélisme pour accélérer le traitement. Pour tracer ces appels, nous utilisons des outils de monitoring de type « tracing ».
Ce type de monitoring est encore jeune et des standards se mettent en place avec OpenTelemetry. En effet, l’objectif est de tracer le traitement quel que soit la technologie (java, javascript, .Net,…) et le protocole utilisé (http, amqp, …). Nous avons fait le choix d’utiliser Jaeger en raison de sa popularité. Dans notre cas, le code a dû être adapté pour assurer la propagation du contexte. De plus, pour les traitements critiques tel que la valorisation d’un portefeuille, nous avons enrichi les traces pour connaitre le temps passé dans chaque étape métiers.
Jaeger nous permettait de savoir précisément le temps passé dans chaque service, de le visualiser et d’en extraire le chemin critique, ainsi que de comptabiliser le nombre d’appels à un autre service.
Ce type d’outil est décisif lors de la migration d’un monolithe en microservice. En effet, dans un monolithe un traitement qui déclenche 1000 appels à une méthode de calcul passe inaperçu. En revanche si cette méthode de calcul est migrée dans un microservice, nous allons avoir 1000 appels http et il faudra revoir le code pour conserver les performances initiales et ne pas stresser le micro-services.
A ce stade, nous avions alors un beau panel d’outils de monitoring prêts à investiguer le moindre incident. Encore fallait-t-il savoir quand nous avions un incident… Une solution est de scruter régulièrement les dashboards, mettre un écran dans l’openspace pour toujours garder un œil dessus. Une autre solution moins contraignante est de configurer des alertes afin d’être notifié en cas de disfonctionnement.
Alertes
Mettre en place des alertes n’est pas aussi évident qu’il n’y parait…
Eviter les faux positifs
Une alerte se déclenche sur une règle. Nous n’allons pas rentrer dans les détails sur les bonnes pratiques pour établir cette règle, mais il faut garder à l’esprit qu’il faut toujours éviter de déclencher des fausses alertes, au risque de rapidement perdre confiance dans la pertinence de l’alerte qui sera alors perçue comme un spam. La règle de l’alerte doit être régulièrement adaptée pour éviter des faux positifs.
Qui doit recevoir l’alerte ?
Les personnes qui doivent recevoir l’alerte sont en priorité les personnes qui sont aptes à agir pour rétablir la situation. Il est aussi pertinent d’ajouter les personnes souhaitant être informées de l’état du système.
Que devons-nous faire ?
Déclencher une alerte est une bonne chose à condition de savoir comment elle doit être prise en charge. Un processus clair doit être défini et formalisé. Au minimum, je conseille d’informer dans le message d’alerte les conséquences de celle-ci et les actions possibles à réaliser.
Outil
Les alertes se font principalement sur des métriques. Prometheus et Grafana sont aptes à déclencher des alertes. J’ai toutefois une préférence pour Grafana car il permet nativement d’avoir le lien sur le dashboard correspondant à la métrique dans le rouge dans la notification.
Formation
Ces outils de monitoring sont destinés à être utilisés par les devs et les ops. Ils doivent avoir accès à ces outils et bien sûr les comprendre. Pour cela, il est essentiel qu’ils en prennent connaissance et se forment dessus. Nous avons mis en place des sessions courtes de formation d’environ 30 min une fois par semaine sur 8 semaines.
Conclusion
Dans ce retour d’expérience, nous avons pu appréhender un ensemble d’outils issus du monde open source. Ceux-ci se sont avérés particulières fiables et robustes. Seuls quelques bugs très mineurs ont été rencontrés sur Grafana.
Aujourd’hui, ils nous apportent une aide précieuse pour comprendre le comportement de nos applications, anticiper les problèmes et bien sûr l’analyse d’incidents. Malheureusement, encore beaucoup de sociétés n’ont pas fait le pas pour mettre en place du monitoring applicatif et se limitent à du monitoring d’infrastructure. Sans eux, la résolution de problème s’avère compliquée et hasardeuse. Dans le pire des scénarios, elle est parfois impossible.
Le choix d’outil est aussi fortement contraint par le budget. Certains outils peuvent devenir rapidement très coûteux en fonction de leur utilisation. Un autre critère pour le choix est de vouloir ou pouvoir exporter ces métriques et logs dans le Cloud. Des solutions de monitoring, comme Datadog, sont purement Cloud et aucun déploiement sur site n’est alors possible.
Il faut savoir que le monde des outils de monitoring est en pleine expansion. Les grands acteurs redoublent d’investissement dans leurs outils pour répondre à ce marché prometteur. Un des champs de bataille est l’introduction d’Intelligence Artificielle pour faciliter la recherche de la cause d’un incident ou pour le déclenchement d’alerte. A suivre…