Introduktion til Log4j2 - Appenders, Layouts og Filtre

1. Oversigt

Logning af begivenheder er et kritisk aspekt af softwareudvikling. Mens der er mange rammer tilgængelige i Java-økosystemet, har Log4J været det mest populære i årtier på grund af den fleksibilitet og enkelhed, det giver.

Log4j 2 er en ny og forbedret version af den klassiske Log4j-ramme.

I denne artikel introducerer vi de mest almindelige appenders, layouts og filtre via praktiske eksempler.

I Log4J2 er en appender simpelthen en destination for logbegivenheder; det kan være så simpelt som en konsol og kan være komplekst som enhver RDBMS. Layouter bestemmer, hvordan logfilerne skal præsenteres, og filtre filtrerer dataene efter de forskellige kriterier.

2. Opsætning

For at forstå flere logningskomponenter og deres konfiguration, lad os oprette forskellige testanvendelsestilfælde, der hver består af en log4J2.xml konfigurationsfil og en JUnit 4 test klasse.

To maven-afhængigheder er fælles for alle eksempler:

 org.apache.logging.log4j log4j-core 2.7 org.apache.logging.log4j log4j-core 2.7 test-jar test 

Udover det vigtigste log4j-kerne pakke skal vi inkludere 'test jar', der hører til pakken for at få adgang til en kontekstregel, der er nødvendig til test af ikke-almindeligt navngivne konfigurationsfiler.

3. Standardkonfiguration

ConsoleAppender er standardkonfigurationen af Log4J 2 kernepakke. Det logger meddelelser til systemkonsollen i et simpelt mønster:

Lad os analysere tags i denne enkle XML-konfiguration:

  • Konfiguration: Grundelementet i en Log4J 2 konfigurationsfil og attribut status er niveauet for de interne Log4J-begivenheder, som vi vil logge på
  • Appenders: Dette element holder en eller flere appenders. Her konfigurerer vi en appender, der output til systemkonsollen som standard ud
  • Loggere: Dette element kan bestå af flere konfigurerede Logger elementer. Med det specielle Rod tag, kan du konfigurere en navnløs standardlogger, der modtager alle logbeskeder fra applikationen. Hver logger kan indstilles til et minimum logniveau
  • AppenderRef: Dette element definerer en henvisning til et element fra Appenders afsnit. Derfor attributten 'ref'Er knyttet til en appenders'navn'Attribut

Den tilsvarende enhedstest vil være tilsvarende enkel. Vi får en Logger reference og udskrive to meddelelser:

@Test offentlig ugyldighed givenLoggerWithDefaultConfig_whenLogToConsole_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger (getClass ()); Undtagelse e = ny RuntimeException ("Dette er kun en test!"); logger.info ("Dette er en simpel besked på INFO-niveau." + "Den bliver skjult."); logger.error ("Dette er en simpel besked på FEJL-niveau." + "Dette er det mindst synlige niveau.", e); } 

4. ConsoleAppender Med Mønsterlayout

Lad os definere en ny konsolappender med et tilpasset farvemønster i en separat XML-fil og inkludere det i vores hovedkonfiguration:

Denne fil bruger nogle mønstervariabler, der bliver erstattet af Log4J 2 ved kørselstid:

  • % style {…} {colorname}: Dette udskriver teksten i det første parentespar () i en given farve (colorname).
  • % højdepunkt {…} {FATAL = kolornamn,…}: Dette svarer til 'stil' variablen. Men der kan gives en anden farve for hvert logniveau.
  • %datoformat}: Dette erstattes af den aktuelle dato i det angivne format. Her bruger vi 'DEFAULT' DateTime-format, åååå-MM-dd HH: mm: ss, SSS '.
  • % -5niveau: Udskriver niveauet for logmeddelelsen på en højrejusteret måde.
  • %besked: Repræsenterer den rå logmeddelelse

Men der findes mange flere variabler og formatering i Mønsterlayout. Du kan henvise dem til den officielle dokumentation for Log4J 2.

Nu inkluderer vi den definerede konsolappender i vores hovedkonfiguration:

Enhedstesten:

@Test offentlig ugyldighed givenLoggerWithConsoleConfig_whenLogToConsoleInColors_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger ("CONSOLE_PATTERN_APPENDER_MARKER"); logger.trace ("Dette er en farvet besked på TRACE-niveau."); ...} 

5. Async File Appender With JSON Layout og BurstFilter

Nogle gange er det nyttigt at skrive logbeskeder på en asynkron måde. For eksempel, hvis applikationsydelse har prioritet over tilgængeligheden af ​​logfiler.

I sådanne brugstilfælde kan vi bruge en AsyncAppender.

For vores eksempel konfigurerer vi en asynkron JSON logfil. Desuden inkluderer vi et burst-filter, der begrænser logoutputtet med en specificeret hastighed:

   ...          ...        

Læg mærke til det:

  • Det JSON Layout er konfigureret på en måde, der skriver en loghændelse pr. række
  • Det BurstFilter vil slippe hver begivenhed med 'INFO' niveau og derover, hvis der er mere end to af dem, men højst 10 afgivne begivenheder
  • Det AsyncAppender er indstillet til en buffer på 80 logbeskeder; derefter skylles bufferen til logfilen

Lad os se på den tilsvarende enhedstest. Vi udfylder den tilføjede buffer i en løkke, lad den skrive til disken og inspicere linjetællingen for logfilen:

@Test offentlig ugyldighed givenLoggerWithAsyncConfig_whenLogToJsonFile_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger ("ASYNC_JSON_FILE_APPENDER"); endelig intantal = 88; for (int i = 0; i 0 && logEventsCount <= count); }

6. RollingFile Appender og XMLLayout

Derefter opretter vi en rullende logfil. Efter en konfigureret filstørrelse komprimeres og roteres logfilen.

Denne gang bruger vi en XML layout:

Læg mærke til det:

  • Det RollingFile appender har en 'filePattern' attribut, som bruges til at navngive roterede logfiler og kan konfigureres med pladsholdervariabler. I vores eksempel skal den indeholde en dato og en tæller, før filens suffiks.
  • Standardkonfigurationen af XMLLayout vil skrive enkeltloghændelsesobjekter uden rodelementet.
  • Vi bruger en størrelsesbaseret politik til at rotere vores logfiler.

Vores enhedstestklasse vil se ud som den fra det foregående afsnit:

@Test offentlig ugyldighed givenLoggerWithRollingFileConfig_whenLogToXMLFile_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger ("XML_ROLLING_FILE_APPENDER"); endelig intantal = 88; for (int i = 0; i <count; i ++) {logger.info ("Dette er rullende fil XML-besked # {} på INFO-niveau.", i); }}

7. Syslog Appender

Lad os sige, at vi skal sende loggede begivenheder til en ekstern maskine via netværket. Den enkleste måde at gøre det på ved hjælp af Log4J2 ville være at bruge det Syslog Appender:

   ...     ...        

Attributterne i Syslog tag:

  • navn: definerer navnet på appenderen og skal være unik. Da vi kan have flere Syslog-appenders til den samme applikation og konfiguration
  • format: den kan enten indstilles til BSD eller RFC5424, og Syslog-poster vil blive formateret i overensstemmelse hermed
  • vært & port: værtsnavnet og porten på den eksterne Syslog-servermaskine
  • protokol: om du vil bruge TCP eller UPD
  • facilitet: til hvilket Syslog-anlæg begivenheden vil blive skrevet
  • connectTimeoutMillis: tidsperiode for at vente på en etableret forbindelse, er som standard nul
  • reconnectionDelayMillis: tid til at vente, før du forsøger at oprette forbindelse igen

8. FailoverAppender

Nu kan der være tilfælde, hvor en appender ikke behandler loghændelserne, og vi ikke ønsker at miste dataene. I sådanne tilfælde er FailoverAppender kommer praktisk.

For eksempel, hvis Syslog appender undlader at sende begivenheder til den eksterne maskine i stedet for at miste de data, vi måske falder tilbage til FileAppender midlertidigt.

Det FailoverAppender tager en primær appender og antallet af sekundære appenders. Hvis det primære mislykkes, forsøger det at behandle loghændelsen med sekundære i rækkefølge, indtil en lykkes, eller der ikke er nogen sekundærer at prøve:

Lad os teste det:

@Test offentlig ugyldighed givenLoggerWithFailoverConfig_whenLog_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger ("FAIL_OVER_SYSLOG_APPENDER"); Undtagelse e = ny RuntimeException ("Dette er kun en test!"); logger.trace ("Dette er en syslog-meddelelse på TRACE-niveau."); logger.debug ("Dette er en syslog-besked på DEBUG-niveau."); logger.info ("Dette er en syslog-besked på INFO-niveau. Dette er det mindst synlige niveau."); logger.warn ("Dette er en syslog-besked på WARN-niveau."); logger.error ("Dette er en syslog-meddelelse på FEJL-niveau.", e); logger.fatal ("Dette er en syslog-besked på FATAL-niveau."); }

9. JDBC Appender

JDBC-appenderen sender loghændelser til en RDBMS ved hjælp af standard JDBC. Forbindelsen kan opnås enten ved hjælp af en hvilken som helst JNDI-datakilde eller en hvilken som helst forbindelsesfabrik.

Grundkonfigurationen består af en Datakilde eller ConnectionFactory, ColumnConfigs og tabelnavn:

Lad os nu prøve:

@Test offentlig ugyldighed givenLoggerWithJdbcConfig_whenLogToDataSource_thanOK () kaster undtagelse {Logger logger = LogManager.getLogger ("JDBC_APPENDER"); endelig intantal = 88; for (int i = 0; i <count; i ++) {logger.info ("Dette er JDBC-besked # {} på INFO-niveau.", count); } Forbindelsesforbindelse = ConnectionFactory.getConnection (); ResultSet resultSet = connection.createStatement () .executeQuery ("SELECT COUNT (*) AS ROW_COUNT FROM logs"); int logCount = 0; hvis (resultSet.next ()) {logCount = resultSet.getInt ("ROW_COUNT"); } assertTrue (logCount == count); }

10. Konklusion

Denne artikel viser meget enkle eksempler på, hvordan du kan bruge forskellige logningsappendere, filtrere og layout med Log4J2 og måder at konfigurere dem på.

Eksemplerne, der ledsager artiklen, er tilgængelige på GitHub.