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 log4jfost trei lucruri pentru asta:

  • înregistrarea subpachetelor;
  • set de anexe (rezultate);
  • setări de reîncărcare la cald.

În primul rând, setările log4jar 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, log4ja 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, log4ja 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 JDKau 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 JULeste inclus JDK, vestea proastă este că puțini oameni îl folosesc.

IUL

Dezvoltatorii nu numai că JULau 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 Javaadesea 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 JULfoarte 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> msgSupplierarată 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, JULar 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.

JCL

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 JCLa 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 JULnu 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 log4ja 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 log4jaltor 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, Logbacknu 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 xmlconfigurare:

<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 log4ja 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

Slf4jacceptă 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 slf4ja 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, SLF4Ja î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.