Plutôt que de mettre des logs dans toutes nos fonctions et d'utiliser uniquement le paramétrage de log4J pour changer le niveau d'affichage des logs, nous allons utiliser un des composants de Spring permettant la mise en place d'intercepteurs pour exécuter du code complémentaire: Spring AOP
Dans cet article, nous allons journaliser les appels de méthodes de chaque fonction, le temps d'exécution et les retours des méthodes. Afin de clarifier un point qui doit tout de suite vous venir à l'esprit, cette journalisation est effectivement relativement gourmande en temps d'exécution: analyse des intercepteurs, exécution du code supplémentaire, écriture fichier des logs, ... Nous ne mettrons donc en place ce système que sur des cas précis: analyse en développement, pistage en recette. Nous verrons qu'il est relativement simple de désactiver ce mécanisme de logs par paramétrage.
La mise en place d'un tel système va demander quelques opérations:
- Mise en place de Spring dans votre projet (nous considérons que c'est déjà fait)
- Ajout de Spring AOP et AspectJ
- Mise en place des intercepteurs et du code à exécuter
- Paramétrage du listener de Spring
Ajout de Spring AOP et AspectJ
Deux possibilités:
- si vous utilisez maven, vous aurez besoin de 2 dépendances:
Vous devez également avoir les librairies de log4J pour la journalisation.
Mise en place des intercepteurs et du code à exécuter
Nous allons maintenant créer une classe LoggerAop ainsi que le paramétrage des intercepteurs et du code à exécuter pour chaque méthode.
Dans cette classe, nous allons maintenant ajouter une méthode qui sera exécutée à chaque interception. Avant tout chose, nous définissions un logger log4J:
Voici la signature de la méthode et le paramétrage de l'intercepteur:
Paramétrage du listener de Spring
Nous isolons le paramétrage des points d'interceptions dans un fichier spécifique. Cela nous permettra de le charger ou non suivant l'environnement: dev, recette ou production. Pour cela, il faut créer un fichier spring-aop.xml dans le répertoire WEB-INF et voici le contenu:
Stéphane Barthon
- si vous utilisez maven, vous aurez besoin de 2 dépendances:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${org.aspectj.verision}</version>
</dependency>
Vous devez également avoir les librairies de log4J pour la journalisation.
Mise en place des intercepteurs et du code à exécuter
Nous allons maintenant créer une classe LoggerAop ainsi que le paramétrage des intercepteurs et du code à exécuter pour chaque méthode.
@Component
@Aspect
public class LoggerAop {
...
}
Dans cette classe, nous allons maintenant ajouter une méthode qui sera exécutée à chaque interception. Avant tout chose, nous définissions un logger log4J:
private final Log myLogger = LogFactory.getLog(this.getClass());
Voici la signature de la méthode et le paramétrage de l'intercepteur:
@Around("execution(* fr.mycompany..*.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
...
}
// Mise en place d'un timer pour logger le temps d'exécution
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Exécution de la méthode interceptée
Object retVal = joinPoint.proceed();
// Arrêt du timer
stopWatch.stop();
// construction du message de log avec:
// la classe, la signature de la méthode, le temps d'exécution
//les paramétres en entrée et en sortie
StringBuffer logMessage = new StringBuffer();
logMessage.append(joinPoint.getTarget().getClass().getName());
logMessage.append(".");
logMessage.append(joinPoint.getSignature().getName());
logMessage.append("(");
// Ajout des paramètres en entrée
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
logMessage.append(args[i]).append(",");
}
if (args.length > 0) {
logMessage.deleteCharAt(logMessage.length() - 1);
}
logMessage.append(")");
logMessage.append(" execution time: ");
logMessage.append(stopWatch.getTotalTimeMillis());
logMessage.append(" ms");
myLogger.info(logMessage.toString());
if (retVal != null) {
myLogger.info("returned value = " + retVal.toString());
}
return retVal;
Paramétrage du listener de Spring
Nous isolons le paramétrage des points d'interceptions dans un fichier spécifique. Cela nous permettra de le charger ou non suivant l'environnement: dev, recette ou production. Pour cela, il faut créer un fichier spring-aop.xml dans le répertoire WEB-INF et voici le contenu:
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<aop:aspectj-autoproxy/>
</beans>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml,WEB-INF/context-security-osgi.xml,WEB-INF/context-jmx.xml,WEB-INF/context-aop.xml</param-value>
</context-param>
Stéphane Barthon
Aucun commentaire:
Enregistrer un commentaire
Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.