Vodič za prijavu

1. Pregled

Zapis je jedan od najčešće korištenih okvira za bilježenje u Java zajednici. To je zamjena za svog prethodnika, Log4j. Logback nudi bržu implementaciju od Log4j, pruža više mogućnosti za konfiguraciju i veću fleksibilnost u arhiviranju starih datoteka dnevnika.

Ovaj uvod predstavit će Logback-ovu arhitekturu i pokazati vam kako je možete koristiti za poboljšanje svojih aplikacija.

2. Arhitektura povratka

Tri klase obuhvaćaju arhitekturu Logback; Drvosječa, Napadač, i Izgled.

Logger je kontekst za poruke dnevnika. Ovo je klasa s kojom aplikacije komuniciraju kako bi stvorile poruke dnevnika.

Dodaci postavljaju poruke dnevnika na njihova konačna odredišta. Drvar može imati više od jednog uređivača. Općenito smatramo da su Appenderi priloženi tekstualnim datotekama, ali Logback je mnogo snažniji od toga.

Layout priprema poruke za izlaz. Zapisnik podržava stvaranje prilagođenih klasa za formatiranje poruka, kao i robusne opcije konfiguracije za postojeće.

3. Postavljanje

3.1. Ovisnost Mavena

Logback koristi Simple Logging Facade for Java (SLF4J) kao svoje izvorno sučelje. Prije nego što započnemo bilježiti poruke, u svoj moramo dodati Logback i Slf4j pom.xml:

 ch.qos.logback logback-core 1.2.3 org.slf4j slf4j-api 1.7.30 test 

Maven Central ima najnoviju verziju Logback Core i najnoviju verziju slf4j-api.

3.2. Put predavanja

Prijava također zahtijeva prijava-klasika.jar na stazi za vrijeme izvođenja.

To ćemo dodati na pom.xml kao testna ovisnost:

 ch.qos. logback prijava-klasika 1.2.3 

4. Osnovni primjer i konfiguracija

Počnimo s brzim primjerom upotrebe povratne prijave u aplikaciji.

Prvo, trebamo konfiguracijsku datoteku. Stvorit ćemo tekstualnu datoteku s imenom logback.xml i stavite to negdje u naš razred:

   % d {HH: mm: ss.SSS} [% nit]% -5 nivo% zapisnika {36} -% msg% n 

Dalje, trebamo jednostavnu nastavu s a glavni metoda:

javna klasa Primjer {private static final Logger logger = LoggerFactory.getLogger (Example.class); javna statička void glavna (String [] args) {logger.info ("Primjer zapisnika iz {}", Example.class.getSimpleName ()); }}

Ova klasa stvara Drvosječa i poziva informacije () za generiranje poruke dnevnika.

Kad trčimo Primjer vidimo našu poruku prijavljenu na konzolu:

20: 34: 22.136 [glavna] INFO Primjer - Primjer dnevnika iz Primjera

Lako je shvatiti zašto je Logback toliko popularan; pokrećemo se za nekoliko minuta.

Ova konfiguracija i kôd daju nam nekoliko savjeta kako to funkcionira.

  1. Mi imamo prilijepac imenovan IZDAVANJE koji upućuje na naziv klase ConsoleAppender.
  2. Postoji obrazac koji opisuje format naše poruke dnevnika.
  3. Naš kod stvara Drvosječa i prenijeli smo mu svoju poruku putem informacije () metoda.

Sad kad razumijemo osnove, pogledajmo izbliza.

5. Drvosječa Konteksti

5.1. Stvaranje konteksta

Da bismo prijavili poruku u Logback, inicijalizirali smo a Drvosječa iz SLF4J ili povratne informacije:

privatni statički konačni logger logger = LoggerFactory.getLogger (Example.class); 

A zatim ga upotrijebio:

logger.info ("Primjer zapisnika iz {}", Example.class.getSimpleName ()); 

Ovo je naš kontekst bilježenja. Kad smo je stvorili, prošli smo LoggerFactory naš razred. To daje Drvosječa ime (postoji i preopterećenje koje prihvaća Niz).

Konteksti zapisivanja postoje u hijerarhiji koja jako sliči hijerarhiji Java objekta:

  1. Drvar je predak kada njegovo ime, praćeno točkom, stavlja prefiks nad ime potomka
  2. Sjekač je roditelj kada između njega i djeteta nema predaka

Na primjer, Primjer razred ispod je u com.baeldung.logback paket. Postoji još jedan razred s imenom ExampleAppender u com.baeldung.logback.appenders paket.

ExampleAppender's Logger je dijete od Primjerov zapisničar.

Svi zapisničari su potomci unaprijed definiranog matičnog zapisnika.

A Drvosječa ima Razina, koji se mogu postaviti bilo putem konfiguracije ili pomoću Logger.setLevel (). Postavljanje razine u kodu poništava konfiguracijske datoteke.

Moguće razine su prema redoslijedu prioriteta: TRACE, DEBUG, INFO, UPOZORENJE i POGREŠKA.Svaka razina ima odgovarajuću metodu koju koristimo za bilježenje poruke na toj razini.

Ako Loggeru nije izričito dodijeljena razina, nasljeđuje razinu svog najbližeg pretka. Korijenski zapisnik je zadan na DEBUG. U nastavku ćemo vidjeti kako to poništiti.

5.2. Korištenje konteksta

Stvorimo primjer programa koji demonstrira upotrebu konteksta unutar hijerarhija bilježenja:

ch.qos.logback.classic.Logger parentLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback"); parentLogger.setLevel (Level.INFO); Dnevnik dnevnika zapisnika = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback.tests"); parentLogger.warn ("Ova je poruka zabilježena jer UPOZORENJE> INFO."); parentLogger.debug ("Ova poruka nije zabilježena jer DEBUG <INFO."); childlogger.info ("INFO == INFO"); childlogger.debug ("DEBUG <INFO"); 

Kada ovo pokrenemo, vidimo sljedeće poruke:

20: 31: 29.586 [glavna] UPOZORENJE com.baeldung.logback - Ova je poruka zabilježena jer UPOZORENJE> INFO. 20: 31: 29.594 [glavna] INFO com.baeldung.logback.tests - INFO == INFO

Počinjemo s dohvaćanjem a Drvosječa imenovan com.baeldung.logback i baci ga na a ch.qos.logback.classic.Logger.

Kontekst povratne informacije potreban je za postavljanje razine u sljedećem izrazu; imajte na umu da apstraktni loger SLF4J ne primjenjuje setLevel ().

Postavljamo razinu našeg konteksta na INFO;tada kreiramo još jedan zapisnik s imenom com.baeldung.logback.tests.

U svaki kontekst bilježimo dvije poruke da bismo demonstrirali hijerarhiju. Prijava zabilježi UPOZORITI, i INFO poruke i filtrira DEBUGporuke.

Sada, upotrijebimo matični zapisnik:

ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback"); logger.debug ("Bok!"); Dnevnik rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger (org.slf4j.Logger.ROOT_LOGGER_NAME); logger.debug ("Ova je poruka zabilježena jer DEBUG == DEBUG."); rootLogger.setLevel (Level.ERROR); logger.warn ("Ova poruka nije zabilježena jer WARN <ERROR."); logger.error ("Ovo je zabilježeno."); 

Ove poruke vidimo kad izvršimo ovaj isječak:

20: 44: 44.241 [glavna] DEBUG com.baeldung.logback - Bok! 20: 44: 44.243 [glavna] DEBUG com.baeldung.logback - Ova je poruka zabilježena jer je DEBUG == DEBUG. 20: 44: 44.243 [glavna] POGREŠKA com.baeldung.logback - Ovo je zabilježeno. 

Da zaključimo, započeli smo s Drvosječa kontekst i tiskan a DEBUG poruka.

Zatim smo dohvatili matični zapisnik koristeći njegovo statički definirano ime i postavili njegovu razinu na POGREŠKA.

I na kraju, pokazali smo da Logback zapravo filtrira bilo koji iskaz manje od pogreške.

5.3. Parametrirane poruke

Za razliku od poruka u gornjim uzorcima isječaka, najkorisnije poruke dnevnika zahtijevale su dodavanje Žice. To podrazumijeva dodjelu memorije, serializiranje objekata, spajanje Žice, i potencijalno čišćenje smeća kasnije.

Razmotrite sljedeću poruku:

log.debug ("Trenutni broj je" + broj); 

Snosimo troškove izrade poruke bez obzira bilježi li je Logger poruku ili ne.

Logback nudi alternativu sa svojim parametriziranim porukama:

log.debug ("Trenutni broj je {}", broj); 

Zagrade {} prihvaćaju sve Objekt i koristi svoje toString () metoda za izgradnju poruke tek nakon što provjerite je li potrebna poruka dnevnika.

Pokušajmo s nekoliko različitih parametara:

String message = "Ovo je niz"; Cijeli broj nula = 0; pokušajte {logger.debug ("Prijava dnevnika: {}", poruka); logger.debug ("Idemo podijeliti {} s {}", 42, nula); rezultat int = 42 / nula; } catch (Iznimka e) {logger.error ("Pogreška pri dijeljenju {} s {}", 42, nula, e); } 

Ovaj isječak daje:

21: 32: 10.311 [glavna] DEBUG com.baeldung.logback.LogbackTests - Prijava dnevnika: Ovo je niz 21: 32: 10.316 [glavna] DEBUG com.baeldung.logback.LogbackTests - Dijeljenje 42 s 0 21:32 : 10.316 [glavna] POGREŠKA com.baeldung.logback.LogbackTests - Pogreška pri dijeljenju 42 sa 0 java.lang.ArithmeticException: / s nulom na com.baeldung.logback.LogbackTests.givenParameters_ValuesLogged (LogbackTests.java:64) ... 

Vidimo kako a Niz, an int, i an Cijeli broj mogu se predati kao parametri.

Također, kada an Iznimka se prosljeđuje kao posljednji argument načinu evidentiranja, Logback će ispisati trag steka za nas.

6. Detaljna konfiguracija

U prethodnim primjerima koristili smo 11-linijsku konfiguracijsku datoteku koju smo stvorili u odjeljku 4 za ispis poruka dnevnika na konzolu. Ovo je zadano ponašanje Logback-a; ako ne može pronaći konfiguracijsku datoteku, kreira ConsoleAppender i povezuje ga s matičnim zapisnikom.

6.1. Pronalaženje podataka o konfiguraciji

Datoteka za konfiguraciju može se smjestiti u put predavanja i nazvati bilo kojim logback.xml ili logback-test.xml.

Evo kako će Logback pokušati pronaći podatke o konfiguraciji:

  1. Potražite datoteke s imenom logback-test.xml, logback.groovy,ili logback.xml u razrednoj stazi, tim redoslijedom.
  2. Ako knjižnica ne pronađe te datoteke, pokušat će koristiti Java ServiceLoader locirati implementatora com.qos.logback.classic.spi.Configurator.
  3. Konfigurirajte se tako da zapisuje izlaz izravno na konzolu

Napomena: trenutna verzija Logback-a ne podržava Groovy konfiguraciju jer ne postoji verzija Groovy-a kompatibilna s Java 9.

6.2. Osnovna konfiguracija

Pogledajmo bliže naš primjer konfiguracije.

Cijela datoteka je u oznake.

Vidimo oznaku koja proglašava Napadač tipa ConsoleAppender, i imenuje ga IZDAVANJE. Unutar te oznake nalazi se enkoder. Ima obrazac s onim što izgleda u sprintf stilu kodovi za bijeg:

  % d {HH: mm: ss.SSS} [% nit]% -5 nivo% zapisnika {36} -% msg% n 

Posljednje, vidimo a korijen označiti. Ova oznaka postavlja matični zapisnik na DEBUG modu i povezuje njegov izlaz s Napadač imenovan IZDAVANJE:

6.3. Rješavanje problema s konfiguracijom

Datoteke s konfiguracijom prijave mogu se zakomplicirati, tako da postoji nekoliko ugrađenih mehanizama za rješavanje problema.

Da biste vidjeli podatke o otklanjanju pogrešaka dok Logback obrađuje konfiguraciju, možete uključiti evidentiranje otklanjanja pogrešaka:

 ... 

Zapis će ispisati informacije o statusu na konzoli dok obrađuje konfiguraciju:

23: 54: 23,040 | -INFO u ch.qos.logback.classic.LoggerContext [zadano] - Pronađen resurs [logback-test.xml] na [file: / Users / egoebelbecker / ideaProjects / logback-guide / out / test / resources / logback-test.xml] 23: 54: 23,230 | -INFO u ch.qos.logback.core.joran.action.AppenderAction - O instanciranju dodavača tipa [ch.qos.logback.core.ConsoleAppender] 23: 54: 23,236 | -INFO u ch.qos.logback.core.joran.action.AppenderAction - Imenovanje dodavača kao [STDOUT] 23: 54: 23,247 | -INFO u ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pod pretpostavkom zadane vrste [ch.qos.logback.classic.encoder.PatternLayoutEncoder] za svojstvo [encoder] 23: 54: 23,308 | -INFO u ch.qos.logback.classic.joran.action.RootLoggerAction - Postavljanje razine ROOT zapisničara na DEBUG 23: 54: 23,309 | -INFO u ch.qos.logback.core.joran.action.AppenderRefAction - Pričvršćivanje dodataka s imenom [STDOUT] na Logger [ROOT] 23: 54: 23,310 | -INFO u ch.qos.logback. classic.joran.action.ConfigurationAction - Kraj konfiguracije. 23: 54: 23,313 | -INFO u [zaštićen e-poštom] - Registriranje trenutne konfiguracije kao sigurne rezervne točke

Ako se tijekom raščlanjivanja konfiguracijske datoteke nađu upozorenja ili pogreške, Logback na konzolu zapisuje statusne poruke.

Postoji drugi mehanizam za ispis informacija o statusu:

  ... 

The StatusListener presreće poruke o statusu i ispisuje ih tijekom konfiguracije i dok je program pokrenut.

Ispisuje se izlaz iz svih konfiguracijskih datoteka, što ga čini korisnim za lociranje "nevaljalih" konfiguracijskih datoteka na putu predavanja.

6.4. Automatsko ponovno učitavanje konfiguracije

Ponovno učitavanje konfiguracije evidentiranja dok je program pokrenut moćan je alat za rješavanje problema. Zabilježba to omogućuje s skenirati parametar:

 ... 

Zadano ponašanje je skeniranje konfiguracijske datoteke radi promjena svakih 60 sekundi. Izmijenite ovaj interval dodavanjem period skeniranja:

 ... 

Vrijednosti možemo odrediti u milisekundama, sekundama, minutama ili satima.

6.5. Modificiranje Sjekači

U našoj gornjoj datoteci uzorka postavili smo razinu root zapisnika i povezali ga s konzolom Napadač.

Možemo postaviti razinu za bilo koji zapisnik:

   % d {HH: mm: ss.SSS} [% nit]% -5 nivo% zapisnika {36} -% msg% n 

Dodajmo ovo u našu stazu do klasa i pokrenimo ovaj kod:

Foobar zapisnika = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.foobar"); Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback"); Logger testslogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback.tests"); foobar.debug ("Ovo se bilježi s foobar"); logger.debug ("Ovo se ne bilježi iz zapisnika"); logger.info ("Ovo se bilježi iz zapisnika"); testslogger.info ("Ovo se ne bilježi iz testova"); testslogger.warn ("Ovo se bilježi iz testova"); 

Vidimo ovaj rezultat:

00: 29: 51.787 [main] DEBUG com.baeldung.foobar - Ovo je zabilježeno s foobar 00: 29: 51.789 [main] INFO com.baeldung.logback - Ovo je zabilježeno iz logger 00: 29: 51.789 [main] WARN com .baeldung.logback.tests - Ovo se bilježi iz testova 

Ne postavljajući programsku razinu naših drvosječa, konfiguracija ih postavlja; com.baeldung.foobar nasljeđuje DEBUG iz matičnog zapisnika.

Sjekačitakođer naslijediti prilog-ref iz matičnog zapisnika. Kao što ćemo vidjeti u nastavku, ovo možemo poništiti.

6.6. Zamjena varijable

Datoteke za konfiguraciju povratnih podataka podržavaju varijable. Varijable definiramo unutar skripte za konfiguraciju ili eksterno. Varijabla se može navesti u bilo kojem trenutku u konfiguracijskoj skripti umjesto vrijednosti.

Na primjer, ovdje je konfiguracija za FileAppender:

  $ {LOG_DIR} /tests.log true% -4relative [% thread]% -5level% logger {35} -% msg% n 

Na vrhu konfiguracije proglasili smo imovineimenovan LOG_DIR.Zatim smo ga koristili kao dio putanje do datoteke unutar datoteke prilijepac definicija.

Svojstva su deklarirana u a oznaka u skriptama za konfiguraciju. Ali dostupni su i iz vanjskih izvora, poput svojstava sustava. Mogli bismo izostaviti imovine deklaraciji u ovom primjeru i postavite vrijednost LOG_DIR na naredbenom retku:

$ java -DLOG_DIR = / var / log / application com.baeldung.logback.LogbackTests

Vrijednost nekretnine određujemo s $ {ime_proizvoda}. Logback implementira varijable kao zamjenu teksta. Zamjena varijable može se dogoditi u bilo kojem trenutku u konfiguracijskoj datoteci gdje se može navesti vrijednost.

7. Dodaci

Sjekači proći LoggingEvents do Dodaci.Dodaci obaviti stvarni posao sječe. Obično o prijavi razmišljamo kao o nečemu što ide u datoteku ili konzolu, ali Prijava je sposobna za puno više. Jezgra povratka pruža nekoliko korisnih dodataka.

7.1. ConsoleAppender

Vidjeli smo ConsoleAppenderna djelu već. Unatoč svom imenu, ConsoleAppender dodaje poruke na System.outili System.err.

Koristi OutputStreamWriter kako bi međuspremnik U / I-a usmjerio na System.err ne rezultira nebuferiranim pisanjem.

7.2. FileAppender

FileAppenderdodaje datoteke u datoteku. Podržava širok raspon konfiguracijskih parametara. Dodajmo dodavač datoteke u našu osnovnu konfiguraciju:

    % d {HH: mm: ss.SSS} [% nit]% -5 nivoa% zapisnika {36} -% msg% n tests.log true% -4relativni [% nit]% -5 nivoa% prijavitelja {35} -% msg % n 

The FileAppender je konfiguriran s imenom datoteke putem . The oznaka upućuje Napadačda se doda postojećoj datoteci, a ne da je skrati. Ako test izvedemo nekoliko puta, vidimo da je izlaz za bilježenje dodan istoj datoteci.

Ako ponovno pokrenemo test odozgo, poruke od com.baeldung.logback.tests idite i na konzolu i na datoteku nazvanu tests.log. Dnevnik potomka nasljeđuje povezanost matičnog zapisnika sa ConsoleAppender sa svojom povezanošću sa FileAppender. Dodaci su kumulativni.

Možemo nadjačati ovo ponašanje:

Postavljanje aditivnost do lažnoonemogućava zadano ponašanje. Ispitivanja neće se prijaviti na konzolu, kao ni bilo tko od njezinih potomaka.

7.3. RollingFileAppender

Često dodavanje poruka dnevnika u istu datoteku nije ponašanje koje nam treba. Želimo da se datoteke "kotrljaju" na temelju vremena, veličine datoteke dnevnika ili njihove kombinacije.

Za ovo imamo RollingFileAppender:

  $ {LOG_FILE} .log $ {LOG_FILE}.% D {yyyy-MM-dd} .gz 30 3GB% -4relative [% thread]% -5level% logger {35} -% msg% n 

A RollingFileAppenderima RollingPolicy.U ovoj konfiguraciji uzorka vidimo TimeBasedRollingPolicy.

Slično kao FileAppender, konfigurirali smo ovaj dodatak s imenom datoteke. Proglasili smo svojstvo i koristili ga za to jer ćemo ponovno koristiti naziv datoteke u nastavku.

Mi definiramo a fileNamePattern unutar RollingPolicy.Ovaj obrazac definira ne samo naziv datoteka, već i koliko često ih valjati. TimeBasedRollingPolicyispituje uzorak i kotrlja se u najfinije definiranom razdoblju.

Na primjer:

   $ {LOG_DIR} / $ {LOG_FILE} .log $ {LOG_DIR} /% d {yyyy / MM} / $ {LOG_FILE} .gz 3 GB 

Aktivna datoteka dnevnika je / var / logs / application / LogFile.Ova se datoteka početkom svakog mjeseca prebacuje u / Tekuća godina / Trenutni mjesec / LogFile.gzi RollingFileAppender stvaranova aktivna datoteka.

Kada ukupna veličina arhiviranih datoteka dosegne 3 GB, RollingFileAppenderbriše arhive po principu "prvi u prvom izađe".

Postoje kodovi za tjedan, sat, minutu, sekundu, pa čak i milisekundu. Zapis ima ovdje referencu.

RollingFileAppendertakođer ima ugrađenu podršku za komprimiranje datoteka. Komprimira naše valjane datoteke jer ih je imenovao LogFile.gz.

Vremenski utemeljena politikanije naša jedina opcija za valjanje datoteka. Logback također nudi SizeAndTimeBasedRollingPolicy,koji će se pokretati na temelju trenutne veličine datoteke dnevnika, kao i vremena. Također nudi a FixedWindowRollingPolicykoja kotrlja nazive datoteka dnevnika svaki put kad se loger pokrene.

Možemo i sami napisati svoje RollingPolicy.

7.4. Prilagođeni dodaci

Možemo stvoriti prilagođene dodavače proširujući jednu od osnovnih klasa dodavača Logbacka. Ovdje imamo vodič za stvaranje prilagođenih dodataka.

8. Izgledi

Izgledi formatirati poruke dnevnika. Kao i ostatak Logback-a, Izgledisu proširivi i možemo stvoriti vlastite. Međutim, zadano PatternLayout nudi ono što većini aplikacija treba, a zatim i neke.

Koristili smo PatternLayout u svim našim dosadašnjim primjerima:

 % d {HH: mm: ss.SSS} [% nit]% -5 nivo% zapisnika {36} -% msg% n 

Ova skripta za konfiguraciju sadrži konfiguraciju za PatternLayoutEncoder.Prolazimo pored Davač našem Napadač,a ovaj koder koristi PatternLayout za formatiranje poruka.

Tekst u Oznaka definira način oblikovanja poruka dnevnika. PatternLayout implementira veliku raznolikost pretvorbenih riječi i modifikatora formata za stvaranje uzoraka.

Razbijemo ovu. PatternLayout prepoznaje riječi pretvorbe s%, pa pretvorbe u našem uzorku generiraju:

  • % d {VV: mm: ss.SSS} - vremensku oznaku sa satima, minutama, sekundama i milisekundama
  • [%nit] - naziv niti koja generira poruku dnevnika, okružena uglastim zagradama
  • % -5 razina - razina događaja zapisivanja, nadopunjena na 5 znakova
  • % zapisnik {36} - ime logera, skraćeno na 35 znakova
  • % msg% n - poruke dnevnika nakon kojih slijedi znak za razdvajanje linije ovisan o platformi

Dakle, vidimo poruke slične ovoj:

21: 32: 10.311 [glavna] DEBUG com.baeldung.logback.LogbackTests - Prijava dnevnika: Ovo je niz

Iscrpan popis riječi za pretvorbu i modifikatora formata možete pronaći ovdje.

9. Zaključak

U ovom opsežnom vodiču pokrili smo osnove korištenja prijave u aplikaciji.

Gledali smo tri glavne komponente u arhitekturi Logbacka: biljege, dodavače i izgled. Logback ima moćne konfiguracijske skripte pomoću kojih smo manipulirali komponentama za filtriranje i formatiranje poruka. Također smo pogledali dva najčešće korištena dodavača datoteka za stvaranje, prevrtanje, organiziranje i komprimiranje datoteka dnevnika.

Kao i obično, isječke koda možete pronaći na GitHubu.