2.1 Primul logger - log4j
După cum știți deja, istoricul jurnalelor a început cu System.err.println()
ieșirea unei înregistrări pe consolă. Este încă folosit în mod activ pentru depanare, de exemplu, Intellij IDEA îl folosește pentru a afișa mesaje de eroare pe consolă. Dar această opțiune nu are nicio setare, așa că hai să mergem mai departe.
Primul și cel mai popular logger a fost numit Log4j
. A fost o soluție bună și foarte personalizabilă. Din cauza diverselor circumstanțe, această decizie nu a intrat niciodată în JDK, ceea ce a supărat foarte mult întreaga comunitate.
Acest logger nu a putut doar să se înregistreze, ci a fost creat de programatori pentru programatori și le-a permis să rezolve problemele care au apărut constant în legătură cu înregistrarea în jurnal.
După cum știți deja, jurnalele sunt scrise în final, astfel încât cineva să le citească și să încerce să înțeleagă ce s-a întâmplat în timpul funcționării programului - ce și când a mers prost conform așteptărilor.
Au log4j
fost trei lucruri pentru asta:
- înregistrarea subpachetelor;
- set de anexe (rezultate);
- setări de reîncărcare la cald.
În primul rând, setările log4j
ar putea fi scrise în așa fel încât să permită conectarea într-un pachet și să o dezactiveze în altul. De exemplu, a fost posibil să activați conectarea în com.codegym.server
, dar să o dezactivați în com.codegym.server.payment
. Acest lucru a făcut posibilă eliminarea rapidă a informațiilor inutile din jurnal.
În al doilea rând, log4j
a permis scrierea rezultatelor înregistrării în mai multe fișiere jurnal deodată. Și ieșirea pentru fiecare ar putea fi configurată individual. De exemplu, într-un fișier a fost posibil să se scrie doar informații despre erori grave, în altul - jurnalele dintr-un anumit modul, iar într-un al treilea - jurnalele pentru un anumit timp.
Fiecare fișier jurnal a fost astfel reglat la un anumit tip de problemă așteptată. Acest lucru simplifică foarte mult viața programatorilor cărora nu le place să caute manual fișierele jurnal gigabyte.
Și, în cele din urmă, în al treilea rând, log4j
a permis modificarea setărilor de jurnal direct în timp ce programul rula, fără a-l reporni. Acest lucru a fost foarte util atunci când a fost necesar să corectați funcționarea jurnalelor pentru a găsi informații suplimentare despre o anumită eroare.
Important! Există două versiuni ale jurnalului log4j
: 1.2.x și 2.xx , care sunt incompatibile între ele .
Puteți conecta loggerul la proiect folosind codul:
<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 Primul logger oficial - IUL: java.util.logging
După ce grădina zoologică a loggerilor a apărut în comunitatea Java, dezvoltatorii JDK
au decis să creeze un singur logger standard pe care să îl folosească toată lumea. Asa a aparut loggerul JUL
: pachet java.util.logging
.
Cu toate acestea, în timpul dezvoltării sale, creatorii logger-ului au luat ca bază nu log4j
, ci o variantă a logger-ului de la IBM, care a influențat dezvoltarea acestuia. Vestea bună este că logger-ul JUL
este inclus JDK
, vestea proastă este că puțini oameni îl folosesc.

Dezvoltatorii nu numai că JUL
au creat „un alt standard universal” , ci și-au creat și propriile niveluri de înregistrare pentru acesta, care diferă de cele acceptate de loggerii populari la acea vreme.
Și asta a fost o mare problemă. La urma urmei, produsele sunt Java
adesea colectate dintr-un număr mare de biblioteci, iar fiecare astfel de bibliotecă avea propriul său logger. Deci a fost necesar să se configureze toate loggerele care se află în aplicație.
Deși loggerul în sine este destul de bun. Crearea unui logger este mai mult sau mai puțin la fel. Pentru a face acest lucru, trebuie să importați:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
Numele clasei este transmis special pentru a ști de unde provine înregistrarea.
Numai odată cu lansarea, dezvoltatorii au rezolvat probleme importante, după care este JUL
foarte convenabil de utilizat. Înainte de asta, era un fel de logger de al doilea rang.
Acest logger acceptă, de asemenea, expresii lambda și evaluare leneșă. Începând cu Java 8
, poți trece Supplier<String>
. Acest lucru ajută la citirea și crearea unui șir numai în momentul în care este cu adevărat necesar, și nu de fiecare dată, așa cum era înainte.
Metodele cu un argument Supplier<String> msgSupplier
arată astfel:
public void info(Supplier msgSupplier) {
log(Level.INFO, msgSupplier);
}
2.3 First logger wrapper - JCL: jakarta commons logging
Pentru o lungă perioadă de timp nu a existat un singur standard în rândul lor, JUL
ar fi trebuit să devină unul, dar a fost mai rău log4j
, așa că nu a apărut niciodată un singur standard. Dar a apărut o întreagă grădina zoologică de tăietori de lemne, fiecare dintre care dorea să devină la fel.

Cu toate acestea, dezvoltatorilor obișnuiți Java nu le-a plăcut că aproape fiecare bibliotecă are propriul său logger și trebuie configurată cumva într-un mod special. Prin urmare, comunitatea a decis să creeze un înveliș special față de ceilalți bușteni - așa se faceJCL: jakarta commons logging
Și din nou, proiectul, care a fost creat pentru a fi un lider, nu a devenit unul. Nu poți crea un câștigător, poți deveni doar un câștigător. Funcționalitatea JCL
a fost foarte slabă și nimeni nu a vrut să o folosească. Loggerul, conceput pentru a înlocui toți loggerul, a avut aceeași soartă, deoarece JUL
nu a fost folosit.
Deși a fost adăugată la multe biblioteci lansate de comunitatea Apache, grădina zoologică a loggerilor a crescut.
2.4 Primul ultimul logger - Logback
Dar asta nu este tot. Dezvoltatorul log4j
a decis că el este cel mai deștept (ei bine, la urma urmei, cei mai mulți oameni i-au folosit loggerul) și a decis să scrie un nou logger îmbunătățit care să combine avantajele log4j
altor loggere.
Noul logger a fost numit Logback
. Acest logger trebuia să devină viitorul singur logger pe care îl va folosi toată lumea. S-a bazat pe aceeași idee ca în log4j
.
Puteți conecta acest logger la proiect folosind codul:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
Diferențele au fost în Logback
:
- performanta imbunatatita;
- suport nativ adăugat
slf4j
; - opțiune extinsă de filtrare.
Un alt avantaj al acestui logger a fost că avea setări implicite foarte bune. Și trebuia să configurați loggerul doar dacă voiai să schimbi ceva în ele. De asemenea, fișierul de setări a fost mai bine adaptat la software-ul corporativ - toate configurațiile sale au fost setate ca xml/
.
În mod implicit, Logback
nu necesită setări și înregistrează toate jurnalele de la nivel DEBUG
și mai sus. Dacă aveți nevoie de un comportament diferit, acesta poate fi configurat prin xml
configurare:
<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 Cel mai recent logger universal - SLF4J: Simple Logging Facade pentru Java
Cât poate dura să găsești mijlocul de aur...
În 2006, unul dintre creatori log4j
a părăsit proiectul și a decis să încerce din nou să creeze un logger universal. Dar de data aceasta nu a fost un nou logger, ci un nou standard universal (wrapper) care a permis diferiților logger să interacționeze împreună.
Acest logger se numea slf4j — Simple Logging Facade for Java
, era un înveliș în jurul log4j
, JUL
, common-loggins and logback
. Acest logger a rezolvat o problemă reală - gestionarea unei grădini zoologice de loggeri, așa că toată lumea a început imediat să-l folosească.
Rezolvăm eroic problemele pe care ni le creăm. După cum puteți vedea, progresul a ajuns la punctul în care am creat un înveliș peste înveliș...
Învelișul în sine constă din două părți:
API
, care este folosit în aplicații;- Implementări care sunt adăugate ca dependențe separate pentru fiecare logger.
Puteți conecta loggerul la proiect folosind codul:
<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>
Este suficient să conectați implementarea corectă și atât: întregul proiect va funcționa cu ea.
2.6 Optimizare în slf4j
Slf4j
acceptă toate caracteristicile noi, cum ar fi formatarea șirurilor pentru înregistrare . Înainte de asta a existat o astfel de problemă. Să presupunem că doriți să imprimați un mesaj în jurnal:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
Există o problemă cu acest cod. Să presupunem că aplicația dvs. funcționează production
și nu scrie nimic în jurnal DEBUG-messages
, cu toate acestea, metoda log.debug()
va fi apelată în continuare și, atunci când este apelată, vor fi apelate și următoarele metode:
user.toString();
request.getRemoteAddr();
Apelarea acestor metode încetinește aplicația. Apelul lor este necesar doar în timpul depanării, dar sunt chemați oricum.
Din punct de vedere al logicii, această problemă trebuia rezolvată chiar în biblioteca de logare. Și în prima versiune de log4j a apărut soluția:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
În loc de o linie pentru jurnal, acum era necesar să scrieți trei. Ceea ce a înrăutățit dramatic lizibilitatea codului și a scăzut popularitatea log4j
.
Loggerul slf4j
a reușit să îmbunătățească puțin situația, oferind înregistrare inteligentă. Arăta așa:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
unde {}
denotă inserarea argumentelor care sunt transmise în metodă. Adică, primul {}
corespunde utilizatorului, al doilea {}
lui request.getRemoteAddr()
.
Acești parametri vor fi concatenați într-un singur mesaj numai dacă nivelul de înregistrare permite înregistrarea. Nu perfect, dar mai bun decât toate celelalte opțiuni.
După aceea, SLF4J
a început să crească rapid în popularitate, în acest moment aceasta este cea mai bună soluție.
Prin urmare, vom lua în considerare înregistrarea folosind exemplul unui pachet slf4j-log4j12
.
GO TO FULL VERSION