JAMon est une API qui permet de monitorer les applications Java (http://jamonapi.sourceforge.net/). Couplé avec Spring AOP, on peut facilement connaître le temps d'exécution d'une méthode ou le temps d'accès à une page. On peut aussi connaître le coût des requêtes SQL. Nous allons procéder en 2 étapes :
  1. Mise en place "globale" de JAMon.
  2. Paramétrer l'application pour définir les éléments dont on souhaite mesurer les temps d'exécution.

Mise en place "globale" de JAMon

Voici comment mettre en oeuvre JAMon dans une application J2EE avec Spring :
  1. Télécharger JAMon ici : http://sourceforge.net/project/showfiles.php?group_id=96550.
  2. Ajouter jamon-2.7.jar dans les lib de de l'application.
  3. Décompresser le WAR (jamon.war) et récupérer la JSP jamonadmin.jsp. Copier aussi les lib fdsapi.jar, hsqldb.jar et jakarta-ora.jar présentes dans WEB-INF/lib dans les lib de l'application. Cela permet de faire fonctionner la JSP jamonadmin.jsp dans l'application.

Paramétrer l'application pour définir les éléments dont on souhaite mesurer les temps d'exécution

La 2e étape est de paramétrer son application pour qu'elle transmette des données à JAMon. 3 possibilités :
  1. Ajouter un filtre de servlet à l'application pour suivre le temps d'appel aux pages.
  2. Utiliser la POA pour appeler les moniteurs JAMon et suivre le temps d'exécution de certaines méthodes.
  3. Utiliser un proxy JDBC pour suivre le temps d'exécution des requêtes SQL.

Suivre le temps d'appel aux pages

Le principe est le suivant : on ajoute un filtre de servlet afin de mesurer le temps d'appel à chaque page.
Ajouter les lignes suivantes dans le fichier web.xml :
<filter>
<filter-name>JAMonFilter</filter-name>
<filter-class>com.jamonapi.JAMonFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>JAMonFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Attention, ces lignes doivent être ajoutées juste après la balise <display-name>.

Suivre le temps d'exécution de certaines méthodes

Pour éviter de modifier son code source, l'idée est d'utiliser la classe JamonPerformanceMonitorInterceptor fournie par Spring. Pour connaitre dans le détail comment définir un intercepteur avec Spring, le mieux est de se référer à la documentation (http://static.springframework.org/spring/docs/2.5.x/reference/aop.html et http://static.springframework.org/spring/docs/2.5.x/reference/aop-api.html). Voici un exemple simple pour connaitre le temps d'exécution des méthodes publiques du bean "monBean".
Créer un fichier applicationContext-monitoring.xml avec le code suivant :
<beans>
<bean id="jamonPerformanceMonitorInterceptor" class="org.springframework.aop.interceptor.JamonPerformanceMonitorInterceptor">
<property name="trackAllInvocations">
<value>true</value>
</property>
</bean>
<bean name="serviceProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="monBean"></property>
<property name="interceptorNames">
<list>
<value>jamonPerformanceMonitorInterceptor</value>
</list>
</property>
</bean>
</beans>
Attention, la propriété trackAllInvocations est importante car le monitoring n'est actif que si les logs sont activés OU si cette propriété est à true. Donc, pour garantir que le monitoring est activé même si les logs ne sont pas actifs, il faut la positionner à true (la valeur par défaut est false). Extrait de la Javadoc de cette méthode :
"Set whether to track all invocations that go through this interceptor, or just invocations with trace logging enabled. Default is "false": Only invocations with trace logging enabled will be monitored. Specify "true" to let JAMon track all invocations, gathering statistics even when trace logging is disabled."

Suivre le temps d'exécution des requêtes SQL

L'idée ici est d'encapsuler le driver JDBC dans le driver JAMon. Exemple avec Hibernate. Dans le fichier hibernate.cfg.xml
  • Remplacer le driver comme suit :
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
par
<property name="hibernate.connection.driver_class">com.jamonapi.proxy.JAMonDriver</property>
  • Remplacer l'url de connexion :
<property name="hibernate.connection.url">jdbc:mysql://localhost/maBD</property>
par
<property name="hibernate.connection.url">jdbc:jamon:mysql://localhost/maBD?jamonrealdriver=com.mysql.jdbc.Driver</property>