En guide til logback

1. Oversigt

Logback er en af ​​de mest anvendte logningsrammer i Java Community. Det er en erstatning for sin forgænger, Log4j. Logback tilbyder en hurtigere implementering end Log4j, giver flere muligheder for konfiguration og mere fleksibilitet i arkivering af gamle logfiler.

Denne introduktion introducerer Logbacks arkitektur og viser dig, hvordan du kan bruge den til at gøre dine applikationer bedre.

2. Logback-arkitektur

Tre klasser omfatter Logback-arkitekturen; Logger, Appenderog Layout.

En logger er en kontekst for logmeddelelser. Dette er den klasse, som applikationer interagerer med for at oprette logmeddelelser.

Appenders placerer logbeskeder på deres endelige destinationer. En logger kan have mere end en appender. Vi tænker generelt på Appenders som knyttet til tekstfiler, men Logback er meget mere potent end det.

Layout forbereder meddelelser til udsendelse. Logback understøtter oprettelsen af ​​brugerdefinerede klasser til formatering af meddelelser samt robuste konfigurationsmuligheder for de eksisterende.

3. Opsætning

3.1. Maven afhængighed

Logback bruger Simple Logging Facade til Java (SLF4J) som sin oprindelige grænseflade. Inden vi kan begynde at logge beskeder, skal vi tilføje Logback og Slf4j til vores pom.xml:

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

Maven Central har den nyeste version af Logback Core og den nyeste version af slf4j-api.

3.2. Klassesti

Logback kræver også logback-classic.jar på klassestien til runtime.

Vi tilføjer dette til pom.xml som en testafhængighed:

 ch.qos.logback logback-classic 1.2.3 

4. Grundlæggende eksempel og konfiguration

Lad os starte med et hurtigt eksempel på brug af Logback i en applikation.

For det første har vi brug for en konfigurationsfil. Vi opretter en tekstfil med navnet logback.xml og læg det et eller andet sted på vores klassesti:

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

Dernæst har vi brug for en simpel klasse med en vigtigste metode:

offentlig klasse Eksempel {privat statisk endelig Logger logger = LoggerFactory.getLogger (Eksempel.klasse); public static void main (String [] args) {logger.info ("Eksempel log fra {}", Example.class.getSimpleName ()); }}

Denne klasse skaber en Logger og opkald info () for at generere en logmeddelelse.

Når vi løber Eksempel vi ser vores besked logget på konsollen:

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

Det er let at se, hvorfor Logback er så populært; vi kører på få minutter.

Denne konfiguration og kode giver os et par tip til, hvordan dette fungerer.

  1. Vi har en appender som hedder STDOUT der refererer til et holdnavn ConsoleAppender.
  2. Der er et mønster, der beskriver formatet på vores logmeddelelse.
  3. Vores kode skaber en Logger og vi sendte vores besked til det via en info () metode.

Nu hvor vi forstår det grundlæggende, lad os se nærmere på det.

5. Logger Kontekster

5.1. Oprettelse af en kontekst

For at logge en besked til Logback initialiserede vi a Logger fra SLF4J eller Logback:

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

Og brugte det derefter:

logger.info ("Eksempel log fra {}", Eksempel.class.getSimpleName ()); 

Dette er vores logningskontekst. Da vi skabte det, gik vi forbi LoggerFabrik vores klasse. Dette giver Logger et navn (der er også en overbelastning, der accepterer en Snor).

Loggingskontekster findes i et hierarki, der minder meget om Java-objekthierarkiet:

  1. En logger er en forfader, når dens navn efterfulgt af en prik foran en efterkommer loggers navn
  2. En logger er forælder, når der ikke er nogen forfædre mellem den og et barn

F.eks Eksempel klasse nedenfor er i com.baeldung.logback pakke. Der er en anden klasse ved navn EksempelAppender i com.baeldung.logback.appenders pakke.

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

Alle loggere er efterkommere af den foruddefinerede rodlogger.

EN Logger har en Niveau, som kan indstilles enten via konfiguration eller med Logger.setLevel (). Indstilling af niveau i kode tilsidesætter konfigurationsfiler.

De mulige niveauer er i rækkefølge: TRACE, DEBUG, INFO, ADVARSEL og FEJL.Hvert niveau har en tilsvarende metode, som vi bruger til at logge en besked på det niveau.

Hvis en logger ikke eksplicit tildeles et niveau, arver den niveauet for sin nærmeste forfader. Rodloggeren er som standard FEJLFINDE. Vi får se, hvordan du tilsidesætter dette nedenfor.

5.2. Brug af en sammenhæng

Lad os oprette et eksempelprogram, der demonstrerer ved hjælp af en kontekst inden for logningshierarkier:

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 meddelelse er logget fordi WARN> INFO."); parentLogger.debug ("Denne meddelelse er ikke logget, fordi DEBUG <INFO."); childlogger.info ("INFO == INFO"); childlogger.debug ("DEBUG <INFO"); 

Når vi kører dette, ser vi disse meddelelser:

20: 31: 29.586 [main] WARN com.baeldung.logback - Denne meddelelse er logget, fordi WARN> INFO. 20: 31: 29.594 [main] INFO com.baeldung.logback.tests - INFO == INFO

Vi starter med at hente en Logger som hedder com.baeldung.logback og kast det til en ch.qos.logback.classic.Logger.

En Logback-kontekst er nødvendig for at indstille niveauet i den næste sætning; bemærk, at SLF4Js abstrakte logger ikke implementeres setLevel ().

Vi indstiller niveauet for vores kontekst til INFO;vi opretter derefter en anden logger med navnet com.baeldung.logback.tests.

Vi logger to meddelelser med hver kontekst for at demonstrere hierarkiet. Logback logger ADVARE, og INFO beskeder og filtrerer FEJLFINDEBeskeder.

Lad os nu bruge rodloggeren:

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

Vi ser disse meddelelser, når vi udfører dette uddrag:

20: 44: 44.241 [main] DEBUG com.baeldung.logback - Hej der! 20: 44: 44.243 [main] DEBUG com.baeldung.logback - Denne meddelelse er logget, fordi DEBUG == DEBUG. 20: 44: 44.243 [main] FEJL com.baeldung.logback - Dette er logget. 

Afslutningsvis startede vi med en Logger sammenhæng og trykt a FEJLFINDE besked.

Vi hentede derefter rodloggeren ved hjælp af dens statisk definerede navn og indstillede dens niveau til FEJL.

Og endelig demonstrerede vi, at Logback faktisk filtrerer ethvert udsagn mindre end en fejl.

5.3. Parameteriserede meddelelser

I modsætning til meddelelserne i eksemplet ovenfor, kræves det, at de mest nyttige logmeddelelser tilføjes Strenge. Dette indebærer at allokere hukommelse, serieoprette objekter, sammenkæde Strenge, og muligvis rense affaldet senere.

Overvej følgende meddelelse:

log.debug ("Nuværende antal er" + antal); 

Vi afholder omkostningerne ved at oprette meddelelsen, uanset om loggeren logger meddelelsen eller ej.

Logback tilbyder et alternativ med sine parametriserede meddelelser:

log.debug ("Nuværende antal er {}", antal); 

Bøjlerne {} accepterer enhver Objekt og bruger sin toString () metode til kun at oprette en besked efter at have bekræftet, at logbeskeden er påkrævet.

Lad os prøve nogle forskellige parametre:

String message = "Dette er en streng"; Heltal nul = 0; prøv {logger.debug ("Logningsmeddelelse: {}", besked); logger.debug ("Går til at dele {} med {}", 42, nul); int-resultat = 42 / nul; } fange (Undtagelse e) {logger.error ("Fejl ved at dele {} med {}", 42, nul, e); } 

Dette uddrag giver:

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] FEJL com.baeldung.logback.LogbackTests - Fejl divideret 42 med 0 java.lang.ArithmeticException: / ved nul ved com.baeldung.logback.LogbackTests.givenParameters_ValuesLogged (LogbackTests.java:64) ... 

Vi ser, hvordan en Snor, en int, og en Heltal kan overføres som parametre.

Også når en Undtagelse sendes som det sidste argument til en logningsmetode, vil Logback udskrive stacksporingen for os.

6. Detaljeret konfiguration

I de foregående eksempler brugte vi 11-linjers konfigurationsfil, som vi oprettede i afsnit 4 til at udskrive logmeddelelser til konsollen. Dette er Logbacks standardadfærd; hvis den ikke kan finde en konfigurationsfil, opretter den en ConsoleAppender og knytter det til rodloggeren.

6.1. Find konfigurationsoplysninger

En konfigurationsfil kan placeres i klassestien og navngives enten logback.xml eller logback-test.xml.

Sådan forsøger Logback at finde konfigurationsdata:

  1. Søg efter filer, der er navngivet logback-test.xml, logback.groovy,eller logback.xml i klassestien i den rækkefølge.
  2. Hvis biblioteket ikke finder disse filer, vil det forsøge at bruge Java'er ServiceLoader at finde en implementer af com.qos.logback.classic.spi.Configurator.
  3. Konfigurer sig selv til at logge output direkte til konsollen

Bemærk: den aktuelle version af Logback understøtter ikke Groovy-konfiguration, fordi der ikke er en version af Groovy, der er kompatibel med Java 9.

6.2. Grundlæggende konfiguration

Lad os se nærmere på vores eksempelkonfiguration.

Hele filen er inde tags.

Vi ser et mærke, der erklærer en Appender af typen ConsoleAppenderog navngiver det STDOUT. Indlejret i dette mærke er en indkoder. Det har et mønster med, hvordan det ser ud sprintf-stil flugtkoder:

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

Til sidst ser vi en rod tag. Dette tag indstiller rodloggeren til FEJLFINDE tilstand og knytter dets output til Appender som hedder STDOUT:

6.3. Fejlfindingskonfiguration

Logback-konfigurationsfiler kan blive komplicerede, så der er flere indbyggede mekanismer til fejlfinding.

For at se fejlretningsoplysninger, når Logback behandler konfigurationen, kan du slå fejlretningslogning til:

 ... 

Logback udskriver statusoplysninger til konsollen, når den behandler konfigurationen:

23: 54: 23,040 | -INFO i ch.qos.logback.classic.LoggerContext [standard] - Fundet ressource [logback-test.xml] ved [fil: / Brugere / egoebelbecker / idéProjekter / logback-guide / out / test / ressourcer / logback-test.xml] 23: 54: 23,230 | -INFO i ch.qos.logback.core.joran.action.AppenderAction - Om at instantiere appender af typen [ch.qos.logback.core.ConsoleAppender] 23: 54: 23,236 | -INFO i ch.qos.logback.core.joran.action.AppenderAction - Navngiv appender som [STDOUT] 23: 54: 23,247 | -INFO i ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Under forudsætning af standardtype [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] egenskab 23: 54: 23,308 | -INFO i ch.qos.logback.classic.joran.action.RootLoggerAction - Indstil niveau for ROOT logger til DEBUG 23: 54: 23,309 | -INFO i ch.qos.logback.core.joran.action.AppenderRefAction - Vedhæftning af appender ved navn [STDOUT] til Logger [ROOT] 23: 54: 23,310 | -INFO i ch.qos.logback. classic.joran.action.ConfigurationAction - Konfigurationsslut. 23: 54: 23,313 | -INFO i [e-mail-beskyttet] - Registrering af den aktuelle konfiguration som sikkert reservepunkt

Hvis der opstår advarsler eller fejl under parsing af konfigurationsfilen, skriver Logback statusmeddelelser til konsollen.

Der er en anden mekanisme til udskrivning af statusoplysninger:

  ... 

Det StatusListener aflytter statusmeddelelser og udskriver dem under konfigurationen, og mens programmet kører.

Outputtet fra alle konfigurationsfiler udskrives, hvilket gør det nyttigt til at finde “rogue” konfigurationsfiler på klassestien.

6.4. Genindlæser konfiguration automatisk

Genindlæsning af logningskonfiguration, mens et program kører, er et effektivt fejlfindingsværktøj. Logback gør dette muligt med scanning parameter:

 ... 

Standardadfærden er at scanne konfigurationsfilen for ændringer hvert 60. sekund. Rediger dette interval ved at tilføje scanPeriod:

 ... 

Vi kan specificere værdier i millisekunder, sekunder, minutter eller timer.

6.5. Ændring Loggere

I vores eksempelfil ovenfor indstiller vi niveauet for rodloggeren og knytter det til konsollen Appender.

Vi kan indstille niveauet for enhver logger:

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

Lad os tilføje dette til vores klassesti og køre denne kode:

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 tests"); testslogger.warn ("Dette er logget fra tests"); 

Vi ser denne output:

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 er logget fra tests 

Ved ikke at indstille niveauet for vores loggere programmatisk, indstiller konfigurationen dem; com.baeldung.foobar arver FEJLFINDE fra rodloggeren.

Loggereogså arve appender-ref fra rodloggeren. Som vi ser nedenfor, kan vi tilsidesætte dette.

6.6. Variabel udskiftning

Logback-konfigurationsfiler understøtter variabler. Vi definerer variabler inde i konfigurationsscriptet eller eksternt. En variabel kan angives til enhver tid i et konfigurationsscript i stedet for en værdi.

For eksempel er her konfigurationen for en FileAppender:

  $ {LOG_DIR} /tests.log sand% -4relativ [% tråd]% -5niveau% logger {35} -% msg% n 

Øverst i konfigurationen erklærede vi en ejendomsom hedder LOG_DIR.Derefter brugte vi det som en del af stien til filen inde i appender definition.

Ejendomme er angivet i a tag i konfigurationsscripts. Men de er også tilgængelige fra eksterne kilder, såsom systemegenskaber. Vi kunne udelade ejendom erklæring i dette eksempel og indstil værdien af LOG_DIR på kommandolinjen:

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

Vi specificerer ejendommens værdi med $ {propertyname}. Logback implementerer variabler som udskiftning af tekst. Variabel erstatning kan forekomme når som helst i en konfigurationsfil, hvor en værdi kan specificeres.

7. Appenders

Loggere passere LoggingEvents til Appenders.Appenders udføre det egentlige arbejde med at logge. Vi tænker normalt på logning som noget, der går til en fil eller konsollen, men Logback er i stand til meget mere. Logback-kerne giver flere nyttige appenders.

7.1. ConsoleAppender

Vi har set ConsoleAppenderallerede i aktion. Trods sit navn, ConsoleAppender tilføjer beskeder til System.outeller System.err.

Det bruger en OutputStreamWriter at buffer I / O, så dirigere den til System.err resulterer ikke i ubuffert skrivning.

7.2. FileAppender

FileAppendertilføjer meddelelser til en fil. Det understøtter en bred vifte af konfigurationsparametre. Lad os tilføje en filappender til vores grundlæggende konfiguration:

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

Det FileAppender er konfigureret med et filnavn via . Det tag instruerer Appenderat føje til en eksisterende fil i stedet for at afkorte den. Hvis vi kører testen flere gange, ser vi, at loggeoutputtet føjes til den samme fil.

Hvis vi genkører vores test ovenfra, meddelelser fra com.baeldung.logback.tests gå til både konsollen og til en fil med navnet tests.log. Den efterfølgende logger arver rodloggerens tilknytning til ConsoleAppender med dets tilknytning til FileAppender. Appenders er kumulative.

Vi kan tilsidesætte denne adfærd:

Indstilling additivitet til falskdeaktiverer standardadfærd. Test logger ikke på konsollen, og heller ikke nogen af ​​dens efterkommere.

7.3. RollingFileAppender

Ofte er det ikke den adfærd, vi har brug for, at tilføje logbeskeder til den samme fil. Vi ønsker, at filer skal "rulle" baseret på tid, logfilstørrelse eller en kombination af begge.

Til dette har vi RollingFileAppender:

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

EN RollingFileAppenderhar en Rullende politik.I denne eksempelkonfiguration ser vi a TimeBasedRollingPolicy.

Svarende til FileAppender, vi konfigurerede denne appender med et filnavn. Vi erklærede en ejendom og brugte den til dette, fordi vi genbruger filnavnet nedenfor.

Vi definerer en fileNamePattern inde i Rullende politik.Dette mønster definerer ikke kun navnet på filer, men også hvor ofte de skal rulles. TimeBasedRollingPolicyundersøger mønsteret og ruller i den finest definerede periode.

For eksempel:

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

Den aktive logfil er / var / logs / application / LogFile.Denne fil rulles over i begyndelsen af ​​hver måned til / Nuværende år / Nuværende måned / LogFile.gzog RollingFileAppender skaberen ny aktiv fil.

Når den samlede størrelse af arkiverede filer når 3 GB, RollingFileAppendersletter arkiver på først-til-første-ud-basis.

Der er koder i en uge, time, minut, sekund og endda millisekund. Logback har en reference her.

RollingFileAppenderhar også indbygget support til komprimering af filer. Det komprimerer vores rullede filer, fordi navngivet vores dem LogFile.gz.

TimeBasedPolicyer ikke vores eneste mulighed for rullende filer. Logback tilbyder også Størrelse og tidBaseret rullende politik,som vil rulle baseret på den aktuelle logfilstørrelse samt tid. Det tilbyder også en FixedWindowRollingPolicysom ruller logfilnavne hver gang loggeren startes.

Vi kan også skrive vores egne Rullende politik.

7.4. Brugerdefinerede appenders

Vi kan oprette brugerdefinerede appenders ved at udvide en af ​​Logbacks basale appender-klasser. Vi har en tutorial til oprettelse af brugerdefinerede appenders her.

8. Layouter

Layouter formatere logbeskeder. Ligesom resten af ​​Logback, Layouterer udvidelige, og vi kan skabe vores egne. Dog standard Mønsterlayout tilbyder, hvad de fleste applikationer har brug for, og derefter nogle.

Vi har brugt Mønsterlayout i alle vores eksempler hidtil:

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

Dette konfigurationsscript indeholder konfigurationen til PatternLayoutEncoder.Vi passerer en Koder til vores Appender,og denne indkoder bruger Mønsterlayout for at formatere beskederne.

Teksten i tag definerer, hvordan logmeddelelser formateres. Mønsterlayout implementerer et stort udvalg af konverteringsord og formatmodifikatorer til oprettelse af mønstre.

Lad os nedbryde denne. Mønsterlayout genkender konverteringsord med%, så konverteringerne i vores mønster genererer:

  • % d {HH: mm: ss.SSS} - et tidsstempel med timer, minutter, sekunder og millisekunder
  • [%tråd] - trådnavnet, der genererer logbeskeden, omgivet af firkantede parenteser
  • % -5niveau - niveauet for logningshændelsen, polstret til 5 tegn
  • % logger {36} - loggerens navn, afkortet til 35 tegn
  • % msg% n - logmeddelelserne efterfulgt af det platformafhængige linjeseparatortegn

Så vi ser beskeder svarende til dette:

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

En udtømmende liste over konverteringsord og formatmodifikatorer kan findes her.

9. Konklusion

I denne omfattende vejledning dækkede vi det grundlæggende ved at bruge Logback i en applikation.

Vi kiggede på de tre hovedkomponenter i Logbacks arkitektur: loggere, appenders og layout. Logback har kraftige konfigurationsskripter, som vi brugte til at manipulere komponenter til filtrering og formatering af meddelelser. Vi kiggede også på de to mest anvendte filtilhængere til at oprette, rulle over, organisere og komprimere logfiler.

Som sædvanligt kan kodeuddrag findes på GitHub.


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