Vous l’avez compris, dans mon précédent articleLogback était un prétexte pour présenter une manière détournée d’utiliser mon outil fétiche de manipulation de données. Avec peu de suspens, si j’ai le choix du Framework de logging, je partirais sur Logback, pour des raisons qui ne concernent d’ailleurs pas les performances.

Et, puisque j’ai lancé le sujet, voilà quelques arguments comparatifs issus de mes premiers essais :

Ecriture du fichier de configuration

Dans Log4J, pour paramétrer un logger, tout est « param » :

1
2
3
<param name="File" value="/tmp/log4j.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="1MB" />

Dans Logback, c’est le nom de l’attribut XML qui détermine le paramètre :

1
2
3
4
5
<file>/tmp/logback.log</file>
<append>true</append>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
	<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>

Dans les deux cas, les mécanismes sont similaires : l’API va utiliser les informations (la valeur de l’attribut « param » pour Log4J, le nom de la balise pour Logback), afin de déterminer par réflexion quels setters apeller.

La syntaxe Log4J a un avantage : le fichier de configuration peut être contrôlé par une DTD, ce qui n’est pas possible avec Logback.

Mais la syntaxe Logback a deux avantages :

  • Le premier est purement esthétique : la façon d’écrire le fichier de configuration est plus agréable et moins verbeuse
  • Le deuxième est que cette syntaxe est beaucoup plus puissante. Alors que dans Log4J, tous les paramètres d’un Appender sont des types simples (chaînes de caractères, nombres), la syntaxe Logback autorise une imbrication illimitée de paramètres objets, pourvu qu’ils aient un constructeur vide (comme dans l’exemple ci-dessus)

Utilisation de SLF4J

SLF4J offre une couche d’abstraction permettant de changer de Framework de logging de façon transparente, puisque les classes spécifiques ne sont plus référencées dans le code. Il permet également d’accroître les performances de Logging par un certain nombre de petites optimisations. Prenons le code suivant :

1
logger.debug("Traitement du client " + client.toString());

Quel que soit le niveau de logging, la concaténation est effectuée, même si elle est inutile. Avec SLF4J, on peut écrire :

1
logger.debug("Traitement du client {}", client.toString());

La concaténation n’est effectuée que si le message doit réellement être loggué. Cela peut faire gagner un espace mémoire non négligeable en production avec des logs « INFO ».

Log4J et Logback peuvent tous deux utiliser SLF4J, mais ne sont pas égaux : Logback est l’implémentation native de SLF4J, alors que son implémentation pour Log4J est « wrappée ». De ce fait, certaines fonctionnalités sont perdues.

En particulier, le niveau de logging « FATAL » n’est pas géré par SLF4J. Sur ce point, je ne comprends pas le choix de l’équipe du projet, malgré ma lecture de leur FAQ. J’ai vu beaucoup plus de projets utiliser la distinction ERROR/FATAL que TRACE/DEBUG au niveau du logging. De plus, SLF4J se voulant une façade pour de nombreuses APIs, pourquoi restreindre les fonctionnalités de la façade sur ce point (par ailleurs très poussée sur d’autres, comme les « marqueurs ») ? Il n’aurait pas été plus difficile de créer une méthode frontale « fatal()« , quitte à la rediriger vers « error() » pour Logback.

Bref, pour résumer, lorsqu’on utilise Log4J avec SLF4J, on perd cette fonctionnalité, alors que les fonctionnalités de Logback collent exactement à celles de la façade (et pour cause). Mais relativisons : ce point n’est pas déterminant.

Les fonctionnalités

C’est certainement le plus gros atout de Logback par rapport à Log4J. Les fonctionnalités du premier sont beaucoup plus étendues.

Au niveau des « appenders » de l’API, ceux de Logback sont plus nombreux et offrent plus de possibilités :

Une option très intéressante du RollingFileAppender de Logback est, par exemple, de permettre la compression des anciens fichiers de logs au moment du roulement. Il suffit de donner un FileNamePattern se terminant par « .gz », « .zip », etc.

Et ceci est vrai également pour les autres fonctions (Filter, etc.).

Compléments

Un bref comparatif donne donc très clairement Logback gagnant. D’autres raisons de migrer son d’ailleurs données directement sur le site de ce dernier.

Enfin, pour en apprendre un peu plus sur Logback et SLF4J (et plus particulièrement les très intéressantes fonctionnalités MDC et Markers qui peuvent très largement contribuer à l’identification d’un incident lorsque correctement utilisées), je vous conseille cet article, résumant le conférence de Ceki Gülcü lors de la conférence Devoxx 2009.