2.1 Premier enregistreur - log4j
Comme vous le savez déjà, l'historique des journaux a commencé avec System.err.println()
la sortie d'un enregistrement sur la console. Il est toujours activement utilisé pour le débogage, par exemple, Intellij IDEA l'utilise pour afficher des messages d'erreur sur la console. Mais cette option n'a aucun paramètre, alors passons à autre chose.
Le premier et le plus populaire des enregistreurs s'appelait Log4j
. C'était une bonne solution hautement personnalisable. En raison de diverses circonstances, cette décision n'est jamais entrée dans le JDK, ce qui a grandement bouleversé toute la communauté.
Cet enregistreur n'était pas seulement capable de se connecter, il a été créé par des programmeurs pour des programmeurs et leur a permis de résoudre des problèmes qui se posaient constamment en rapport avec la journalisation.
Comme vous le savez déjà, les journaux sont écrits à la fin afin qu'une personne les lise et essaie de comprendre ce qui s'est passé pendant le fonctionnement du programme - quoi et quand s'est mal passé comme prévu.
Il y log4j
avait trois choses pour cela :
- journalisation des sous-paquetages ;
- ensemble d'appendices (résultats) ;
- paramètres de rechargement à chaud.
Premièrement, les paramètres log4j
peuvent être écrits de manière à activer la journalisation dans un package et à la désactiver dans un autre. Par exemple, il était possible d'activer la journalisation dans le com.codegym.server
, mais de la désactiver dans le com.codegym.server.payment
. Cela a permis de supprimer rapidement les informations inutiles du journal.
Deuxièmement, log4j
cela permettait d'écrire les résultats de journalisation dans plusieurs fichiers journaux à la fois. Et la sortie de chacun peut être configurée individuellement. Par exemple, dans un fichier, il était possible d'écrire uniquement des informations sur les erreurs graves, dans un autre - les journaux d'un module spécifique et dans un troisième - les journaux pendant un certain temps.
Chaque fichier journal était ainsi adapté à un type particulier de problème attendu. Cela simplifie grandement la vie des programmeurs qui n'aiment pas parcourir manuellement les fichiers journaux de gigaoctets.
Et enfin, troisièmement, log4j
cela permettait de modifier les paramètres du journal directement pendant que le programme était en cours d'exécution, sans le redémarrer. C'était très pratique lorsqu'il fallait corriger le travail des journaux afin de trouver des informations supplémentaires sur une erreur spécifique.
Important! Il existe deux versions du journal log4j
: 1.2.x et 2.xx , qui sont incompatibles entre elles .
Vous pouvez connecter le logger au projet en utilisant le code :
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
</dependencies>
2.2 Premier enregistreur officiel - JUL : java.util.logging
Après l'apparition du zoo des enregistreurs dans la communauté Java, les développeurs JDK
ont décidé de créer un enregistreur standard que tout le monde utiliserait. Voici comment le logger est apparu JUL
: package java.util.logging
.
Cependant, lors de son développement, les créateurs de l'enregistreur n'ont pas pris pour base log4j
, mais une variante de l'enregistreur d'IBM, qui a influencé son développement. La bonne nouvelle est que l'enregistreur JUL
est inclus JDK
, la mauvaise nouvelle est que peu de gens l'utilisent.

Non seulement les développeurs JUL
ont créé "un autre standard universel" , mais ils ont également créé leurs propres niveaux de journalisation, qui différaient de ceux acceptés par les enregistreurs populaires à l'époque.
Et c'était un gros problème. Après tout, les produits sont Java
souvent collectés dans un grand nombre de bibliothèques, et chacune de ces bibliothèques avait son propre enregistreur. Il a donc fallu configurer tous les loggers qui se trouvent dans l'application.
Bien que l'enregistreur lui-même soit plutôt bon. La création d'un enregistreur est plus ou moins la même chose. Pour ce faire, vous devez importer :
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Le nom de la classe est spécialement passé afin de savoir d'où vient la journalisation.
Ce n'est qu'avec la version que les développeurs ont résolu des problèmes importants, après quoi il JUL
est vraiment pratique à utiliser. Avant cela, c'était une sorte d'enregistreur de second ordre.
Cet enregistreur prend également en charge les expressions lambda et l'évaluation paresseuse. À partir de Java 8
, vous pouvez passer Supplier<String>
. Cela permet de lire et de créer une chaîne uniquement au moment où elle est vraiment nécessaire, et pas à chaque fois, comme c'était le cas auparavant.
Les méthodes avec un argument Supplier<String> msgSupplier
ressemblent à ceci :
public void info(Supplier msgSupplier) {
log(Level.INFO, msgSupplier);
}
2.3 Premier wrapper de journalisation - JCL : jakarta commons logging
Pendant longtemps il n'y a pas eu de standard unique chez les bûcherons, ça JUL
aurait dû en devenir un, mais c'était pire log4j
, donc un standard unique n'est jamais apparu. Mais tout un zoo de bûcherons est apparu, chacun voulant devenir le même.

Cependant, les développeurs Java ordinaires n'aimaient pas que presque chaque bibliothèque ait son propre enregistreur et doive être configurée d'une manière spéciale. Par conséquent, la communauté a décidé de créer un emballage spécial par rapport aux autres enregistreurs - c'est ainsi queJCL: jakarta commons logging
Et encore une fois, le projet, qui a été créé pour être un leader, ne l'est pas devenu. Vous ne pouvez pas créer un gagnant, vous ne pouvez que devenir un gagnant. La fonctionnalité JCL
était très médiocre et personne ne voulait l'utiliser. Le logger, destiné à remplacer tous les loggers, a connu le même sort puisqu'il JUL
n'a pas été utilisé.
Bien qu'il ait été ajouté à de nombreuses bibliothèques publiées par la communauté Apache, le zoo des enregistreurs n'a fait que croître.
2.4 Premier dernier enregistreur - Logback
Mais ce n'est pas tout. Le développeur log4j
a décidé qu'il était le plus intelligent (enfin, après tout, la plupart des gens utilisaient son enregistreur) et a décidé d'écrire un nouvel enregistreur amélioré qui combinerait les avantages log4j
des autres enregistreurs.
Le nouvel enregistreur s'appelait Logback
. C'est cet enregistreur qui devait devenir le futur enregistreur unique que tout le monde utiliserait. Il était basé sur la même idée que dans log4j
.
Vous pouvez connecter ce logger au projet en utilisant le code :
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
Les différences portaient sur Logback
:
- performance améliorée;
- support natif ajouté
slf4j
; - option de filtrage étendue.
Un autre avantage de cet enregistreur était qu'il avait de très bons paramètres par défaut. Et vous deviez configurer l'enregistreur uniquement si vous vouliez y changer quelque chose. De plus, le fichier de paramètres était mieux adapté aux logiciels d'entreprise - toutes ses configurations étaient définies en tant que xml/
.
Par défaut, Logback
il ne nécessite aucun paramètre et enregistre tous les journaux du niveau DEBUG
et au-dessus. Si vous avez besoin d'un comportement différent, il peut être configuré via xml
configuration :
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>app.log</file>
<encoder>
<pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
</encoder>
</appender>
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
<root level="info">
<appender-ref ref="FILE" />
</root>
</configuration>
2.5 Dernier enregistreur universel - SLF4J : Façade de journalisation simple pour Java
Combien de temps peut-il falloir pour trouver le juste milieu...
En 2006, l'un des créateurs log4j
a quitté le projet et a décidé de réessayer de créer un enregistreur universel. Mais cette fois, il ne s'agissait pas d'un nouveau logger, mais d'un nouveau standard universel (wrapper) qui permettait à différents loggers d'interagir ensemble.
Cet enregistreur s'appelait slf4j — Simple Logging Facade for Java
, c'était un wrapper autour de log4j
, JUL
, common-loggins и logback
. Cet enregistreur a résolu un vrai problème - gérer un zoo d'enregistreurs, donc tout le monde a immédiatement commencé à l'utiliser.
Nous résolvons héroïquement les problèmes que nous nous créons. Comme vous pouvez le voir, les progrès ont atteint le point où nous avons créé un wrapper sur le wrapper ...
L'enveloppe elle-même se compose de deux parties :
API
, qui est utilisé dans les applications ;- Implémentations ajoutées en tant que dépendances distinctes pour chaque enregistreur.
Vous pouvez connecter le logger au projet en utilisant le code :
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.2</version>
</dependency>
Il suffit de connecter la bonne implémentation et c'est tout : tout le projet fonctionnera avec.
2.6 Optimisation dans slf4j
Slf4j
prend en charge toutes les nouvelles fonctionnalités telles que le formatage des chaînes pour la journalisation . Avant cela, il y avait un tel problème. Supposons que vous souhaitiez imprimer un message dans le journal :
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Il y a un problème avec ce code. Supposons que votre application fonctionne production
et n'en écrive pas dans le log DEBUG-messages
, cependant, la méthode log.debug()
sera toujours appelée, et lorsqu'elle sera appelée, les méthodes suivantes seront également appelées :
user.toString();
request.getRemoteAddr();
L'appel de ces méthodes ralentit l'application. Leur appel n'est nécessaire que pendant le débogage, mais ils sont quand même appelés.
Du point de vue de la logique, ce problème devait être résolu dans la bibliothèque de journalisation elle-même. Et dans la première version de log4j, la solution est apparue :
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
Au lieu d'une ligne pour le journal, il fallait maintenant en écrire trois. Ce qui a considérablement aggravé la lisibilité du code et réduit la popularité de log4j
.
L'enregistreur slf4j
a pu améliorer légèrement la situation en proposant une journalisation intelligente. Ça ressemblait à ça :
log.debug("User {} connected from {}", user, request.getRemoteAddr());
où {}
dénotent l'insertion d'arguments passés dans la méthode. Autrement dit, le premier {}
correspond à l'utilisateur, le second {}
à request.getRemoteAddr()
.
Ces paramètres seront concaténés en un seul message uniquement si le niveau de journalisation autorise la journalisation. Pas parfait, mais mieux que toutes les autres options.
Après cela, SLF4J
il a commencé à gagner rapidement en popularité, pour le moment c'est la meilleure solution.
Par conséquent, nous considérerons la journalisation en utilisant l'exemple d'un bundle slf4j-log4j12
.
GO TO FULL VERSION