"Oh, eccoti! Ti sei ricordato che oggi abbiamo un'altra lezione?"

"No, ti stavo solo cercando. Quasi..."

"Eccellente, allora cominciamo. Oggi voglio parlarvi del logging."

"Il registro è un elenco degli eventi che si sono verificati. Quasi come il registro di una nave o un diario. O Twitter - forse puoi relazionarti meglio con quello. Non sorprende che un logger sia un oggetto che usi per la registrazione."

"Nella programmazione, è consuetudine registrare quasi tutto. E in Java, registriamo tutto e anche un po' di più."

"Il fatto è che i programmi Java sono molto spesso applicazioni server di grandi dimensioni senza interfaccia utente, console, ecc. Elaborano migliaia di richieste degli utenti contemporaneamente e spesso si verificano vari errori. Soprattutto quando diversi thread iniziano a interferire tra loro."

"In effetti, l'unico modo per cercare bug e guasti raramente riproducibili in queste circostanze è registrare tutto ciò che accade su ogni thread."

"Molto spesso, il registro contiene informazioni sugli argomenti del metodo, eventuali errori rilevati e molte informazioni intermedie."

"Più completo è il registro, più facile è riprodurre una sequenza di eventi e tracciare le cause di errori o bug."

"A volte i log raggiungono diversi gigabyte al giorno. Questo è normale."

"Qualche gigabyte? O_o"

"Sì. Molto spesso, i file di registro vengono archiviati automaticamente, con l'indicazione della relativa data."

"Ehi."

"Uh-huh. Inizialmente, Java non aveva un proprio logger. Di conseguenza, sono stati scritti diversi logger indipendenti. Il più comune di questi era log4j."

"Alcuni anni dopo, Java ha ottenuto un proprio logger, ma la sua funzionalità era di gran lunga inferiore e non era ampiamente utilizzato."

"È un dato di fatto che Java abbia un logger ufficiale, ma l'intera comunità di programmatori Java preferisce utilizzare altri logger. "

"Successivamente, sono stati scritti molti altri logger basati su log4j."

"Quindi lo speciale logger universale slf4j, che ora è ampiamente utilizzato, è stato scritto per tutti loro. È molto simile a log4j, quindi lo userò come esempio per spiegare la registrazione."

"L'intero processo di registrazione si compone di tre parti."

" In primo luogo , raccogliere informazioni."

" Secondo , filtra le informazioni raccolte."

" In terzo luogo , registra le informazioni selezionate."

"Iniziamo con la raccolta. Ecco un tipico esempio di una classe che registra:"

Classe con registrazione
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;
  }
 }
}

"Presta attenzione alle parole evidenziate in rosso."

" Riga 3  – Crea l' oggetto logger . Un tale oggetto statico viene creato in quasi tutte le classi! Beh, ad eccezione delle classi che non fanno altro che memorizzare i dati."

" LoggerFactory è una classe speciale per la creazione di logger e getLogger è uno dei suoi metodi statici. L'oggetto corrente viene solitamente passato, ma sono possibili varie opzioni."

" Riga 7 – Le informazioni sulla chiamata al metodo vengono scritte nel logger. Si noti che questa è la prima riga del metodo. Non appena il metodo viene chiamato, scriviamo immediatamente le informazioni nel registro."

"Chiamiamo il metodo di debug, il che significa che l'importanza dell'informazione è il livello DEBUG. Questo è usato per filtrare. Te ne parlerò tra un paio di minuti."

" Riga 17 – Rileviamo un'eccezione e... la scriviamo immediatamente nel registro! Questo è esattamente ciò che deve essere fatto."

"Questa volta chiamiamo il metodo di errore, che indica immediatamente che l'informazione è di livello ERROR"

Registratore - 1

"Per ora sembra tutto chiaro. Beh, per quanto può essere chiaro nel bel mezzo della nostra conversazione."

"Ottimo, allora passiamo al filtro dei messaggi."

"Di solito, ogni messaggio di registro ha il proprio livello di importanza, che puoi utilizzare per scartare alcuni dei messaggi. Ecco i livelli di importanza che ho menzionato:"

Livello di importanza Descrizione
TUTTO Tutti i messaggi
TRACCIA Messaggi di debug a grana fine
DEBUG Importanti messaggi di debug
INFORMAZIONI Messaggi informativi
AVVISARE Avvertenze
ERRORE Errori
FATALE Errori fatali
SPENTO Nessun messaggio

Questi livelli vengono utilizzati anche durante il filtraggio dei messaggi.

Supponiamo di impostare il livello di registrazione su WARN. Quindi tutti i messaggi meno importanti di WARN verranno scartati: TRACE, DEBUG, INFO.

Se imposti il ​​livello di filtraggio su FATAL, anche i messaggi ERROR verranno scartati.

"Ci sono altri due livelli di importanza utilizzati durante il filtraggio: OFF, che scarta tutti i messaggi; e ALL, che mostra tutti i messaggi (niente viene scartato)."

"Come e dove posso impostare il filtro?"

"Te lo dirò senza ulteriori indugi."

"Di solito, le impostazioni del logger log4j sono specificate nel file log4j.properties."

È possibile specificare più oggetti appender in questo file. I dati vengono scritti su questi oggetti. Ci sono origini dati e ci sono appender, oggetti che hanno scopi opposti. Oggetti in cui i dati scorrono come acqua.

"Ecco alcuni esempi:"

Accesso alla 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}

Righe 1 e 4 – Questi sono commenti

Riga 2 – Indichiamo il livello di registrazione che vogliamo. Tutti i livelli meno importanti (DEBUG, TRACE) verranno scartati.

Nello stesso punto, aggiungiamo una virgola e quindi indichiamo il nome dell'oggetto (che inventiamo noi stessi) su cui verrà scritto il registro. Le righe 5-9 contengono le sue impostazioni.

Riga 5 – Specifichiamo il tipo di appender ( ConsoleAppender ).

Riga 6 – Indichiamo esattamente dove stiamo scrivendo ( System.out. ).

Riga 7 – Impostiamo la classe che gestirà i pattern di conversione (PatternLayout).

Riga 8 – Impostiamo il pattern di conversione che verrà utilizzato per la scrittura. Nell'esempio sopra, è la data e l'ora.

"Ed ecco come appare la scrittura su un file:"

Registrazione in un file
# 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 riga 2 imposta il livello di filtraggio dei messaggi e il nome dell'oggetto appender (sink)."

"Riga 5 – Specifichiamo il tipo di appender del file ( RollingFileAppender )."

"Riga 6 – Specifichiamo il nome del file in cui verrà scritto il registro."

"Riga 7 – Specifichiamo la dimensione massima del registro. Quando questo limite di dimensione viene superato, viene creato un nuovo file."

"Riga 8 – Specifichiamo il numero di vecchi file di registro da archiviare."

"Righe 9-10 – Imposta il modello di conversione."

"Non so cosa stia succedendo qui, ma posso immaginarlo. Questo è incoraggiante."

"Fantastico. Quindi ecco un esempio di come scrivere un registro in un file e nella console:"

Accesso alla console e un file
# 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, quindi puoi farlo? Fantastico!"

"Sì. Puoi dichiarare tutti gli appender che vuoi e personalizzare ognuno di essi."

Inoltre, ogni appender può avere impostazioni molto flessibili per il filtraggio dei messaggi. Non solo possiamo assegnare un singolo livello di filtraggio dei messaggi a ciascun appender, ma possiamo anche filtrare i messaggi per pacchetto! Ecco perché è necessario specificare una classe durante la creazione di un logger (sto parlando di LoggerFactory.getLogger ).

"Per esempio:"

Accesso alla console e un file
# 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

"Righe 6 e 15: impostiamo il nostro livello di filtro per ogni appender."

"Righe 20-23 – Specifichiamo il nome del pacchetto e il livello di filtraggio per i suoi messaggi. Log4j.logger è un prefisso: il nome del pacchetto è evidenziato in arancione."

"Davvero? Puoi anche farlo. Beh, figo!"

"A proposito, né log4j né slf4j sono inclusi nel JDK. Dovrai scaricarli separatamente. Puoi farlo qui . Ma c'è un altro modo:"

" Passaggio 1 .Aggiungi le importazioni alla classe:"

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

" Passaggio 2 . Posiziona il cursore su queste righe e premi Alt+Invio in IntelliJ IDEA"

" Passaggio 3 . Scegli la voce di menu "File jar sul Web".

" Passaggio 4 . Scegli 'slf4j-log4j13.jar'"

" Passaggio 5 . Specificare dove scaricare la libreria (jar)"

" Passaggio 6. Usa le classi di cui hai bisogno."

"Whoa! Che giornata è stata questa. C'è così tanto di nuovo e così tanto di bello!"

"Ecco un altro buon articolo sulla registrazione: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSCOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"Va bene, basta così. Rilassati, programmatore."