Taille de texte par Defaut
Agrandir la Taille du Texte
Réduire la Taille du Texte
Options d'accessibilité
Informatique

Au secours, il me faut des logs !

itk IT
21 juin 2016
Pas de commentaires

Vous utilisez Spring-mvc pour vos contrôleurs REST et Spring-security pour l’accès à votre couche de services ? Nous allons décrire comment ajouter rapidement des logs serveurs pour monitorer les actions de vos utilisateurs. Car enfin, le grand jour est arrivé : votre application est prête, elle est belle, elle est packagée, elle est déployée, et vous diffusez fièrement son adresse à une horde de nouveaux utilisateurs impatients.

Petit bémol, vous avez négligé d’analyser ce qu’allaient être les logs de votre application, et vous vous retrouvez impuissant devant certaines remontées de bugs utilisateurs.

Voici un petit pansement qui vous aidera tant que le nombre de vos utilisateurs n’est pas très gros et qu’ils ne sont pas trop gourmands.

Des logs via de la programmation par aspect

Si vous utilisez spring-mvc vous avez sûrement annoté toutes les classes de votre couche controlleur @RestController. Nous allons utiliser spring-aop pour intercepter leurs méthodes.

Commencez par créer un aspect comportant deux PointCuts pour intercepter d’une part les méthodes publiques, d’autres part les méthodes issues d’un bean spring annoté @RestController :

@Aspect
@Component
public class ControllerLog {

    @Pointcut("execution(public * *(..))")
    public void publicMethod() {}

    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void beanAnnotatedWithRestController() {}

}

On continue avec un advice @Before dont le code sera exécuté juste avant nos controlleur. Nous allons utiliser le SecurityContextHolder de Spring-security pour récupérer l’utilisateur courant, puis construire la liste des arguments passés en paramètre.

    private static final Logger LOG = LoggerFactory.getLogger(ControllerLog.class);

    private static final String SPACE = " ";
    private static final String LOG_PATTERN = "{} executing {} ({})";

    @Before("publicMethod() && beanAnnotatedWithRestController()")
    public void controllerMethod(JoinPoint jp) {
        Authentication loggedUser = SecurityContextHolder.getContext().getAuthentication();
        StringBuilder argumentList = new StringBuilder().append(SPACE);
        for (Object argument : jp.getArgs()) {
            argumentList.append(argument).append(SPACE);
        }
        LOG.info(LOG_PATTERN, loggedUser.getName(), jp.getSignature().toShortString(), argumentList.toString());

    }

Il vous suffit maintenant d’annoter votre classe de configuration Spring de @EnableAspectJAutoProxy pour activer les aspects, de configurer intelligemment logback et le tour est joué.

Le résultat : des utilisateurs tracés à la loupe

Suivant l’état de votre configuration logback, de vos méthodes toString() et de votre application, vous allez obtenir quelque chose de ce style :

c.i.w.w.a.ControllerLog [ControllerLog.java:37] anonymousUser executing AuthenticationController.login(..) ( model.Login@7dd8620 org.springframework.security.web.firewall.FirewalledResponse@5727a8ad 
c.i.w.w.a.ControllerLog [ControllerLog.java:37] Advisor [id=70929, username=bob] executing MyController.get(..) ( 1409 )
c.i.w.w.a.ControllerLog [ControllerLog.java:37] Advisor [id=70929, username=bob] executing ApplicationController.getApplications(..) ( 330366 )
c.i.w.w.a.ControllerLog [ControllerLog.java:37] Advisor [id=70929, username=bob] executing SimulationController.getSimulation(..) ( 1484 )

C’est verbeux, mais vous allez pouvoir tracer vos utilisateurs de manière très (trop ?) fine.

Une fausse bonne idée !

Nous avons évidemment décrit ici un pansement qui fera l’affaire juste un temps. Quand votre application sera vraiment utilisée, cette technique aura le double désavantage de :

  • ralentir considérablement votre application
  • surcharger considérablement vos logs

Pour palier ces problèmes, vous pouvez utiliser les @Profile Spring, le rechargement à chaud de la configuration de logback, voire une intelligente combinaison des deux. Le mieux étant d’établir une vraie politique de logging dans vos applications.

Commentaires 0

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *