Introduction à Logback
Logback est un framework de journalisation open source conçu par le fondateur de log4j. Il se compose de trois modules : logback-core, logback-classic et logback-access. logback-core sert de base aux deux autres. logback-classic est une version améliorée de log4j et implémente nativement l’API SLF4J, ce qui permet une migration facile vers d’autres systèmes de logs (log4j, JDK14 Logging, etc.). logback-access s’intègre avec les conteneurs Servlet pour exposer les logs via HTTP.
Avantages de Logback
- Exécution rapide et empreinte mémoire réduite à l’initialisation
- Implémentation native de SLF4J – pas besoin de conversion
- Configuration simple et adaptable à divers environnements
- Suppression automatique des fichiers de logs obsolètes
- Filtres puissants évitant la génération excessive de logs lors des changements de niveau
- Récupération après erreurs d’E/S
- ...
Pour plus de détails, consultez la documentation officielle.
Structure de configuration de Logback
Voici une vue simplifiée de la hiérarchie des éléments XML (non exhaustive) :
configuration
root
logger
property
appender
layout
rollingPolicy
Pattern
fileNamePattern
maxFileSize
maxHistory
totalSizeCap
Éléments de configuration
<configuration> – Racine
Attributs : scan (rechargement automatique, défaut true), scanPeriod (intervalle de vérification, défaut 1 minute), debug (affichage des infos d’état de Logback, défaut true).
<configuration scan="true" scanPeriod="30 seconds" debug="true">
...
</configuration>
<root> et <logger> – Niveaux de log
root: niveau par défaut pour tous les loggers non configurés explicitement.logger: niveau personnalisé pour un nom spécifique.
Exemple :
<logger name="oneInfo" level="DEBUG" additivity="false">
<appender-ref ref="ONE_INFO" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE" />
</root>
additivity="false" empêche la propagation vers le root.
<property> – Variables
<property name="LOG_HOME" value="logs/pcm"/>
Le dossier est créé automatiquement dans le répertoire du projet.
<appender> – Destination des logs
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
...
</appender>
<layout> et <Pattern> – Format du message
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n
</Pattern>
</layout>
Rotation des fichiers (rolling policy)
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>31</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
</appender>
Les fichiers sont créés quotidiennement (par le %d), et lorsqu’un fichier dépasse 10 Mo, il est renommé avec un index %i. Les fichiers de plus de 31 jours sont supprimés, et la taille totale des logs est limitée à 10 Go.
Utilisation de Logback
Pour utiliser Logback, ajoutez les dépendances Maven suivantes (versions stables actuelles) :
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
Exemple complet de configuration (logback.xml)
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="true">
<property name="LOG_HOME" value="logs/pcm"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>31</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n</Pattern>
</layout>
</appender>
<appender name="ONE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/oneInfo/%d{yyyy-MM-dd}/oneInfo.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>31</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n</Pattern>
</layout>
</appender>
<appender name="TWO_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/twoInfo/%d{yyyy-MM-dd}/twoInfo.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>31</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n</Pattern>
</layout>
</appender>
<logger name="oneInfo" level="DEBUG" additivity="false">
<appender-ref ref="ONE_INFO" />
</logger>
<logger name="twoInfo" level="WARN" additivity="true">
<appender-ref ref="TWO_INFO" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE" />
</root>
</configuration>
Code Java de test
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackDemo {
private static final Logger LOG_MAIN = LoggerFactory.getLogger(LogbackDemo.class);
private static final Logger LOG_CUSTOM1 = LoggerFactory.getLogger("oneInfo");
private static final Logger LOG_CUSTOM2 = LoggerFactory.getLogger("twoInfo");
public static void main(String[] args) {
execute();
}
private static void execute() {
LOG_MAIN.debug("Log principal – debug");
LOG_MAIN.info("Log principal – info");
LOG_MAIN.warn("Log principal – warn");
LOG_MAIN.error("Log principal – error");
LOG_CUSTOM1.debug("oneInfo – debug");
LOG_CUSTOM1.info("oneInfo – info");
LOG_CUSTOM1.warn("oneInfo – warn");
LOG_CUSTOM1.error("oneInfo – error");
LOG_CUSTOM2.debug("twoInfo – debug");
LOG_CUSTOM2.info("twoInfo – info");
LOG_CUSTOM2.warn("twoInfo – warn");
LOG_CUSTOM2.error("twoInfo – error");
}
}
Résultats attendus
- LOG_MAIN : niveau INFO → seuls les messages info, warn et error appparaissent dans la console et dans le fichier
FILE. - LOG_CUSTOM1 :
additivity="false"→ aucun message dans la console. Les logs de niveau DEBUG et supérieur sont écrits dans le fichier${LOG_HOME}/oneInfo/.... - LOG_CUSTOM2 :
additivity="true"→ les logs warn et error apparaissent dans la console (carrootest INFO) ainsi que dans le fichier${LOG_HOME}/twoInfo/....