Articles

cum funcționează Log4J2: 10 moduri de a obține cele mai multe din ea

Log4j2 este versiunea actualizată a Bibliotecii populare și influente log4j, utilizate pe scară largă în ecosistemul Java pentru atât de mulți ani. Versiunea 2.x păstrează toate caracteristicile de logare ale predecesorului său și se bazează pe acea fundație cu unele îmbunătățiri semnificative, în special în domeniul performanței.

și, desigur, având în vedere modul în care logarea instrumentală este pentru orice aplicație, atât în scopuri de audit, cât și în scopuri de depanare, alegerea unei biblioteci solide de logare este o decizie destul de importantă.

în secțiunile următoare, vom arunca o privire de ce biblioteca log4j2 este o alegere excelentă pentru această decizie și cum o putem folosi într-o aplicație.

configurare Log4j2 de bază

pentru a începe să utilizați log4j2 în proiectul dvs., trebuie doar să adăugați dependența log4j-core. Dacă utilizați Maven, puteți adăuga următoarea dependență la pom.fișier xml:

și dacă lucrați cu Gradle, trebuie să adăugați dependența la compilare.fișier gradle:

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

din cutie, log4j2 va oferi automat o configurație simplă, dacă nu definiți în mod explicit unul singur. Configurația implicită se conectează la consolă la un nivel de nivel de eroare sau mai mare.

pentru a începe logarea mesajelor folosind această configurație de bază, tot ce trebuie să faceți este să obțineți o instanță Logger folosind clasa LogManager:

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

apoi puteți utiliza obiectul logger cu metode corespunzătoare nivelului de jurnal dorit:

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

personalizarea configurației Log4j2

o configurație log4j2 personalizată poate fi creată fie programatic, fie printr-un fișier de configurare.

biblioteca acceptă fișiere de configurare scrise în XML, JSON, YAML, precum și .format proprietăți. Aici, vom folosi XML pentru a discuta în primul rând toate exemplele.

În primul rând, puteți suprascrie configurația implicită prin simpla creare a unui log4j2.fișier xml pe classpath:

să aruncăm o privire mai atentă la etichetele utilizate în această configurație simplă:

  • configurare: elementul rădăcină al unui fișier de configurare log4j2; atributul de stare reprezintă nivelul la care ar trebui înregistrate evenimentele log4j interne
  • Appenders: acest element conține o listă de appenders; în exemplul nostru, este definit un appender corespunzător consolei de sistem
  • Loggers: acest element conține o listă de instanțe Logger. Elementul rădăcină este un logger standard care emite toate mesajele

este important să înțelegem că loggerul rădăcină este obligatoriu în fiecare configurație. După cum sa discutat, dacă nu furnizați unul, acesta va fi configurat automat în mod implicit cu un appender de consolă și nivelul jurnalului de erori.

Configurarea Appenders

în arhitectura log4j2, un appender este practic responsabil pentru trimiterea mesajelor jurnal la o anumită destinație de ieșire.

iată câteva dintre cele mai utile tipuri de aplicații pe care le oferă biblioteca:

  • ConsoleAppender – înregistrează mesaje către consola de sistem
  • FileAppender – scrie mesaje jurnal într – un fișier
  • RollingFileAppender – scrie mesajele într – un fișier jurnal de rulare
  • JDBCAppender-utilizează o bază de date relațională pentru jurnalele
  • AsyncAppender-conține o listă de alte anexe și determină jurnalele pentru acestea să fie scrise într-un fir separat

pentru a înțelege mai bine cum funcționează appenders, să ne uităm la câteva exemple de configurare.

RollingFileAppender

logare totul într-un singur fișier este, desigur, nu este ideal. Este, de obicei, mult mai bine să se rostogolească peste fișierul jurnal activ în mod regulat – care este exact ceea ce face RollingFileAppender.

veți putea, de asemenea, să depășiți elementele de bază cu acest tip de appender și să configurați atât o politică de declanșare personalizată, cât și o strategie de rollover.

Politica de declanșare determină când fișierul jurnal este rulat, ceea ce înseamnă că este creat un fișier nou, în timp ce strategia de rollover determină modul în care fișierul este rulat.

ca un exemplu rapid, să configurați un appender care creează un nou fișier jurnal bazat pe 3 politici:

  • OnStartupTriggeringPolicy – un nou fișier jurnal este creat de fiecare dată când începe JVM
  • TimeBasedTriggeringPolicy – fișierul jurnal este rulat pe baza unui model dată/oră
  • SizeBasedTriggeringPolicy – fișierul este rulat atunci când ajunge la o anumită dimensiune

configurația va utiliza defaultrolloverstrategy:

puteți vedea cât de flexibil este acest stil de configurare și cum puteți regla semantica exactă a strategiei dvs. de logare – până la ultimul detaliu.

JDBCAppender

după cum sugerează și numele, acest appender folosește JDBC pentru a scrie jurnale într-o bază de date relațională.

pentru această configurație, trebuie să definiți o sursă de conexiune, care poate fi fie o sursă de date JNDI, fie o conexiune personalizată. Logger utilizează ConnectionSource pentru a obține conexiuni JDBC, motiv pentru care este important să se utilizeze un bazin de conexiune pentru o performanță mai bună.

pentru a configura aplicația în fișierul de configurare XML, puteți utiliza eticheta JDBC:

după cum puteți vedea, sursa de date JNDI este pur și simplu specificată folosind atributul jndiName al etichetei sursă de date. Împreună cu ConnectionSource, puteți defini tabelul și coloanele care vor fi utilizate pentru stocarea datelor de jurnal.

FailoverAppender

în cele din urmă, să aruncăm o privire la FailoverAppender; aceasta definește un appender principal și o listă de copii de rezervă care vor interveni pentru a gestiona înregistrarea în cazul în care cea primară eșuează.

de exemplu, puteți configura un JDBCAppender primar, cu un secundar rollingfile și consola appenders în cazul în care o conexiune de bază de date nu poate fi stabilită:

într-un mediu de producție, având o strategie failover pentru mecanismul de logare este întotdeauna o idee bună.

Configurarea Layouts

în timp ce appenders sunt responsabile pentru trimiterea mesajelor jurnal la o destinație, aspectele sunt utilizate de appenders pentru a defini modul în care un mesaj jurnal va fi formatat.

Iată o scurtă descriere a unora dintre cele mai frecvent utilizate machete care oferă log4j2:

  • PatternLayout – configurează mesajele conform unui model șir
  • JsonLayout – definește un format JSON pentru mesajele jurnal
  • CsvLayout – poate fi folosit pentru a crea mesaje într-un format CSV

PatternLayout

primul tip de aspect vom uita la este PatternLayout. Aceasta este o soluție destul de flexibilă, care vă oferă mult control asupra ieșirii finale a mesajului jurnal.

mecanismul este condus în principal de un model de conversie care conține specificatori de conversie. Fiecare specificator începe cu semnul%, urmat de modificatori care controlează lucruri precum lățimea și culoarea mesajului și un caracter de conversie care reprezintă conținutul, cum ar fi data sau numele firului.

să ne uităm la un exemplu de configurare a unui model care configurează liniile de jurnal pentru a afișa data, firul, nivelul jurnalului și mesajul de jurnal cu culori diferite pentru diferite niveluri de jurnal:

acești specificatori merită să fie înțeleși în detaliu, deci să aruncăm o privire mai atentă:

  • %d{HH:mm:ss.SSS} – afișează data evenimentului Jurnal în formatul specificat
  • %t – afișează numele firului
  • %level – afișează nivelul jurnal al mesajului
  • %highlight{%level} – este utilizat pentru a defini culorile pentru modelul dintre paranteze buclate
  • %msg%n – afișează mesajul jurnal

ieșirea va afișa nivelurile jurnal cu diferite culori:

puteți citi mai multe despre setul complet de opțiuni pentru definirea modelelor în documentația log4j2 pe patternlayout.

Jsonlayout

datele de logare folosind formatul JSON au unele avantaje semnificative, cum ar fi facilitarea analizării și procesării jurnalelor prin instrumente de logare pe linie.

pentru a configura JSONLayout în log4j2, puteți defini pur și simplu tag-ul corespunzător:

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

setarea complete = true va produce un document JSON bine format:

pentru a putea produce JSON, de asemenea, trebuie să adăugați biblioteca jackson-databind la classpath:

configurarea filtrelor

filtrele din log4j2 sunt utilizate pentru a determina dacă un mesaj de jurnal trebuie procesat sau omis.

un filtru poate fi configurat pentru întreaga configurație sau la nivel de logger sau appender.

Biblioteca oferă mai multe tipuri de filtre care pot fi utilizate:

  • BurstFilter – controlează numărul de evenimente jurnal permis
  • DynamicThresholdFilter – filtre log linii bazate pe anumite atribute
  • RegexFilter – filtre mesaje bazate pe dacă se potrivesc cu o expresie regulată

puteți, de exemplu, controla rata cu care cererea este permis să vă conectați date.

în scopul de a face, puteți configura un BurstFilter și se aplică că la mesaje INFO:

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

Acest lucru va ignora selectiv controlul traficului mesajelor la nivel de informații și de mai jos, asigurându-vă că nu pierdeți niciunul dintre mesajele mai importante de mai sus.

în acest caz, rate definește mesajele medii de jurnale care ar trebui procesate pe secundă, iar maxBurst controlează dimensiunea totală a exploziei de trafic înainte ca filtrul să înceapă să elimine intrările de jurnal.

în mod similar, putem configura appender doar pentru a accepta mesaje de jurnal care se potrivesc cu o expresie regulată specifică:

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

În general, acest mecanism de filtrare poate fi utilizat cu mare precizie pentru a vă asigura că fiecare aplicație din configurația dvs. generală de înregistrare urmărește informațiile corecte. Abilitatea de a înregistra doar informații foarte specifice și relevante duce, în general, la o analiză foarte rapidă a cauzelor rădăcină, în special în sistemele complexe – mai ales atunci când este cuplată cu un instrument puternic de vizualizare a jurnalelor.

Configurarea loggerilor

pe lângă loggerul rădăcină, putem defini și elemente suplimentare de Logger cu diferite niveluri de jurnal, anexe sau filtre. Fiecare Logger necesită un nume care poate fi folosit mai târziu pentru a-l referi:

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

pentru a scrie mesaje de jurnal folosind acest Logger special, puteți obține o referință la acesta folosind clasa LogManager:

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

Un alt mod foarte comun de a structura ierarhia acestor loggeri se bazează pe clasa Java:

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

utilizarea căutărilor

căutările reprezintă o modalitate de a insera valori externe în configurația log4j2. Am văzut deja un exemplu de căutare dată în configurația RollingFileAppender:

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

căutarea ${date:AAAA-MM} va insera data curentă în numele fișierului, în timp ce $ – ul precedent este un caracter escape, pentru a insera expresia lookup în atributul filePattern.

de asemenea, puteți insera valorile proprietăților sistemului în configurația log4j2 folosind formatul ${SYS:property_name}:

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

Un alt tip de informații pe care le puteți căuta și insera sunt informațiile despre mediul Java:

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

puteți găsi mai multe detalii despre tipul de date pe care log4j2 documentație.

configurare programatică

pe lângă fișierele de configurare, log4j2 poate fi configurat și programatic. Există câteva moduri diferite de a face acest lucru:

  • creați un ConfigurationFactory personalizat
  • utilizați clasa Configurator
  • modificați configurația după inițializare
  • combinați fișierele de proprietăți și configurația programatică

Să aruncăm o privire la modul de configurare a unui aspect și a unui appender programatic:

apoi, puteți defini un logger folosind clasa LoggerConfig, asociați appenderul la acesta și actualizați configurația:

apoi, puteți începe să utilizați logger ca de obicei:

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

Acest stil de API fluent poate duce la o dezvoltare mai rapidă și iterație pe configurații de logare mai complexe, deoarece acum beneficiați de avantajele de a lucra direct cu codul Java.

cu toate acestea, având în vedere că XML poate fi încă mai ușor de citit și compact, puteți dezvolta de multe ori configurația programatic și apoi converti în XML atunci când totul este făcut.

niveluri jurnal personalizate

nivelurile jurnal încorporate pentru log4j2 sunt:

  • OFF
  • FATAL
  • eroare
  • WARN
  • INFO
  • depanare
  • TRACE
  • toate

În plus față de acestea, puteți defini, de asemenea, un nivel jurnal personalizat în funcție de nevoile dvs. de aplicare.

de exemplu, pentru a defini acest nou nivel de jurnal, puteți utiliza nivelul.forName () API-specificarea noului nume de nivel și a unui număr întreg care reprezintă locul nivelului în ierarhia nivelurilor de jurnal:

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

pentru a determina ce valoare întreagă să utilizați, puteți arunca o privire la valorile definite pentru celelalte niveluri de jurnal din documentația log4j2:

valoarea 350 plasează nivelul între WARN și INFO, ceea ce înseamnă că mesajele vor fi afișate atunci când nivelul este setat la INFO sau mai sus.

pentru a înregistra un mesaj la nivel personalizat, trebuie să utilizați metoda log ():

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

configurația XML echivalentă ar putea fi:

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

apoi poate fi utilizată prin API-ul standard log:

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

noile niveluri personalizate vor fi afișate în același mod ca și cele standard:

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

migrând din Log4j 1.x

dacă migrați o aplicație utilizând 1.versiunea X a Bibliotecii la curent 2.versiunea x, există câteva rute pe care le puteți urma:

  • utilizați log4j 1.x bridge
  • actualizați manual API-ul și configurația

utilizarea podului este banală. Trebuie doar să înlocuiți dependența log4j cu Biblioteca log4j-1.2-api:

deși aceasta este metoda mai rapidă, are dezavantajul de a fi limitată în tipul de configurație care poate fi convertit.

metoda manuală este, desigur, mai multă muncă, dar va duce în cele din urmă la o soluție de logare mai flexibilă și mai puternică.

iată câteva dintre cele mai frecvente tipuri de modificări pe care trebuie să le faceți:

concluzie

fișierele jurnal sunt critice în orice mediu de producție, iar alegerea unei soluții bune de logare poate fi diferența dintre a petrece 5 minute și a petrece o zi întreagă pentru a înțelege o problemă în producție.

Log4j2 este o soluție puternică și robustă de logare pentru aplicații Java moderne, cu o gamă largă de opțiuni de configurare.

permite configurarea ușoară a celor mai bune practici avansate de logare, cum ar fi fișierele rulante, diferite tipuri de destinații de ieșire de logare, suport pentru formate de logare structurate, cum ar fi JSON sau XML, folosind mai multe jurnale și filtre și niveluri de jurnal personalizate.

în cele din urmă, atunci când aveți nevoie pentru a merge dincolo de analiza manuală a datelor de jurnal, cu siguranta a verifica afară capacitățile de logare incluse în Retrace APM.