Skip to content

Logging (FR)

mekor-dev edited this page Sep 29, 2020 · 6 revisions

Introduction

Le projet utilise SL4J avec l'implémentation par défaut de Wildfly (log4J).
Je décris ici mes bonnes pratiques. Bien évidemment, ce sont les miennes, et ne sont pas forcément parfaites.

Configuration

Le logger est configuré dans le fichier /src/main/resources/lo4j.properties.
Il est également possible de le configurer dans le standalone.xml de Wildfly et d'ignorer ce fichier afin d'avoir une configuration propre a l'environnement.

Utilisation

@Inject
private Logger log;

public void hello(){
   log.debug("Entering hello");
}

Evitez d'hériter le logger d'une classe à l'autre. Vous perdrez l'information de la classe associée au logger.

Bonnes pratiques

Log level

En production, seuls les logs INFO, WARN et ERROR sont affichés. J'utilise les logger de la manière suivant :

  • DEBUG : Utilisé pour l'entrée et sortie de méthode et tout information utile au développeur (hors production).
public String printDocument(Document doc, Mode mode) {
    log.debug("Entering printDocument(doc={}, mode={})", doc, mode);
    String id = //Lengthy printing operation
    log.debug("Leaving printDocument(): {}", id);
    return id;
}
  • INFO : Utilisé lorsqu'un processus important, dont on désire avoir l'information en production, a lieu. ex : Lancement du serveur et affichage des paramètres de l'applications
  • WARN : Utilisé lorsqu'une erreur non critique ou gérée à lieu, qui ne bloque pas le processus. ex : Connection échouée pour mauvais mot de passe / Mauvais format de données entrantes d'un web-service.
  • ERROR : Sera utilisé lorsqu'une erreur non prévue à lieu et empêche le déroulement de la suite du processus. Notamment les exceptions
  • FATAL : Sera utilisé lorsqu'une erreur stoppe totalement le fonctionnement de l'application (Très rare en web).

De la bonne utilisation du logger

  • Il est important de logger le plus d'information UTILE possible (pas trop non plus donc).
  • Les logs doivent être compréhensibles par tous (surtout les logs d'un niveau supérieur à DEBUG) et concis.
  • Il est important de logger le message ET les paramètres sur le même appel pour éviter de perdre les paramètres dans le flot d'utilisateurs en production.

Personnellement, j'arrive à me passer du debugger depuis que je fais attention à mes logs.

Log paramétrisé

Ne pas utiliser de concaténation. En effet, celles-ci sont évaluées avant l'appel de la méthode et donc construites MEME SI le log level n'est pas activé.

log.info("user " + username + "is now logged); // BAD
log.info("user {} is now logged", username); // GOOD

Log avec un paramètre complexe (toString)

Dans le cas ou l'on veut logger un objet complexe, il faut surcharger la méthode toString(), pour afficher, par exemple, l'objet en JSON et passer l'objet lui même en paramètre du logger (pas la méthode toString() !)
Cela permet de n'exécuter la méthode toString() que lorsque le mode debug est activé.

log.info("{}", user.toString()); // BAD - Le toString() sera executé même si le log level n'est pas activé
log.info("{}", user); // GOOD - Le toString n'est executé qu'après vérification du log level

Log avec un paramètre complexe (méthode lourde)

Dans le cas ou l'on veut logger le résultat d'une méthode lourde, qui n'est pas toString(), surtout si ce log est appelé souvent, il faut vérifier que le log level est activé avant:

if (log.isDebugEnabled()) {
  log.debug(user.heavyprocess());
}

Éviter les NPE

Une NPE dans le paramètre d'un log arrêtera tout le processus. C'est clairement à éviter.

log.debug("user with name {} is connecting", user.getUsername()); // À éviter. sauf si on est sûr que user n'est pas null
log.debug("user {} is connecting", user); // Mieux

Log d'une exception

Logger l'exception en ERROR ou FATAL et faire attention à ce que l'exception se trouve dans le dernier paramètre. Et non en tant que paramétrisation de la chaîne de caractères.

log.error("exception : {}", e); // BAD
log.error("exception", e); // GOOD
log.error("exception while logging user {}", user, e); // GOOD

Paramétrage du logger

Un nouveau fichier de log sera créé chaque jours en production.

Le logger sera paramétré pour contenir les infos suivantes :

  • Date et heure (sans précision en millisecondes)
  • Nom du serveur
  • Nom simple de la classe
  • ID de thread ou de requête
  • Message de l'utilisateur
  • Exception si elle existe

Ressources

https://stackify.com/java-logging-best-practices/ https://dzone.com/articles/9-logging-sins-in-your-java-applications https://www.javacodegeeks.com/2011/01/10-tips-proper-application-logging.html

Clone this wiki locally