Articles

Sådan fungerer Log4J2: 10 måder at få mest muligt ud af det

Log4j2 er den opdaterede version af det populære og indflydelsesrige log4j-bibliotek, der bruges i vid udstrækning i hele Java-økosystemet i så mange år. Version 2.h holder alle logningsfunktionerne fra sin forgænger og bygger på dette fundament med nogle betydelige forbedringer, især inden for ydeevne.

og selvfølgelig, i betragtning af hvor instrumentel logning er til enhver applikation, både til revisions-og fejlfindingsformål, er det en ganske vigtig beslutning at vælge et solidt logbogsbibliotek.

i de følgende afsnit skal vi se på, hvorfor log4j2-biblioteket er et godt valg til den beslutning, og hvordan vi kan bruge det i en applikation.

grundlæggende Log4j2-konfiguration

for at begynde at bruge log4j2 i dit projekt skal du blot tilføje Log4J-core-afhængigheden. Hvis du bruger Maven, kan du tilføje følgende afhængighed til din pom.fil:

og hvis du arbejder med Gradle, skal du tilføje afhængigheden til build.gradle file:

dependencies { compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.8.2'}

ud af boksen giver log4j2 automatisk en simpel konfiguration, hvis du ikke eksplicit definerer en selv. Standardkonfigurationen logger på konsollen på et niveau af fejlniveau eller derover.

for at begynde at logge meddelelser ved hjælp af denne grundlæggende konfiguration er alt, hvad du skal gøre, at få en Loggerinstans ved hjælp af LogManager-klassen:

private static Logger logger = LogManager.getLogger(MyService.class);

derefter kan du bruge loggerobjektet med metoder svarende til det ønskede logniveau:

logger.error("This is an error message");

tilpasning af Log4j2-konfigurationen

en brugerdefineret log4j2-konfiguration kan oprettes enten programmatisk eller gennem en konfigurationsfil.

biblioteket understøtter konfigurationsfiler skrevet i HML, JSON, YAML, samt .egenskaber format. Her vil vi først og fremmest diskutere alle eksempler.

for det første kan du tilsidesætte standardkonfigurationen ved blot at oprette en log4j2.fil på classpath:

lad os se nærmere på de tags, der bruges i denne enkle konfiguration:

  • konfiguration: rodelementet i en log4j2-konfigurationsfil; statusattributten repræsenterer det niveau, hvor interne log4j-begivenheder skal logges
  • tilføjere: dette element indeholder en liste over tilføjere; i vores eksempel er en appender svarende til systemkonsollen defineret
  • loggere: dette element indeholder en liste over Loggerforekomster. Rodelementet er en standard logger, der udsender alle meddelelser

det er vigtigt at forstå, at Rodloggeren er obligatorisk i enhver konfiguration. Som diskuteret, hvis du ikke leverer en, konfigureres den automatisk som standard med en Konsolappender og FEJLLOGNIVEAUET.

konfiguration af tilføjere

i log4j2-arkitekturen er en appender grundlæggende ansvarlig for at sende logmeddelelser til en bestemt outputdestination.

Her er nogle af de mest nyttige typer af tilføjere, som biblioteket giver:

  • ConsoleAppender – logger meddelelser til systemkonsollen
  • FileAppender – skriver logbeskeder til en fil
  • RollingFileAppender – skriver meddelelserne til en rullende logfil
  • JDBCAppender – bruger en relationsdatabase til logfiler
  • Asyncappender – indeholder en liste over andre tilføjere og bestemmer logfilerne for disse, der skal skrives i en separat tråd

for bedre at forstå, hvordan tilføjere fungerer, lad os se på nogle konfigurationseksempler.

RollingFileAppender

logning af alt i en enkelt fil er selvfølgelig ikke ideel. Det er normalt meget bedre at rulle over den aktive logfil regelmæssigt-hvilket er præcis, hvad RollingFileAppender gør.

Du kan også gå ud over det grundlæggende med denne type appender og konfigurere både en brugerdefineret udløsningspolitik såvel som rollover-strategi.

den udløsende politik bestemmer, hvornår logfilen rulles, hvilket betyder, at der oprettes en ny fil, mens rollover-strategien bestemmer, hvordan filen rulles.

som et hurtigt eksempel, lad os konfigurere en appender, der opretter en ny logfil baseret på 3 politikker:

  • OnStartupTriggeringPolicy – en ny logfil oprettes hver gang JVM starter
  • TimeBasedTriggeringPolicy – logfilen rulles baseret på et dato/klokkeslæt mønster
  • Størrelsebasedtriggeringpolicy – filen rulles, når den når en bestemt størrelse

konfigurationen vil bruge defaultrolloverstrategy:

Du kan se, hvor fleksibel denne konfigurationsstil er, og hvordan du kan indstille den nøjagtige semantik i din logningsstrategi – ned til mindste detalje.

JDBCAppender

som navnet antyder, bruger denne appender JDBC til at skrive logfiler til en relationsdatabase.

for denne konfiguration skal du definere en ConnectionSource, som enten kan være en JNDI-datakilde eller en brugerdefineret ConnectionFactory. Loggeren bruger ConnectionSource til at få JDBC-forbindelser, hvorfor det er vigtigt at bruge en forbindelsespulje for bedre ydelse.som du kan se, er JNDI-datakilden simpelthen angivet ved hjælp af attributten jndiname of DataSource tag. Sammen med ConnectionSource kan du definere tabellen og de kolonner, der skal bruges til lagring af logdata.

FailoverAppender

lad os endelig se på FailoverAppender; dette definerer en primær appender og en liste over sikkerhedskopier, der vil træde ind for at håndtere logningen, hvis den primære fejler.

Du kan f.eks. konfigurere en primær JDBCAppender med en sekundær RollingFile-og Konsoltilføjere, hvis en databaseforbindelse ikke kan oprettes:

i et produktionsmiljø er det altid en god ide at have en failover-strategi for din logningsmekanisme.

konfiguration af layout

mens tilføjere er ansvarlige for at sende logmeddelelser til en destination, bruges layouterne af tilføjere til at definere, hvordan en logmeddelelse skal formateres.

Her er en kort beskrivelse af nogle af de mere almindeligt anvendte layouts, som log4j2 tilbyder:

  • PatternLayout – konfigurerer meddelelser i henhold til et Strengmønster
  • JsonLayout – definerer et JSON – format til logmeddelelser
  • CsvLayout-kan bruges til at oprette meddelelser i et CSV-format

PatternLayout

den første type layout, vi skal se på, er PatternLayout. Dette er en ganske fleksibel løsning, der giver dig en masse kontrol over den endelige output af logmeddelelsen.

mekanismen er primært drevet af et konverteringsmønster, der indeholder konverteringsspecifikatorer. Hver specifikator begynder med % – tegnet efterfulgt af modifikatorer, der styrer ting som meddelelsens bredde og farve og et konverteringstegn, der repræsenterer indholdet, f.eks.

lad os se på et eksempel på Konfiguration af et Mønsterlayout, der konfigurerer loglinjer til at vise dato, tråd, logniveau og logmeddelelse med forskellige farver til forskellige logniveauer:

disse specifikationer er værd at forstå i detaljer, så lad os se nærmere på:

  • %d{HH:mm:ss.SSS} – udsender datoen for loghændelsen i det angivne format
  • %t – udsender trådnavnet
  • %niveau – viser logniveauet for meddelelsen
  • %højdepunkt{%niveau} – bruges til at definere farverne for mønsteret mellem krøllede parenteser
  • %msg%n – udsender logmeddelelsen

udgangen viser logniveauerne med forskellige farver:

Du kan læse mere om den fulde sæt med muligheder for at definere mønstre i log4j2-dokumentationen på patternlayout.

Jsonlayout

logning af data ved hjælp af JSON-formatet har nogle væsentlige fordele, såsom at gøre logfilerne lettere at analysere og behandle ved at logge værktøjer ned ad linjen.

for at konfigurere JSONLayout i log4j2 kan du blot definere det tilsvarende tag:

<JSONLayout complete="true" compact="false"/>

indstilling komplet=true vil producere et velformet JSON-dokument:

for at kunne producere JSON skal du også tilføje jackson-databind-biblioteket til classpath:

konfiguration af filtre

filtre i log4j2 bruges til at bestemme, om en logmeddelelse skal behandles eller springes over.

et filter kan konfigureres for hele konfigurationen eller på logger eller appender niveau.

biblioteket indeholder flere typer filtre, der kan bruges:

  • BurstFilter – styrer antallet af tilladte loghændelser
  • DynamicThresholdFilter – filtrerer loglinjer baseret på bestemte attributter
  • Regeksfilter – filtrerer meddelelser baseret på, om de matcher et regulært udtryk

Du kan for eksempel kontrollere den hastighed, hvormed applikationen får lov til at logge data.

for at gøre det kan du oprette et BurstFilter og anvende det på INFOBESKEDER:

<Filters> <BurstFilter level="INFO" rate="10" maxBurst="100"/></Filters>

dette vil selektivt ignorere kontrol trafikken af info niveau meddelelser og nedenfor samtidig sikre, at du ikke mister nogen af de mere vigtige meddelelser ovenfor INFO.

i dette tilfælde definerer rate de gennemsnitlige logmeddelelser, der skal behandles pr.sekund, og maksburst styrer den samlede størrelse af trafikudbruddet, før filteret begynder at fjerne logposter.

på samme måde kan vi kun konfigurere appenderen til at acceptere logmeddelelser, der matcher et specifikt regulært udtryk:

<Appenders> <JDBC name="JDBCAppender"> <RegexFilter regex="*jdbc*" onMatch="ACCEPT" onMismatch="DENY"/> </JDBC></Appenders>

samlet set kan denne filtreringsmekanisme bruges med stor præcision for at sikre, at hver appender i din samlede logningskonfiguration sporer de rigtige oplysninger. Evnen til kun at logge meget specifik og relevant information fører generelt til meget hurtig grundårsanalyse, især i komplekse systemer – især når det kombineres med et kraftfuldt logvisningsværktøj.

konfiguration af loggere

udover Rodloggeren kan vi også definere yderligere Loggerelementer med forskellige logniveauer, tilføjere eller filtre. Hver Logger kræver et navn, der kan bruges senere til at henvise til det:

<Loggers> <Logger name="RollingFileLogger"> <AppenderRef ref="RollingFileAppender" /> </Logger></Loggers>

for at skrive logmeddelelser ved hjælp af denne særlige Logger kan du få en henvisning til den ved hjælp af LogManager-klassen:

Logger rfLogger = LogManager.getLogger("RollingFileLogger");rfLogger.info("User info updated");

en anden meget almindelig måde at strukturere hierarkiet for disse loggere er baseret på Java-klassen:

Logger logger = LogManager.getLogger(MyServiceTest.class);

brug af opslag

opslag repræsenterer en måde at indsætte eksterne værdier i log4j2-konfigurationen. Vi har allerede set et eksempel på datoopslaget i RollingFileAppender-konfigurationen:

<RollingFile name="RollingFileAppender" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">

${date:yyy-MM} opslag indsætter den aktuelle dato i filnavnet, mens det foregående $ er et escape-tegn, for at indsætte opslagsudtrykket i attributten filePattern.

Du kan også indsætte værdier for Systemegenskaber i log4j2-konfiguration ved hjælp af formatet ${sys:property_name}:

<File name="ApplicationLog" fileName="${sys:path}/app.log"/>

en anden type information, du kan slå op og indsætte, er Java-miljøoplysninger:

<PatternLayout header="${java:version} - ${java:os}"> <Pattern>%d %m%n</Pattern></PatternLayout>

Du kan finde flere detaljer om den type data, du kan indsætte gennem opslag i log4j2 dokumentation.

programmatisk konfiguration

udover konfigurationsfiler kan log4j2 også konfigureres programmatisk. Der er et par forskellige måder at gøre det på:

  • Opret en brugerdefineret Konfigurationfactory
  • brug Konfiguratorklassen
  • Rediger konfigurationen efter initialisering
  • kombiner egenskabsfiler og programmatisk konfiguration

lad os se på, hvordan du konfigurerer et layout og appender programmatisk:

dernæst kan du definere en logger ved hjælp af LoggerConfig-klassen, knytte appenderen til den, og Opdater konfigurationen:

derefter kan du begynde at bruge loggeren som sædvanligt:

Logger pLogger = LogManager.getLogger("programmaticLogger");pLogger.info("Programmatic Logger Message");

denne stil med flydende API kan føre til en hurtigere udvikling og iteration på mere komplekse logningskonfigurationer, fordi du nu drager fordel af fordelene ved at arbejde direkte med Java-kode.

men i betragtning af at kml stadig kan være mere læsbar og kompakt, kan du ofte udvikle konfigurationen programmatisk og derefter konvertere den til KML, når alt er gjort.

brugerdefinerede Logniveauer

de indbyggede logniveauer for log4j2 er:

  • OFF
  • FATAL
  • fejl
  • advar
  • INFO
  • DEBUG
  • TRACE
  • alle

ud over disse kan du også definere et brugerdefineret logniveau i henhold til dine applikationsbehov.

for eksempel for at definere dette nye logniveau kan du gøre brug af niveauet.forName () API-angivelse af det nye niveaunavn og et heltal, der repræsenterer stedet for niveauet i logniveauhierarkiet:

Level myLevel = Level.forName("NEW_LEVEL", 350);

for at bestemme, hvilken heltalsværdi der skal bruges, kan du se på de værdier, der er defineret for de andre logniveauer i log4j2-dokumentationen:

350-værdien sætter niveauet mellem advarsel og INFO, hvilket betyder, at meddelelserne vises, når niveauet er indstillet til INFO eller derover.

for at logge en besked på det brugerdefinerede niveau skal du bruge log () – metoden:

logger.log(myLevel, "Custom Level Message");

den tilsvarende konfiguration kan være:

<CustomLevels> <CustomLevel name="NEW_XML_LEVEL" intLevel="350" /></CustomLevels>

så kan den bruges via standard log API:

logger.log(Level.getLevel("NEW_XML_LEVEL"),"Custom XML Level Message");

de nye brugerdefinerede niveauer vises på samme måde som standardniveauerne:

11:28:23.558 NEW_LEVEL - Custom Level Message11:28:23.559 NEW_XML_LEVEL - Custom XML Level Message

migrering fra Log4j 1.

Hvis du migrerer et program ved hjælp af 1.version af biblioteket til den aktuelle 2.der er et par ruter, du kan følge:

  • brug log4j 1.manuelt opdatere API og konfigurationen

Ved hjælp af broen er trivielt. Du behøver kun at erstatte Log4J afhængighed med log4j-1.2-api bibliotek:

selvom dette er den hurtigere metode, har den ulempen ved at være begrænset i den type konfiguration, der kan konverteres.

den manuelle metode er naturligvis mere arbejde, men vil i sidste ende føre til en mere fleksibel og kraftfuld logning løsning.

Her er nogle af de mest almindelige typer ændringer, du skal gøre:

konklusion

logfiler er kritiske i ethvert produktionsmiljø, og at vælge en god logningsløsning kan være forskellen mellem at bruge 5 minutter og bruge en hel dag til at forstå et problem i produktionen.

Log4j2 er en kraftfuld og robust logning løsning til moderne Java-applikationer, med en bred vifte af konfigurationsmuligheder.det giver mulighed for nem konfiguration af avancerede logning bedste praksis såsom rullende filer, forskellige typer af logning output destinationer, støtte til strukturerede logning formater som f.eks.

endelig, når du skal gå ud over manuelt at analysere logdata, skal du helt sikkert tjekke logningsfunktionerne inkluderet i Retrace APM.