En guide til tilbakekobling

1. Oversikt

Logback er en av de mest brukte loggerammene i Java-fellesskapet. Det er en erstatning for forgjengeren, Log4j. Logback tilbyr en raskere implementering enn Log4j, gir flere alternativer for konfigurasjon og mer fleksibilitet i arkivering av gamle loggfiler.

Denne introduksjonen vil introdusere Logbacks arkitektur og vise deg hvordan du kan bruke den til å gjøre applikasjonene dine bedre.

2. Tilbakekoblingsarkitektur

Tre klasser består av Logback-arkitekturen; Logger, Appender, og Oppsett.

En logger er en kontekst for loggmeldinger. Dette er klassen som applikasjoner samhandler med for å lage loggmeldinger.

Appenders plasserer loggmeldinger på sine endelige destinasjoner. En logger kan ha mer enn én appender. Vi tenker generelt på Appenders som knyttet til tekstfiler, men Logback er mye sterkere enn det.

Layout forbereder meldinger for utdata. Logback støtter opprettelsen av tilpassede klasser for formatering av meldinger, samt robuste konfigurasjonsalternativer for de eksisterende.

3. Oppsett

3.1. Maven avhengighet

Logback bruker Simple Logging Facade for Java (SLF4J) som sitt opprinnelige grensesnitt. Før vi kan begynne å logge meldinger, må vi legge til Logback og Slf4j i vår pom.xml:

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

Maven Central har den nyeste versjonen av Logback Core og den nyeste versjonen av slf4j-api.

3.2. Klassesti

Tilbakekobling krever også logback-classic.jar på klassestien for kjøretid.

Vi legger til dette i pom.xml som en testavhengighet:

 ch.qos.logback logback-classic 1.2.3 

4. Grunnleggende eksempel og konfigurasjon

La oss starte med et raskt eksempel på bruk av Logback i et program.

Først trenger vi en konfigurasjonsfil. Vi oppretter en tekstfil med navnet logback.xml og legg det et sted i klassestien vår:

   % d {HH: mm: ss.SSS} [% thread]% -5nivå% logger {36} -% msg% n 

Deretter trenger vi en enkel klasse med en hoved- metode:

public class Eksempel {private static final Logger logger = LoggerFactory.getLogger (Eksempel.klasse); public static void main (String [] args) {logger.info ("Eksemplerlogg fra {}", Example.class.getSimpleName ()); }}

Denne klassen skaper en Logger og ringer info () for å generere en loggmelding.

Når vi løper Eksempel vi ser meldingen vår logget på konsollen:

20: 34: 22.136 [main] INFO Eksempel - Eksempellogg fra eksempel

Det er lett å se hvorfor Logback er så populært; vi er i gang på få minutter.

Denne konfigurasjonen og koden gir oss noen tips om hvordan dette fungerer.

  1. Vi har en appender heter STDOUT som refererer til et kursnavn ConsoleAppender.
  2. Det er et mønster som beskriver formatet på loggmeldingen vår.
  3. Koden vår skaper en Logger og vi sendte meldingen vår til den via en info () metode.

Nå som vi forstår det grunnleggende, la oss se nærmere på det.

5. Logger Kontekster

5.1. Opprette en kontekst

For å logge en melding til Logback, initialiserte vi a Logger fra SLF4J eller Logback:

privat statisk slutt Logger logger = LoggerFactory.getLogger (Eksempel.klasse); 

Og så brukte den:

logger.info ("Eksempellogg fra {}", Example.class.getSimpleName ()); 

Dette er vår loggføringskontekst. Da vi skapte den, passerte vi LoggerFactory vår klasse. Dette gir Logger et navn (det er også en overbelastning som godtar en String).

Loggingskontekster eksisterer i et hierarki som ligner på Java-objekthierarkiet:

  1. En logger er en forfader når navnet, etterfulgt av en prikk, står foran et etterkommers loggers navn
  2. En logger er en forelder når det ikke er noen forfedre mellom den og et barn

For eksempel Eksempel klassen nedenfor er i com.baeldung.logback pakke. Det er en annen klasse som heter ExampleAppender i com.baeldung.logback.appenders pakke.

Eksempel på Appenders logger er et barn av Eksemplets logger.

Alle loggere er etterkommere av den forhåndsdefinerte rotloggeren.

EN Logger har en Nivå, som kan stilles inn enten via konfigurasjon eller med Logger.setLevel (). Innstilling av nivå i kode overstyrer konfigurasjonsfiler.

De mulige nivåene er i rekkefølge: SPOR, DEBUG, INFO, ADVARSEL og FEIL.Hvert nivå har en tilsvarende metode som vi bruker for å logge en melding på det nivået.

Hvis en logger ikke eksplisitt er tildelt et nivå, arver den nivået til sin nærmeste forfader. Rotloggeren er som standard DEBUG. Vi får se hvordan vi kan overstyre dette nedenfor.

5.2. Bruke en sammenheng

La oss lage et eksempelprogram som demonstrerer bruk av en kontekst i logghierarkier:

ch.qos.logback.classic.Logger parentLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback"); parentLogger.setLevel (Level.INFO); Logger childlogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback.tests"); parentLogger.warn ("Denne meldingen er logget fordi WARN> INFO."); parentLogger.debug ("Denne meldingen er ikke logget fordi DEBUG <INFO."); childlogger.info ("INFO == INFO"); childlogger.debug ("DEBUG <INFO"); 

Når vi kjører dette, ser vi disse meldingene:

20: 31: 29.586 [main] WARN com.baeldung.logback - Denne meldingen logges fordi WARN> INFO. 20: 31: 29.594 [main] INFO com.baeldung.logback.tests - INFO == INFO

Vi starter med å hente en Logger heter com.baeldung.logback og kast den til en ch.qos.logback.classic.Logger.

En Logback-kontekst er nødvendig for å sette nivået i neste uttalelse; Vær oppmerksom på at SLF4Js abstrakte logger ikke implementeres setLevel ().

Vi setter nivået på konteksten til INFO;så lager vi en annen logger som heter com.baeldung.logback.tests.

Vi logger to meldinger i hver kontekst for å demonstrere hierarkiet. Logback logger loggen VARSLE, og INFO meldinger og filtrerer DEBUGmeldinger.

La oss nå bruke rotloggeren:

ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger ("com.baeldung.logback"); logger.debug ("Hei!"); Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger (org.slf4j.Logger.ROOT_LOGGER_NAME); logger.debug ("Denne meldingen er logget fordi DEBUG == DEBUG."); rootLogger.setLevel (Level.ERROR); logger.warn ("Denne meldingen er ikke logget fordi WARN <FEIL."); logger.error ("Dette er logget."); 

Vi ser disse meldingene når vi utfører denne kodebiten:

20: 44: 44.241 [main] DEBUG com.baeldung.logback - Hei! 20: 44: 44.243 [main] DEBUG com.baeldung.logback - Denne meldingen er logget fordi DEBUG == DEBUG. 20: 44: 44.243 [main] FEIL com.baeldung.logback - Dette er logget. 

For å avslutte, startet vi med en Logger sammenheng og trykt a DEBUG beskjed.

Vi hentet deretter rotloggeren ved hjelp av det statisk definerte navnet og satte nivået til FEIL.

Og til slutt demonstrerte vi at Logback faktisk filtrerer noe utsagn mindre enn en feil.

5.3. Parameteriserte meldinger

I motsetning til meldingene i eksempelutdragene ovenfor, kreves det at de mest nyttige loggmeldingene legges til Strenger. Dette innebærer å tildele minne, serieisere objekter, sammenkoble Strenger, og muligens rydde opp søpla senere.

Tenk på følgende melding:

log.debug ("Nåværende antall er" + antall); 

Vi pådrar oss kostnadene for å bygge meldingen om loggeren logger meldingen eller ikke.

Logback tilbyr et alternativ med parametriserte meldinger:

log.debug ("Nåværende antall er {}", antall); 

Bøylene {} godtar alle Gjenstand og bruker sin toString () metode for å bygge en melding bare etter å ha bekreftet at loggmeldingen er nødvendig.

La oss prøve noen forskjellige parametere:

String message = "Dette er en streng"; Heltall null = 0; prøv {logger.debug ("Loggmelding: {}", melding); logger.debug ("Går til å dele {} med {}", 42, null); int resultat = 42 / null; } fange (Unntak e) {logger.error ("Feil å dele {} med {}", 42, null, e); } 

Denne kodebiten gir:

21: 32: 10.311 [main] DEBUG com.baeldung.logback.LogbackTests - Logging message: This is a String 21: 32: 10.316 [main] DEBUG com.baeldung.logback.LogbackTests - Going to divide 42 by 0 21:32 : 10.316 [main] FEIL com.baeldung.logback.LogbackTests - Feil med å dele 42 med 0 java.lang.ArithmeticException: / av null ved com.baeldung.logback.LogbackTests.givenParameters_ValuesLogged (LogbackTests.java:64) ... 

Vi ser hvordan en Streng, en int, og en Heltall kan sendes inn som parametere.

Også når en Unntak blir sendt som det siste argumentet til en loggningsmetode, vil Logback skrive ut stabelspor for oss.

6. Detaljert konfigurasjon

I de forrige eksemplene brukte vi 11-linjers konfigurasjonsfil som vi opprettet i avsnitt 4 for å skrive ut loggmeldinger til konsollen. Dette er Logbacks standard oppførsel; hvis den ikke finner en konfigurasjonsfil, oppretter den en ConsoleAppender og knytter den til rotloggeren.

6.1. Finne konfigurasjonsinformasjon

En konfigurasjonsfil kan plasseres i klassestien og få navnet enten logback.xml eller logback-test.xml.

Slik prøver Logback å finne konfigurasjonsdata:

  1. Søk etter filer som heter logback-test.xml, logback.groovy,eller logback.xml i klassestien, i den rekkefølgen.
  2. Hvis biblioteket ikke finner disse filene, vil det prøve å bruke Java-filer ServiceLoader for å finne en redaktør av com.qos.logback.classic.spi.Configurator.
  3. Konfigurer seg selv for å logge utdata direkte til konsollen

Merk: den nåværende versjonen av Logback støtter ikke Groovy-konfigurasjon fordi det ikke er en versjon av Groovy som er kompatibel med Java 9.

6.2. Grunnleggende konfigurasjon

La oss se nærmere på vår eksempelkonfigurasjon.

Hele filen er inne koder.

Vi ser en merkelapp som erklærer en Appender av typen ConsoleAppender, og navngir det STDOUT. Nestet i den koden er en koder. Den har et mønster med hvordan det ser ut sprintf-stil fluktkoder:

  % d {HH: mm: ss.SSS} [% thread]% -5nivå% logger {36} -% msg% n 

Sist, ser vi en rot stikkord. Denne koden setter rotloggeren til DEBUG modus og knytter utgangen til Appender heter STDOUT:

6.3. Feilsøking av konfigurasjon

Konfigurasjonsfiler for tilbakekobling kan bli kompliserte, så det er flere innebygde mekanismer for feilsøking.

For å se feilsøkingsinformasjon når Logback behandler konfigurasjonen, kan du slå på feilsøkingslogging:

 ... 

Logback vil skrive ut statusinformasjon til konsollen når den behandler konfigurasjonen:

23: 54: 23,040 | -INFO i ch.qos.logback.classic.LoggerContext [standard] - Fant ressurs [logback-test.xml] på [file: / Users / egoebelbecker / ideaProjects / logback-guide / out / test / resources / logback-test.xml] 23: 54: 23,230 | -INFO i ch.qos.logback.core.joran.action.AppenderAction - Omtrent å instantiere appender av typen [ch.qos.logback.core.ConsoleAppender] 23: 54: 23,236 | -INFO i ch.qos.logback.core.joran.action.AppenderAction - Navngi appender som [STDOUT] 23: 54: 23,247 | -INFO i ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Forutsatt standard type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] eiendom 23: 54: 23,308 | -INFO i ch.qos.logback.classic.joran.action.RootLoggerAction - Innstillingsnivå for ROOT logger til DEBUG 23: 54: 23,309 | -INFO i ch.qos.logback.core.joran.action.AppenderRefAction - Feste appender kalt [STDOUT] til Logger [ROOT] 23: 54: 23,310 | -INFO i ch.qos.logback. classic.joran.action.ConfigurationAction - Konfigurasjons slutt. 23: 54: 23,313 | -INFO i [e-postbeskyttet] - Registrering av gjeldende konfigurasjon som trygt tilbakepunkt

Hvis det oppstår advarsler eller feil mens du analyserer konfigurasjonsfilen, skriver Logback statusmeldinger til konsollen.

Det er en annen mekanisme for utskrift av statusinformasjon:

  ... 

De StatusListener avlytter statusmeldinger og skriver dem ut under konfigurering og mens programmet kjører.

Utdataene fra alle konfigurasjonsfiler skrives ut, noe som gjør det nyttig for å finne “useriøse” konfigurasjonsfiler på klassestien.

6.4. Last inn konfigurasjon automatisk

Å laste loggkonfigurasjonen på nytt mens et program kjører, er et kraftig feilsøkingsverktøy. Tilbakekobling gjør dette mulig med skanne parameter:

 ... 

Standard oppførsel er å skanne konfigurasjonsfilen for endringer hvert 60. sekund. Endre dette intervallet ved å legge til scanPeriod:

 ... 

Vi kan spesifisere verdier i millisekunder, sekunder, minutter eller timer.

6.5. Endrer Loggere

I eksempelfilen vår ovenfor setter vi nivået på rotloggeren og knytter det til konsollen Appender.

Vi kan sette nivået for hvilken som helst logger:

   % d {HH: mm: ss.SSS} [% thread]% -5nivå% logger {36} -% msg% n 

La oss legge til dette i klassestien vår og kjøre denne koden:

Logger foobar = (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 ("Dette er logget fra foobar"); logger.debug ("Dette er ikke logget fra logger"); logger.info ("Dette er logget fra logger"); testslogger.info ("Dette er ikke logget fra tester"); testslogger.warn ("Dette er logget fra tester"); 

Vi ser denne utgangen:

00: 29: 51.787 [main] DEBUG com.baeldung.foobar - Dette logges fra foobar 00: 29: 51.789 [main] INFO com.baeldung.logback - Dette logges fra logger 00: 29: 51.789 [main] WARN com .baeldung.logback.tests - Dette logges fra tester 

Ved ikke å angi nivået på loggerne våre programmatisk, angir konfigurasjonen dem; com.baeldung.foobar arver DEBUG fra rotloggeren.

Loggerearver også appender-ref fra rotloggeren. Som vi får se nedenfor, kan vi overstyre dette.

6.6. Variabel erstatning

Konfigurasjonsfiler for tilbakekobling støtter variabler. Vi definerer variabler inne i konfigurasjonsskriptet eller eksternt. En variabel kan spesifiseres når som helst i et konfigurasjonsskript i stedet for en verdi.

Her er for eksempel konfigurasjonen for a FileAppender:

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

Øverst i konfigurasjonen erklærte vi a eiendomheter LOG_DIR.Så brukte vi det som en del av banen til filen inne i appender definisjon.

Eiendommer er deklarert i a tag i konfigurasjonsskript. Men de er også tilgjengelige fra eksterne kilder, for eksempel systemegenskaper. Vi kunne utelate eiendom erklæring i dette eksemplet og angi verdien på LOG_DIR på kommandolinjen:

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

Vi spesifiserer verdien på eiendommen med $ {propertyname}. Logback implementerer variabler som tekstutskifting. Variabel erstatning kan forekomme når som helst i en konfigurasjonsfil der en verdi kan spesifiseres.

7. Appenders

Loggere sende LoggingEvents til Appenders.Appenders gjøre selve loggarbeidet. Vi tenker vanligvis på logging som noe som går til en fil eller konsoll, men Logback er i stand til mye mer. Tilbakekjøringskjerne gir flere nyttige appenders.

7.1. ConsoleAppender

Vi har sett ConsoleAppenderi aksjon allerede. Til tross for navnet sitt, ConsoleAppender legger meldinger til System.outeller System.err.

Den bruker en OutputStreamWriter for å buffer I / O, så dirigere den til System.err resulterer ikke i ubuffert skriving.

7.2. FileAppender

FileAppenderlegger til meldinger i en fil. Den støtter et bredt spekter av konfigurasjonsparametere. La oss legge til en filtillegg i vår grunnleggende konfigurasjon:

    % d {HH: mm: ss.SSS} [% thread]% -5nivå% logger {36} -% msg% n tests.log true% -4relativ [% thread]% -5nivå% logger {35} -% msg % n 

De FileAppender er konfigurert med et filnavn via . De tag instruerer Appenderå legge til en eksisterende fil i stedet for å kutte den. Hvis vi kjører testen flere ganger, ser vi at loggoutdataene er lagt til den samme filen.

Hvis vi kjører testen vår ovenfra, meldinger fra com.baeldung.logback.tests gå til både konsollen og til en fil som heter tests.log. Den etterkommende loggeren arver rotloggerens tilknytning til ConsoleAppender med sin tilknytning til FileAppender. Appenders er kumulative.

Vi kan overstyre denne oppførselen:

Omgivelser additivitet til falskdeaktiverer standard oppførsel. Tester vil ikke logge på konsollen, og heller ikke noen av dens etterkommere.

7.3. RollingFileAppender

Ofte er det ikke oppførselen vi trenger å legge til loggmeldinger i den samme filen. Vi ønsker at filer skal "rulle" basert på tid, loggfilstørrelse eller en kombinasjon av begge.

For dette har vi RollingFileAppender:

  $ {LOG_FILE} .log $ {LOG_FILE}.% D {åååå-MM-dd} .gz 30 3 GB% -4relativ [% tråd]% -5nivå% logger {35} -% msg% n 

EN RollingFileAppenderhar en RollingPolicy.I denne eksempelkonfigurasjonen ser vi a TimeBasedRollingPolicy.

I likhet med FileAppender, vi konfigurerte denne appenderen med et filnavn. Vi erklærte en eiendom og brukte den til dette fordi vi vil bruke filnavnet nedenfor.

Vi definerer en fileNamePattern inne i RollingPolicy.Dette mønsteret definerer ikke bare navnet på filer, men også hvor ofte de skal rulles. TimeBasedRollingPolicyundersøker mønsteret og ruller i den fineste perioden.

For eksempel:

   $ {LOG_DIR} / $ {LOG_FILE} .logg $ {LOG_DIR} /% d {åååå / MM} / $ {LOG_FILE} .gz 3 GB 

Den aktive loggfilen er / var / logs / application / LogFile.Denne filen ruller over i begynnelsen av hver måned til / Gjeldende år / Gjeldende måned / LogFile.gzog RollingFileAppender skaperen ny aktiv fil.

Når den totale størrelsen på arkiverte filer når 3 GB, RollingFileAppendersletter arkiver på først-inn-først ut-basis.

Det er koder for en uke, time, minutt, sekund og til og med millisekund. Logback har en referanse her.

RollingFileAppenderhar også innebygd støtte for komprimering av filer. Den komprimerer de rullede filene våre fordi de heter dem LogFile.gz.

TimeBasedPolicyer ikke vårt eneste alternativ for rulling av filer. Logback tilbyr også SizeAndTimeBasedRollingPolicy,som vil rulle basert på gjeldende loggfilstørrelse samt tid. Det tilbyr også en FixedWindowRollingPolicysom ruller loggfilnavnene hver gang loggeren startes.

Vi kan også skrive våre egne RollingPolicy.

7.4. Tilpassede appenders

Vi kan opprette tilpassede appenders ved å utvide en av Logbacks basale appender-klasser. Vi har en veiledning for å lage tilpassede appenders her.

8. Oppsett

Oppsett formatere loggmeldinger. Som resten av Logback, Oppsetter utvidbare, og vi kan lage våre egne. Imidlertid er standard Mønsteroppsett tilbyr det de fleste applikasjoner trenger og deretter noen.

Vi har brukt Mønsteroppsett i alle eksemplene våre så langt:

 % d {HH: mm: ss.SSS} [% thread]% -5nivå% logger {36} -% msg% n 

Dette konfigurasjonsskriptet inneholder konfigurasjonen for PatternLayoutEncoder.Vi passerer en Koder til vår Appender,og denne koderen bruker Mønsteroppsett for å formatere meldingene.

Teksten i tag definerer hvordan loggmeldinger formateres. Mønsteroppsett implementerer et stort utvalg av konverteringsord og formatmodifikatorer for å lage mønstre.

La oss bryte ned denne. Mønsteroppsett gjenkjenner konverteringsord med%, slik at konverteringene i mønsteret vårt genererer:

  • % d {HH: mm: ss.SSS} - et tidsstempel med timer, minutter, sekunder og millisekunder
  • [%tråd] - trådnavnet som genererer loggmeldingen, omgitt av firkantede parenteser
  • % -5nivå - nivået på logghendelsen, polstret til 5 tegn
  • % logger {36} - navnet på loggeren, avkortet til 35 tegn
  • % msg% n - loggmeldingene etterfulgt av det plattformavhengige linjeseparatortegnet

Så vi ser meldinger som ligner på dette:

21: 32: 10.311 [main] DEBUG com.baeldung.logback.LogbackTests - Loggmelding: Dette er en streng

En uttømmende liste over konverteringsord og formatmodifikatorer finner du her.

9. Konklusjon

I denne omfattende veiledningen dekket vi grunnleggende om å bruke Logback i et program.

Vi så på de tre hovedkomponentene i Logbacks arkitektur: loggere, appenders og layout. Logback har kraftige konfigurasjonsskript, som vi brukte til å manipulere komponenter for filtrering og formatering av meldinger. Vi så også på de to mest brukte filtilleggene for å opprette, rulle over, organisere og komprimere loggfiler.

Som vanlig kan du finne kodebiter på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found