Applications et méthodes de monitoring Java

Fiche ressource Article, événement, site web...
  • Création ou MAJ importante : 19/09/13
  • Correction mineure : 19/09/13
Mots-clés

Applications et méthodes de monitoring Java

  • Type de ressource : article, référentiel, résumé
  • Date de publication du document ou de l'événement : Avr 2013
  • Auteur(s) ou responsable(s) : Stéphane Deraco
  • Contact pour plus d'informations : java@services.cnrs.fr

Que faut-il surveiller ?

Surveiller une application peut vouloir dire plusieurs choses selon les besoins et le contexte de l'application. Par exemple, une application contrôlant un élément d'un accélérateur de particules ne sera pas surveillée de la même manière qu'une application chargée d'envoyer un mail dès qu'une page d'un wiki est modifiée.

La surveillance peut être technique (est-ce que mon application fonctionne correctement, est-ce que les performances sont acceptables, combien y a-t-il d'utilisateurs en ce moment) ou fonctionnelle (combien de factures ont été traitées ce mois-ci, pour quel montant).

Quels outils pour surveiller ?

Les outils de surveillance d'une application Java peuvent se diviser en deux catégories : les outils fournissant des données instantanées, et les outils permettant de conserver un historique des données, certains outils fournissant les deux.

Beaucoup d'outils utilisent la fonctionnalité JMX, qui permet d'exposer des informations via des MBeans.

Logs

La mise en place de logs est le minimum à faire dès lors que l'on souhaite surveiller une application.

La solution la plus basique est d'utiliser la méthode System.out.println pour écrire les lignes de logs dans la console. Le problème avec cette solution est qu'elle n'est pas évolutive : on ne peut pas choisir les niveaux de logs, ni quels composants logger.

C'est pour cela que l'on utilise un cadriciel (framework) de log. Les plus courants sont les suivants :

  • JUL (java.util.logging) : c'est le framework de logs implémenté dans la JVM. Il n'est pas beaucoup utilisé, car il n'a été introduit dans Java qu'à partir de la version 1.4.
  • Apache Log4J : c'est l'un des framework de logs les plus utilisés.
  • Logback : c'est un framework écrit par l'auteur de Log4j, qui apporte des améliorations par rapport à ce dernier.
  • Apache Commons Logging et SLF4J : ce sont des façades permettant de choisir l'implémentation de logs. L'utilisation de façade est utile car dans un projet Java utilisant plusieurs librairies tierces, chacune peut utiliser un framework de logs différent. La façade permet d'unifier cela.

Les avantages à utiliser un framework de logs sont les suivants :

  • Pouvoir choisir le niveau de logs à logger.
  • Pouvoir choisir, composant par composant, quel est le niveau de logs.
  • Les données loggées ont ainsi des priorités différentes.
  • Possibilité d'utiliser des destinations différentes pour les logs (fichiers, base de données, JMS, etc).

Avoir une librairie de logs ne suffit pas pour pouvoir surveiller efficacement son application Java. Le choix de ce qu'il faut logger est très important. Il n'en faut pas trop pour ne pas noyer les informations importantes, ni trop peu pour en avoir assez.

Il peut être intéressant d'avoir plusieurs destinations de fichiers de logs, selon les besoins :

  • un fichier full qui contient tous les logs,
  • un fichier securité contenant les logs relatifs à la sécurité (tentatives de connexions, actions sensibles, etc.),
  • un fichier audit pour pouvoir tracer les événements qui surviennent dans l'application.

Il est intéressant de noter que la destination des logs peut être autre chose que des fichiers, et qu'un même message de logs peut être envoyé vers plusieurs destinations. La plupart des librairies de logs permettent d'envoyer les logs en base de données, sur une file d'attente JMS, sur une socket, par mail ou encore sur le système de log Linux syslog. Cependant, il faut en général toujours envoyer les logs critiques au moins dans un fichier, pour être sûr qu'ils soient disponibles (une base de données peut ne pas être montée, le broker JMS peut être saturé, etc.).

L'utilisation de logs permet de surveiller ce qui se passe en temps quasi réel, mais aussi d'accéder à l'historique.

JMX

http://fr.wikipedia.org/wiki/JMX

JMX est une spécification Java permettant d'exposer des MBeans présents dans la JVM. Un MBean est simplement une classe Java exposant des getters et des méthodes.

Cela permet par exemple d'accéder à des attributs de la JVM tels que le temps total de compilation. On peut également appeler des méthodes.

Il est donc possible d'ajouter dans notre programme Java des MBeans afin de les exposer via JMX. Cela permet de remonter des valeurs, ou d'appeler des méthodes de notre programme. Par exemple, Tomcat expose les MBeans User, Role, mais aussi le nombre de requêtes pour chaque servlet. On peut également stopper un port donné, expirer une session, etc.

Utiliser JMX dans une application Java permet donc facilement, avec les outils adéquats, d'interagir avec l'application et de surveiller ce qui se passe dans la JVM, aussi bien au niveau technique qu'au niveau fonctionnel (il suffit d'écrire les MBeans correspondant).

La plupart des outils suivants se basent sur JMX pour remonter les informations.

JConsole

http://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html

JConsole est présent dans le JDK. C'est une interface graphique affichant des graphes décrivant le fonctionnement de la JVM. On y trouve par exemple un graphe affichant la mémoire Heap utilisée, le nombre de threads actifs, ou encore le pourcentage d'utilisation du CPU.

JConsole permet également de consulter les MBeans exposés par la JVM.

JConsole permet de se connecter à une JVM locale, mais également à une JVM distante (il faut effectuer une configuration au niveau de la JVM distante).

Dans le cas où le réseau bloque les ports empêchant JConsole de se connecter à une JVM distante, il est possible d'utiliser un tunnel SSH. Pour cela, on peut utiliser PuTTY :

  • Aller dans la section Connection/SSH/Tunnels, puis dans Add new forwarded port, renseigner un numéro de port quelconque dans Source port (ce sera le port du proxy SOCKS), puis sélectionner Dynamic.
  • Cliquer sur Add. Dans le tableau au dessus, une ligne doit s'ajouter avec le numéro de port préfixé par la lettre D.
  • Se connecter au serveur distant en SSH avec PuTTY.
  • Lancer JConsole avec la commande suivante : jconsole.exe -J-DsocksProxyHost=localhost -J-DsocksProxyPort=10000 (avec 10000 le port renseigné dans PuTTY).

JConsole permet de voir ce qui se passe à un instant donné dans l'application, mais ne permet pas de consulter l'historique. JConsole ne conserve que l'historique depuis son démarrage.

JVisualVM

http://docs.oracle.com/javase/7/docs/technotes/tools/share/jvisualvm.html

JVisualVM est également présent dans le JDK. Il reprend les fonctionnalités de JConsole sur l'affichage de graphes sur les mesures internes de la JVM.

JVisualVM ne permet pas de base d'accéder aux MBeans de la JVM. Cependant, il a un mécanisme de plugins qui permet de rajouter un onglet MBeans (VisualVM-MBeans) offrant les mêmes fonctionnalités que JConsole.

De plus, d'autres plugins sont intéressants :

  • Visual GC : affichage précis des différents pools de mémoire de la JVM, ainsi que les temps utilisés par le Garbage Collector.
  • Tracer-JVM Probes : sondes permettant d'afficher des graphes sur des comportements internes de la JVM (utilisation des Collections, les buffers NIO, etc.).

JVisualVM permet de se connecter à une JVM locale, mais également à une JVM distante (il faut effectuer la même configuration au niveau de la JVM distante que pour JConsole).

Dans le cas où le réseau bloque les ports empêchant JVisualVM de se connecter à une JVM distante, il est possible d'utiliser un tunnel SSH de la même manière que pour JConsole. Il suffit, après avoir activé le proxy SOCKS, d'aller dans JVisualVM dans le menu Tools > Options > Network (proxy SOCKS).

JVisualVM permet de voir ce qui se passe à un instant donné dans l'application, mais ne permet pas de consulter l'historique. JVisualVM ne conserve que l'historique depuis son démarrage.

JMX Term

http://wiki.cyclopsgroup.org/jmxterm

C'est un outil en ligne de commande permettant d'accéder aux MBeans. L'avantage c'est que l'on peut l'utiliser même si on n'a pas d'interface graphique (sur un serveur Linux sans X11 par exemple). Il est fourni sous forme d'un Jar exécutable.

Une fois le Jar lancé, on se connecte à une JVM locale, puis on navigue dans les domaines et les MBeans, pour enfin afficher les valeurs, les renseigner, ou appeler des méthodes.

JMX Term offre également la possibilité d'être utilisé via des outils de scripts, tels que Perl ou un shell. Voici par exemple un extrait du site de JMX Term :

open JMX, "| java -jar $jar -n";

 print JMX "help \n";

 my $host = "localhost";

 my $port = 9991;

 print JMX "open $host:$port\n";

 print JMX "domains\n";

 print JMX "close\n";

 close JMX;

JMX Term ne conserve pas d'historique.

jmxtrans

https://github.com/jmxtrans/jmxtrans

Cet outil a pour objectif d'extraire des informations de différentes JVMs, puis de les envoyer vers d'autres outils pour leur traitement. Il a pour vocation d'être performant avec un grand nombre de JVMs à analyser.

Il fonctionne en tâche de fond. Une fois lancé, il lit des fichiers de configuration écrits en JSON ou YAML, dans lesquels sont décrits les serveurs à analyser, le port JMX, les objets MBeans à interroger, et la façon dont envoyer les données des MBeans.

Par exemple, il est possible de lui demander d'interroger le MBean java.lang:type=OperatingSystem, et de récupérer les valeurs des attributs SystemLoadAverage et FreePhysicalMemorySize, puis d'envoyer ces valeurs dans un fichier texte.

La façon dont JMXTrans traite les données récupérées se fait par la notion de Writer. Il existe des Writers pour écrire les données sur la console, dans un fichier texte, mais aussi vers Graphite (outil web de visualisation de données), ou encore vers des fichiers de type RRD (utilisés entre autre par Nagios, Cacti).

JMXTrans permet donc de surveiller un ensemble de JVMs (sur des attributs de notre choix), et d'envoyer ces données à d'autres outils pour affichage ou analyse.

Par sa nature, JMXTrans permet de conserver l'historique : il tourne en tâche de fond, et les Writers accumulent les données reçues. C'est à la charge des outils externes (Graphite, Nagios, etc.) d'afficher ces données historisées.

Jolokia

http://www.jolokia.org/

Cet outil permet de récupérer les données des attributs de MBeans par des services web REST. Il se greffe dans une JVM et est ensuite interrogeable par une URL, dans laquelle on indique les MBeans à interroger (pour récupérer des valeurs d'attributs, ou appeler des méthodes). Le format retourné par l'URL est du JSON.

La façon d'intégrer Jolokia dans une JVM peut se faire de différente manière : via un war à mettre dans Tomcat, un bundle OSGi, ou un agent Java (spécifié dans la commande java lançant l'application).

Jolokia permet donc de faciliter l'interrogation d'une JVM pour obtenir des données sur son fonctionnement. Il est ensuite facile d'utiliser un autre outil tel que Nagios pour automatiser la récupération d'informations via Jolokia.

Jolokia fournit un instantané de ce qui se passe dans la JVM, c'est à la charge des outils qui l'utilisent d'historiser les données.

HawtIO

http://hawt.io/

C'est une webapp déployable sous un conteneur de servlet (Tomcat par exemple), qui permet de se connecter à une JVM locale ou distante (la connexion à une JVM distante se fait en utilisant Jolokia - Jolokia doit donc être installé sur la JVM distante).

HawtIO met à disposition une interface web permettant de consulter les données exposées (par JMX ou Jolokia) d'une JVM. Il est possible de consulter les données, mais également d'afficher des graphes pour des données numériques.

Ce projet est en plein développement, mais semble prometteur. Il a un système de plugin permettant d'afficher des vues spécifiques selon les frameworks utilisés dans la JVM. Par exemple, s'il détecte qu'il y a le broker ActiveMQ, alors il va rajouter un onglet spécifique facilitant la consultation des données du Broker. De même, si Tomcat est détecté, alors un onglet dédié permettra d'arrêter des applications, de voir les sessions, etc.

HawtIO permet de grapher les données numériques, mais l'historique se limite à la durée de connexion à HawtIO.

YourKit & JProfiler

http://www.yourkit.com/

http://www.ej-technologies.com/products/jprofiler/overview.html

Ces deux outils permettent, comme JConsole et VisualVM, de se connecter à une JVM locale et distante, et d'afficher des informations sur cette JVM.

La force de ces outils est de proposer des méthodes pour détecter ce qui consomme le plus de ressources dans le programme.

Notamment, la détection de fuites mémoire est grandement facilitée avec ces outils, qui montrent le nombre d'instances de chaque objet, et quels sont les objets qui gardent une référence sur ceux-ci, empêchant le garbage collector de les supprimer.

Eclipse MAT

http://www.eclipse.org/mat/

Cet outil est assez similaire dans les objectifs à YourKit et JProfiler, mais il fonctionne sur un Heap Dump. C'est à dire que son utilisation est plutôt post mortem.

Cette page explique comment générer un Heap Dump sur une application existante, et quels paramètres fournir à Java pour qu'il génère automatiquement un Heap Dump en cas de OutOfMemoryError. Cela permettra d'analyser a posteriori les causes d'une fuite mémoire sur un système en production.

Apache JMeter & Gatling

http://jmeter.apache.org/

http://gatling-tool.org/

Ce sont des outil de tests de performance, permettant de tester la résistance d'applications sous différents cas d'utilisation. Les tests de performances peuvent être de différents types, par exemple : tests de charge, tests de stress, tests d'endurance, etc. Cette page explique les différents types de tests.

Ils ne permettent pas d'analyser directement le fonctionnement d'une JVM (ni en cours de fonctionnement, ni à partir d'un Heap Dump), mais ils permettent de s'assurer que notre application (Java ou autre) réponde bien à différents scénarios. Ils produisent par contre des rapports et des graphiques permettant de s'assurer que notre application répondra correctement dans ces cas d'utilisation.

Commentaires

YourKit

Bonjour,
parmi les logiciels cites, j'ai utilise YourKit.

Je ne saurai que trop le recommander: il a ete particulierement utile pour la detection des fuites de memoire (heee oui, il y a des fuites de memoires en java).

Il est payant, mais abordable. On peut aussi commencer a l'utiliser gratuitement quelques semaines. Il n'y a aucune restriction dans les fonctionnalites pendant la periode d'essai.