« Oh, vous y êtes ! Vous souvenez-vous que nous avons une autre leçon aujourd'hui ? »

"Non, je te cherchais juste. Presque…"

"Excellent, alors commençons. Aujourd'hui, je veux vous parler de la journalisation."

"Le journal est une liste des événements qui se sont produits. Presque comme un journal de bord ou un journal. Ou Twitter - peut-être que vous pouvez mieux comprendre cela. Sans surprise, un enregistreur est un objet que vous utilisez pour la journalisation."

"En programmation, il est d'usage de tout journaliser. Et en Java, on journalise tout et même un peu plus."

"Le fait est que les programmes Java sont très souvent de grandes applications serveur sans interface utilisateur, console, etc. Ils traitent des milliers de demandes d'utilisateurs en même temps, et il y a souvent diverses erreurs. Surtout lorsque différents threads commencent à interférer les uns avec les autres."

"En fait, la seule façon de rechercher des bogues et des échecs rarement reproductibles dans ces circonstances est de consigner tout ce qui se passe sur chaque thread."

"Le plus souvent, le journal contient des informations sur les arguments de la méthode, les erreurs détectées et de nombreuses informations intermédiaires."

"Plus le journal est complet, plus il est facile de reproduire une séquence d'événements et de suivre les causes des pannes ou des bugs."

"Parfois, les journaux atteignent plusieurs gigaoctets par jour. C'est normal."

"Quelques gigaoctets ? O_o"

"Oui. Le plus souvent, les fichiers journaux sont automatiquement archivés, avec une indication de la date pertinente."

"Waouh."

"Uh-huh. Initialement, Java n'avait pas son propre enregistreur. En conséquence, plusieurs enregistreurs indépendants ont été écrits. Le plus courant d'entre eux était log4j."

"Quelques années plus tard, Java a eu son propre enregistreur, mais ses fonctionnalités étaient bien inférieures et il n'était pas largement utilisé."

"C'est un fait que Java a un logger officiel, mais toute la communauté des programmeurs Java préfère utiliser d'autres loggers. "

"Plus tard, plusieurs autres enregistreurs ont été écrits sur la base de log4j."

"Ensuite, le logger universel spécial slf4j, qui est maintenant largement utilisé, a été écrit pour chacun d'eux. Il est très similaire à log4j, donc je vais l'utiliser comme exemple pour expliquer la journalisation."

"L'ensemble du processus de journalisation se compose de trois parties."

« Tout d'abord , collecter des informations.

" Deuxièmement , filtrez les informations collectées."

" Troisièmement , enregistrez les informations sélectionnées."

"Commençons par la collection. Voici un exemple typique d'une classe qui se connecte :"

Classe avec journalisation
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"Faites attention aux mots surlignés en rouge."

" Ligne 3  - Créez l' objet logger . Un tel objet statique est créé dans presque toutes les classes ! Eh bien, sauf pour les classes qui ne font rien d'autre que stocker des données."

" LoggerFactory est une classe spéciale pour créer des loggers, et getLogger est l'une de ses méthodes statiques. L'objet courant est généralement passé, mais diverses options sont possibles."

" Ligne 7 - Les informations sur l'appel de la méthode sont écrites dans le journal. Notez qu'il s'agit de la première ligne de la méthode. Dès que la méthode est appelée, nous écrivons immédiatement les informations dans le journal."

"Nous appelons la méthode de débogage, ce qui signifie que l'importance de l'information est le niveau DEBUG. Ceci est utilisé pour le filtrage. Je vous en parlerai dans quelques minutes."

" Ligne 17 – Nous interceptons une exception et... l'écrivons immédiatement dans le journal ! C'est exactement ce qu'il faut faire."

"Cette fois, nous appelons la méthode d'erreur, qui indique immédiatement que l'information est au niveau ERROR"

Enregistreur - 1

"Tout semble clair pour l'instant. Eh bien, dans la mesure où cela peut être clair au milieu de notre conversation."

"Super, alors passons au filtrage des messages."

"Habituellement, chaque message de journal a son propre niveau d'importance, que vous pouvez utiliser pour supprimer certains messages. Voici les niveaux d'importance que j'ai mentionnés :"

Niveau d'importance Description
TOUS Tous les messages
TRACE Messages de débogage précis
DÉBOGUER Messages de débogage importants
INFO Messages d'information
AVERTIR Avertissements
ERREUR les erreurs
FATAL Erreurs fatales
DÉSACTIVÉ Pas de messages

Ces niveaux sont également utilisés lors du filtrage des messages.

Supposons que vous définissiez le niveau de journalisation sur WARN. Ensuite, tous les messages moins importants que WARN seront ignorés : TRACE, DEBUG, INFO.

Si vous réglez le niveau de filtrage sur FATAL, même les messages ERROR seront rejetés.

"Il existe deux autres niveaux d'importance utilisés lors du filtrage : OFF, qui supprime tous les messages ; et ALL, qui affiche tous les messages (rien n'est supprimé)."

"Comment et où configurer le filtrage ?"

« Je vais vous le dire sans plus tarder.

"Habituellement, les paramètres de l'enregistreur log4j sont spécifiés dans le fichier log4j.properties."

Vous pouvez spécifier plusieurs objets appender dans ce fichier. Les données sont écrites dans ces objets. Il existe des sources de données et des ajouts - des objets qui ont des objectifs opposés. Les objets dans lesquels les données coulent comme de l'eau.

"Voici quelques exemples:"

Connexion à la console
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

Lignes 1 et 4 – Ce sont des commentaires

Ligne 2 – Nous indiquons le niveau de journalisation souhaité. Tous les niveaux moins importants (DEBUG, TRACE) seront ignorés.

Au même endroit, nous ajoutons une virgule, puis indiquons le nom de l'objet (que nous créons nous-mêmes) dans lequel le journal sera écrit. Les lignes 5 à 9 contiennent ses paramètres.

Ligne 5 – Nous spécifions le type d'appender ( ConsoleAppender ).

Ligne 6 – Nous indiquons exactement où nous écrivons ( System.out. ).

Ligne 7 – Nous définissons la classe qui gérera les modèles de conversion (PatternLayout).

Ligne 8 - Nous définissons le modèle de conversion qui sera utilisé pour l'écriture. Dans l'exemple ci-dessus, il s'agit de la date et de l'heure.

"Et voici à quoi ressemble l'écriture dans un fichier :"

Se connecter à un fichier
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"La ligne 2 définit le niveau de filtrage des messages et le nom de l'objet appender (sink)."

"Ligne 5 - Nous spécifions le type d'ajout de fichier ( RollingFileAppender )."

"Ligne 6 - Nous spécifions le nom du fichier dans lequel le journal sera écrit."

"Ligne 7 - Nous spécifions la taille maximale du journal. Lorsque cette limite de taille est dépassée, un nouveau fichier est créé."

"Ligne 8 - Nous spécifions le nombre d'anciens fichiers journaux à stocker."

"Lignes 9-10 - Définissez le modèle de conversion."

"Je ne sais pas ce qui se passe ici, mais je peux deviner. C'est encourageant."

"C'est super. Alors voici un exemple de la façon d'écrire un journal dans un fichier et la console :"

Connexion à la console et à un fichier
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

« Ah, alors tu peux faire ça ? C'est super !

"Oui. Vous pouvez déclarer autant d'appenders que vous le souhaitez et personnaliser chacun d'entre eux."

De plus, chaque appender peut avoir des paramètres très flexibles pour le filtrage des messages. Non seulement pouvons-nous attribuer un niveau de filtrage des messages individuel à chaque appender, mais nous pouvons également filtrer les messages par package ! C'est pourquoi vous devez spécifier une classe lors de la création d'un enregistreur (je parle de LoggerFactory.getLogger ).

"Par exemple:"

Connexion à la console et à un fichier
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"Lignes 6 et 15 - Nous définissons notre propre niveau de filtrage pour chaque appender."

"Lignes 20-23 - Nous spécifions le nom du package et le niveau de filtrage de ses messages. Log4j.logger est un préfixe : le nom du package est surligné en orange."

« Vraiment ? Tu peux même faire ça. Eh bien, cool !

"Au fait, ni log4j ni slf4j ne sont inclus dans le JDK. Vous devrez les télécharger séparément. Vous pouvez le faire ici . Mais il existe un autre moyen :"

" Étape 1 .Ajouter des importations à la classe :"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" Étape 2. Placez le curseur sur ces lignes et appuyez sur Alt+Entrée dans IntelliJ IDEA"

" Étape 3 . Choisissez l'élément de menu "Fichier jar sur le Web".'

" Étape 4. Choisissez 'slf4j-log4j13.jar'"

" Étape 5 . Spécifiez où télécharger la bibliothèque (jar)"

" Étape 6 . Utilisez les classes dont vous avez besoin."

"Whoa ! Quelle journée ce fut. Tellement de nouveautés et tellement de choses cool !"

"Voici un autre bon article sur la journalisation : https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"D'accord, ça suffit. Allez vous détendre, programmeur."