Log4j Tutorial: Come configurare il Logger per un’efficiente registrazione delle applicazioni Java
Ottenere visibilità nell’applicazione è fondamentale quando si esegue il codice in produzione. Cosa intendiamo per visibilità? Principalmente cose come le prestazioni delle applicazioni tramite metriche, lo stato delle applicazioni e la disponibilità, i suoi log se è necessario risolverlo o le sue tracce se è necessario capire cosa lo rende lento e come renderlo più veloce.
Le metriche forniscono informazioni sulle prestazioni di ciascuno degli elementi dell’infrastruttura. Traces ti mostrerà una visione più ampia dell’esecuzione del codice e del flusso insieme alle metriche di esecuzione del codice. Infine, i registri ben realizzati forniranno una visione inestimabile dell’esecuzione della logica del codice e di ciò che stava accadendo nel tuo codice. Ciascuno dei pezzi menzionati è cruciale per la tua applicazione e in effetti l’osservabilità complessiva del sistema. Oggi, ci concentreremo solo su un singolo pezzo – i registri. Per essere più precisi – sui registri delle applicazioni Java. Se sei interessato alle metriche, consulta il nostro articolo sulle metriche JVM chiave che dovresti monitorare.
Tuttavia, prima di entrare in esso, affrontiamo un problema che ha avuto un impatto sulla comunità utilizzando questo framework. Il 9 dicembre 2021 è stata segnalata una vulnerabilità critica soprannominata Log4Shell. Identificato come CVE-2021-44228, consente a un utente malintenzionato di prendere il controllo completo di una macchina che esegue Apache Log4j 2 versione 2.14.1 o inferiore, consentendo loro di eseguire codice arbitrario sul server vulnerabile. Nel nostro recente post sul blog sulla vulnerabilità Log4jShell, abbiamo dettagliato come determinare se sei interessato, come risolvere il problema e cosa abbiamo fatto noi di Sematext per proteggere il nostro sistema e gli utenti.
Log4j 1.x Fine vita
Tenete a mente che il 5 agosto 2015 il Logging Services Project Management Committee ha annunciato che il Log4j 1.x aveva raggiunto la sua fine di vita. Tutti gli utenti sono invitati a migrare a Log4j 2.x. In questo post del blog, ti aiuteremo a capire la tua attuale configurazione di Log4j, in particolare log4j 2.versione x-e dopo, ti aiuterò a migrare alla versione più recente e più grande di Log4j.
” Sto usando Log4j 1.x, cosa devo fare?”. Niente panico, non c’è niente di sbagliato in questo. Fare un piano per la transizione a Log4j 2.x. Ti mostrerò come continuare a leggere:). La tua domanda ti ringrazierà per questo. Otterrai le correzioni di sicurezza, i miglioramenti delle prestazioni e molte più funzionalità dopo la migrazione.
” Sto iniziando un nuovo progetto, cosa devo fare?”. Basta usare il Log4j 2.x subito, non pensare nemmeno a Log4j 1.x. Se hai bisogno di aiuto, dai un’occhiata a questo tutorial di registrazione Java in cui spiego tutto ciò di cui hai bisogno.
Accesso a Java
Non c’è magia dietro l’accesso a Java. Tutto si riduce all’utilizzo di una classe Java appropriata e dei suoi metodi per generare eventi di log. Come abbiamo discusso nella guida alla registrazione Java ci sono diversi modi per iniziare
Naturalmente, il più ingenuo e non il percorso migliore da seguire è solo usando il sistema.fuori e sistema.classi err. Sì, puoi farlo e i tuoi messaggi andranno solo allo standard output e all’errore standard. Di solito, ciò significa che verrà stampato sulla console o scritto su un file di qualche tipo o addirittura inviato a /dev/null e per sempre dimenticato. Un esempio di tale codice potrebbe essere simile a questo:
public class SystemExample { public static void main(String args) { System.out.println("Starting my awesome application"); // some work to be done System.out.println( String.format("My application %s started successfully", SystemExample.class) ); }}
L’output dell’esecuzione del codice di cui sopra sarebbe il seguente:
Starting my awesome applicationMy application class com.sematext.logging.log4jsystem.SystemExample started successfully
Non e ‘ perfetto, vero? Non ho alcuna informazione su quale classe ha generato il messaggio e molte, molte altre cose “piccole” che sono cruciali e importanti durante il debug.
Mancano altre cose che non sono realmente connesse al debug. Pensa all’ambiente di esecuzione, a più applicazioni o microservizi e alla necessità di unificare la registrazione per semplificare la configurazione della pipeline di centralizzazione dei log. Utilizzando il sistema.fuori, o / e sistema.err nel nostro codice per scopi di registrazione ci costringerebbe a rifare tutti i luoghi in cui lo usiamo ogni volta che abbiamo bisogno di regolare il formato di registrazione. So che è estremo, ma credimi, abbiamo visto l’uso del sistema.out nel codice di produzione nei modelli di distribuzione delle applicazioni “tradizionali”! Naturalmente, la registrazione al sistema.out è una soluzione adeguata per le applicazioni containerizzate e si dovrebbe utilizzare l’output che si adatta al proprio ambiente. Ricordatelo!
A causa di tutti i motivi menzionati e molti altri a cui non pensiamo nemmeno, dovresti esaminare una delle possibili librerie di registrazione, come Log4 j, Log4j 2, Logback o anche java.util.registrazione che fa parte del kit di sviluppo Java. Per questo post del blog, useremo Log4j.
The Abstraction Layer – SLF4J
L’argomento della scelta della soluzione di registrazione giusta per la tua applicazione Java è qualcosa che abbiamo già discusso nel nostro tutorial sulla registrazione in Java. Consigliamo vivamente di leggere almeno la sezione menzionata.
Useremo SLF4J, un livello di astrazione tra il nostro codice Java e Log4j-la libreria di registrazione di nostra scelta. La facciata di registrazione semplice fornisce collegamenti per framework di registrazione comuni come Log4j, Logback e java.util.registrazione. Immagina il processo di scrittura di un messaggio di registro nel modo seguente e semplificato:
Potresti chiedere perché usare un livello di astrazione? Bene, la risposta è abbastanza semplice – alla fine, potresti voler cambiare il framework di registrazione, aggiornarlo, unificarlo con il resto del tuo stack tecnologico. Quando si utilizza un livello di astrazione, tale operazione è abbastanza semplice: basta scambiare le dipendenze del framework di registrazione e fornire un nuovo pacchetto. Se non dovessimo usare un livello di astrazione, dovremmo cambiare il codice, potenzialmente molto codice. Ogni classe che registra qualcosa. Non è una bella esperienza di sviluppo.
Il Logger
Il codice dell’applicazione Java interagirà con un set standard di elementi chiave che consentono la creazione e la manipolazione degli eventi di log. Abbiamo coperto quelli cruciali nel nostro tutorial di registrazione Java, ma lascia che ti ricordi di una delle classi che useremo costantemente: il Logger.
Il Logger è l’entità principale che un’applicazione utilizza per effettuare chiamate di registrazione – creare eventi di log. L’oggetto Logger viene solitamente utilizzato per una singola classe o un singolo componente per fornire un contesto associato a un caso d’uso specifico. Fornisce metodi per creare eventi di registro con un livello di registro appropriato e trasmetterlo per ulteriori elaborazioni. Di solito creerai un oggetto statico con cui interagirai, ad esempio in questo modo:
... Logger LOGGER = LoggerFactory.getLogger(MyAwesomeClass.class);
E questo è tutto. Ora che sappiamo cosa possiamo aspettarci, diamo un’occhiata alla libreria Log4j.
Log4j
Il modo più semplice per iniziare con Log4j è includere la libreria nel classpath dell’applicazione Java. Per fare ciò includiamo la più recente libreria log4j disponibile, che significa versione 1.2.17 nel nostro file di compilazione.
usiamo Gradle e nella nostra semplice applicazione e le dipendenze sezione per Gradle costruire il file si presenta come segue:
dependencies { implementation 'log4j:log4j:1.2.17'}
Siamo in grado di iniziare a sviluppare il codice e includere la registrazione utilizzando Log4j:
package com.sematext.blog;import org.apache.log4j.Logger;public class ExampleLog4j { private static final Logger LOGGER = Logger.getLogger(ExampleLog4j.class); public static void main(String args) { LOGGER.info("Initializing ExampleLog4j application"); }}
Come si può vedere nel codice di cui sopra abbiamo inizializzato l’oggetto Logger utilizzando la statica getLogger metodo e abbiamo fornito il nome della classe. Dopo averlo fatto possiamo facilmente accedere all’oggetto Logger statico e usarlo per produrre eventi di log. Possiamo farlo nel metodo principale.
Una nota a margine-il metodo getLogger può anche essere chiamato con una stringa come argomento, ad esempio:
private static final Logger LOGGER = Logger.getLogger("com.sematext.blog");
Significherebbe che vogliamo creare un logger e associare il nome di com.sematesto.blog con esso. Se useremo lo stesso nome in qualsiasi altro punto del codice, Log4j restituirà la stessa istanza del Logger. Ciò è utile se desideriamo combinare la registrazione da più classi diverse in un unico posto. Ad esempio, i registri relativi al pagamento in un singolo file di registro dedicato.
Log4j fornisce un elenco di metodi che consentono la creazione di nuovi eventi di log utilizzando un livello di log appropriato. Quelli sono:
- public void traccia(Oggetto messaggio)
- public void debug(Oggetto messaggio)
- public void info(Oggetto messaggio)
- public void warn(Oggetto messaggio)
- public void errore(Oggetto messaggio)
- public void fatale(Oggetto messaggio)
E un metodo generico:
- registro pubblico vuoto (Livello livello, messaggio oggetto)
Abbiamo parlato di livelli di registrazione Java nel nostro post sul blog tutorial di registrazione Java. Se non siete a conoscenza di loro, si prega di prendere qualche minuto per abituarsi a loro come i livelli di registro sono cruciali per la registrazione. Se hai appena iniziato con i livelli di registrazione, tuttavia, ti consigliamo di consultare anche la nostra guida ai livelli di registro. Spieghiamo tutto, da quello che sono a come scegliere quello giusto e come fare uso di loro per ottenere intuizioni significative.
Se dovessimo eseguire il codice sopra l’output che otterremmo sulla console standard sarebbe il seguente:
log4j:WARN No appenders could be found for logger (com.sematext.blog.ExampleLog4j).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Non abbiamo visto il messaggio di log che ci aspettavamo. Log4j ci ha informato che non è presente alcuna configurazione. Oooops, parliamo di come configurare Log4j
Configurazione Log4j
Ci sono diversi modi in cui possiamo configurare la nostra registrazione Log4j. Possiamo farlo a livello di codice, ad esempio includendo un blocco di inizializzazione statico:
static { BasicConfigurator.configure();}
Il codice precedente configura Log4j per inviare i log alla console nel formato predefinito. L’output dell’esecuzione della nostra applicazione di esempio sarebbe il seguente:
0 INFO com.sematext.blog.ExampleLog4jProgrammaticConfig - Initializing ExampleLog4j application
Tuttavia, l’impostazione di Log4j a livello di codice non è molto comune. Il modo più comune sarebbe quello di utilizzare un file di proprietà o un file XML. Possiamo cambiare il nostro codice e includere il file log4j. properties con il seguente contenuto:
log4j.rootLogger=DEBUG, MAINlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%r %-5p %c %x - %m%n
In questo modo abbiamo detto a Log4j che creiamo il root logger, che verrà utilizzato per impostazione predefinita. Il suo livello di registrazione predefinito è impostato su DEBUG, il che significa che verranno inclusi gli eventi di log con DEBUG di gravità o superiore. Quindi DEBUG, INFO, WARN, ERROR e FATAL. Abbiamo anche dato il nostro logger un nome-PRINCIPALE. Successivamente, configuriamo il logger, impostando il suo output su console e utilizzando il layout del modello. Ne parleremo più avanti nel post del blog. L’output di eseguire il codice sopra sarebbe il seguente:
0 INFO com.sematext.blog.ExampleLog4jProperties - Initializing ExampleLog4j application
Se lo desideriamo, possiamo anche cambiare il file log4j. properties e usarne uno chiamato log4j.xml. La stessa configurazione utilizzando il formato XML apparirebbe come segue:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration> <appender name="MAIN" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%r %-5p %c %x - %m%n" /> </layout> </appender> <root> <priority value ="debug"></priority> <appender-ref ref="MAIN" /> </root></log4j:configuration>
Se ora cambiassimo log4j. properties per log4j.xml uno e tenerlo nel classpath l’esecuzione della nostra applicazione di esempio sarebbe la seguente:
0 INFO com.sematext.blog.ExampleLog4jXML - Initializing ExampleLog4j application
Quindi, come fa Log4j a sapere quale file usare? Diamo un’occhiata a questo.
Processo di inizializzazione
È fondamentale sapere che Log4j non fa alcuna ipotesi riguardo all’ambiente in cui è in esecuzione. Log4j non assume alcun tipo di destinazioni di eventi di log predefinite. All’avvio, cerca la proprietà log4j. configuration e tenta di caricare il file specificato come configurazione. Se la posizione del file non può essere convertita in un URL o il file non è presente, tenta di caricare il file dal classpath.
Ciò significa che possiamo sovrascrivere la configurazione Log4j dal classpath fornendo-Dlog4j.configuration durante l’avvio e puntandolo nella posizione corretta. Ad esempio, se includiamo un file chiamato altro.xml con il seguente contenuto:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration> <appender name="MAIN" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%r %-5p %c %x - %m%n" /> </layout> </appender> <root> <priority value ="debug"></priority> <appender-ref ref="MAIN" /> </root></log4j:configuration>
E poi esaurire il codice con-Dlog4j. configuration= / opt / sematext / other.xml l’output dal nostro codice sarà il seguente:
0 INFO com.sematext.blog.ExampleLog4jXML - Initializing ExampleLog4j application
Log4j Appenders
Abbiamo già usato appenders nei nostri esempi well beh, in realtà solo uno-il ConsoleAppender. Il suo unico scopo è scrivere gli eventi di log nella console. Naturalmente, con un gran numero di eventi di log e sistemi in esecuzione in ambienti diversi, la scrittura di dati di testo puro sullo standard output potrebbe non essere l’idea migliore, a meno che non si esegua in contenitori. Ecco perché Log4j supporta più tipi di Appenders. Ecco alcuni esempi comuni di appendici Log4j:
- ConsoleAppender – l’appender che aggiunge gli eventi di log al sistema.fuori o sistema.err con il sistema predefinito.fuori. Quando usi questo appender vedrai i tuoi log nella console della tua applicazione.
- FileAppender-l’appender che aggiunge gli eventi di log a un file definito memorizzandoli nel file system.
- RollingFileAppender – l’appender che estende il FileAppender e ruota il file quando raggiunge una dimensione definita. L’uso di RollingFileAppender impedisce che i file di registro diventino molto grandi e difficili da mantenere.
- SyslogAppender-l’appender che invia gli eventi di log a un demone Syslog remoto.
- JDBCAppender-l’appender che memorizza gli eventi di log nel database. Tieni presente che questo appender non memorizzerà errori e generalmente non è la migliore idea per memorizzare gli eventi di registro in un database.
- SocketAppender-l’appender che invia gli eventi di log serializzati a un socket remoto. Tieni presente che questo appender non utilizza i layout perché invia gli eventi di log grezzi serializzati.
- NullAppender-l’appender che scarta solo gli eventi di log.
Inoltre, è possibile configurare più Appenders per una singola applicazione. Ad esempio, è possibile inviare i log alla console e a un file. Il seguente log4j.proprietà il contenuto del file farebbe esattamente questo:
log4j.rootLogger=DEBUG, MAIN, ROLLINGlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%r %-5p %c %x - %m%nlog4j.appender.ROLLING=org.apache.log4j.RollingFileAppenderlog4j.appender.ROLLING.File=/var/log/sematext/awesome.loglog4j.appender.ROLLING.MaxFileSize=1024KBlog4j.appender.ROLLING.MaxBackupIndex=10log4j.appender.ROLLING.layout=org.apache.log4j.PatternLayoutlog4j.appender.ROLLING.layout.ConversionPattern=%r %-5p %c %x - %m%n
Il nostro root logger è configurato per registrare tutto a partire dalla gravità del DEBUG e per inviare i log a due Appenders: il MAIN e il ROLLING. Il logger PRINCIPALE è quello che abbiamo già visto-quello che invia i dati alla console.
Il secondo logger, quello chiamato ROLLING, è il più interessante in questo esempio. Utilizza RollingFileAppender che scrive i dati nel file e definiamo quanto grande può essere il file e quanti file conservare. Nel nostro caso, i file di registro dovrebbero essere chiamati awesome.registra e scrivi i dati nella directory/var/log/ sematext/. Ogni file dovrebbe essere un massimo di 1024KB e non ci dovrebbero essere più di 10 file memorizzati. Se ci sono più file verranno rimossi dal file system non appena log4j li vede.
Dopo aver eseguito il codice con la configurazione precedente, la console stamperebbe il seguente contenuto:
0 INFO com.sematext.blog.ExampleAppenders - Starting ExampleAppenders application1 WARN com.sematext.blog.ExampleAppenders - Ending ExampleAppenders application
Nel/var/log / sematext / awesome.file di registro vorremmo vedere:
0 INFO com.sematext.blog.ExampleAppenders - Starting ExampleAppenders application1 WARN com.sematext.blog.ExampleAppenders - Ending ExampleAppenders application
Appender Log Level
La cosa bella di Appenders è che possono avere il loro livello che dovrebbe essere preso in considerazione durante la registrazione. Tutti gli esempi che abbiamo visto finora hanno registrato ogni messaggio che aveva la gravità del DEBUG o superiore. E se volessimo cambiarlo per tutte le classi della com.sematesto.pacchetto blog? Dovremmo solo modificare il nostro file log4j.properties:
log4j.rootLogger=DEBUG, MAINlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%r %-5p %c %x - %m%nlog4j.logger.com.sematext.blog=WARN
Guarda l’ultima riga nel file di configurazione sopra. Abbiamo usato il prefisso log4j.logger e abbiamo detto che il logger ha chiamato com.sematesto.blog dovrebbe essere utilizzato solo per i livelli di gravità WARN e superiori, quindi ERRORE e FATALE.
Il nostro codice di applicazione di esempio è simile a questo:
public static void main(String args) { LOGGER.info("Starting ExampleAppenderLevel application"); LOGGER.warn("Ending ExampleAppenderLevel application");}
Con la configurazione sopra Log4j l’output della registrazione appare come segue:
0 WARN com.sematext.blog.ExampleAppenderLevel - Ending ExampleAppenderLevel application
Come puoi vedere, è stato incluso solo il registro del livello di AVVISO. E ‘ esattamente quello che volevamo.
Log4j Layout
Infine, la parte del Log4j logging framework che controlla il modo in cui i nostri dati sono strutturati nel nostro file di log – il layout. Log4j fornisce alcune implementazioni predefinite come PatternLayout, SimpleLayout, XMLLayout, HTMLLayout, EnchancedPatternLayout e DateLayout.
Nella maggior parte dei casi, si incontra il PatternLayout. L’idea alla base di questo layout è che è possibile fornire una varietà di opzioni di formattazione per definire la struttura dei registri. Alcuni degli esempi sono:
- d-data e ora dell’evento di log,
- m – messaggio associato all’evento di log,
- nome t – thread,
- n – separatore di linea dipendente dalla piattaforma,
- p – livello di log.
Per ulteriori informazioni sulle opzioni disponibili, vai ai Javadoc ufficiali di Log4j per PatternLayout.
Quando si utilizza il PatternLayout possiamo configurare quale opzione vorremmo usare. Supponiamo di voler scrivere la data, la gravità dell’evento di log, il thread circondato da parentesi quadre e il messaggio dell’evento di log. Potremmo usare uno schema come questo:
%d %-5p - %m%n
Il file log4j.properties completo in questo caso potrebbe apparire come segue:
log4j.rootLogger=DEBUG, MAINlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%d %-5p - %m%n
Usiamo %d per visualizzare la data, % – 5p per visualizzare la gravità usando 5 caratteri, % t per il thread, %m per il messaggio e % n per il separatore di riga. L’output che viene scritto sulla console dopo aver eseguito il nostro codice di esempio appare come segue:
2021-02-02 11:49:49,003 INFO - Initializing ExampleLog4jFormatter application
Contesto diagnostico nidificato
Nella maggior parte delle applicazioni del mondo reale l’evento di log non esiste da solo. È circondato da un certo contesto. Per fornire tale contesto, per thread, Log4j fornisce il cosiddetto contesto diagnostico nidificato. In questo modo possiamo associare un dato thread con informazioni aggiuntive, ad esempio un identificatore di sessione, proprio come nella nostra applicazione di esempio:
NDC.push(String.format("Session ID: %s", "1234-5678-1234-0987"));LOGGER.info("Initializing ExampleLog4jNDC application");
Quando si utilizza un modello che include la variabile x, verranno incluse informazioni aggiuntive in ogni logline per il thread specificato. Nel nostro caso l’output sarà simile a questo:
0 INFO com.sematext.blog.ExampleLog4jNDC Session ID: 1234-5678-1234-0987 - Initializing ExampleLog4jNDC application
Puoi vedere che le informazioni sull’identificatore di sessione si trovano nella logline. Solo per riferimento, il file log4j. properties che abbiamo usato in questo esempio appare come segue:
log4j.rootLogger=DEBUG, MAINlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%r %-5p %c %x - %m%n
Mapped Diagnostic Context
Il secondo tipo di informazioni contestuali che possiamo includere nei nostri eventi di log è mapped diagnostic context. Utilizzando la classe MDC possiamo fornire ulteriori informazioni relative alla chiave-valore. Simile al contesto diagnostico nidificato, il contesto diagnostico mappato è legato al thread.
Diamo un’occhiata al nostro codice di applicazione di esempio:
MDC.put("user", "[email protected]");MDC.put("step", "initial");LOGGER.info("Initializing ExampleLog4jNDC application");MDC.put("step", "launch");LOGGER.info("Starting ExampleLog4jNDC application");
Abbiamo due campi di contesto: l’utente e il passo. Per visualizzare tutte le informazioni di contesto diagnostico mappate associate all’evento di log, usiamo semplicemente la variabile X nella nostra definizione del modello. Ad esempio:
log4j.rootLogger=DEBUG, MAINlog4j.appender.MAIN=org.apache.log4j.ConsoleAppenderlog4j.appender.MAIN.layout=org.apache.log4j.PatternLayoutlog4j.appender.MAIN.layout.ConversionPattern=%r %-5p %c %X - %m%n
L’avvio del codice sopra riportato insieme alla configurazione comporterebbe il seguente output:
0 INFO com.sematext.blog.ExampleLog4jMDC {{step,initial}{user,[email protected]}} - Initializing ExampleLog4jNDC application1 INFO com.sematext.blog.ExampleLog4jMDC {{step,launch}{user,[email protected]}} - Starting ExampleLog4jNDC application
Possiamo anche scegliere quali informazioni utilizzare cambiando il modello. Ad esempio, per includere l’utente dal contesto diagnostico mappato potremmo scrivere un modello come questo:
%r %-5p %c %X{user} - %m%n
Questa volta l’output sarebbe il seguente:
0 INFO com.sematext.blog.ExampleLog4jMDC [email protected] - Initializing ExampleLog4jNDC application0 INFO com.sematext.blog.ExampleLog4jMDC [email protected] - Starting ExampleLog4jNDC application
Puoi vedere che al posto del generale % X abbiamo usato %X {user}. Ciò significa che siamo interessati alla variabile utente dal contesto diagnostico mappato associato a un determinato evento di log.
Migrazione a Log4j 2
Migrazione da Log4j 1.da x a Log4j 2.x non è difficile e, in alcuni casi, può essere molto facile. Se non hai usato alcun Log4j interno 1.classi x, hai utilizzato i file di configurazione su impostazione di programmazione logger e non hai utilizzato le classi DOMConfigurator e PropertyConfigurator la migrazione dovrebbe essere semplice come includere l’api log4j-1.2.file jar jar invece del Log4j 1.x file jar. Ciò consentirebbe Log4j 2.x per lavorare con il tuo codice. Dovresti aggiungere il Log4j 2.x file jar, regolare la configurazione, e voilà-il gioco è fatto.
Se vuoi saperne di più su Log4j 2.x controlla il nostro tutorial di registrazione Java e il suo Log4j 2.x sezione dedicata.
Tuttavia, se hai usato Log4j interno 1.x classes, la guida ufficiale alla migrazione su come spostarsi da Log4j 1.da x a Log4j 2.x sarà molto utile. Discute il codice necessario e le modifiche alla configurazione e sarà inestimabile in caso di dubbio.
Registrazione centralizzata con strumenti di gestione dei log
L’invio di eventi di log a una console o a un file può essere utile per una singola applicazione, ma gestire più istanze dell’applicazione e correlare i log da più origini non è divertente quando gli eventi di log si trovano in file di testo su macchine diverse. In questi casi, la quantità di dati diventa rapidamente ingestibile e richiede soluzioni dedicate-sia self-hosted o provenienti da uno dei fornitori. E per quanto riguarda i contenitori in cui in genere non si scrivono nemmeno i registri sui file? Come si fa a risolvere ed eseguire il debug di un’applicazione i cui log sono stati emessi nello standard output o il cui contenitore è stato ucciso?
Qui entrano in gioco i servizi di gestione dei log, gli strumenti di analisi dei log e i servizi di registrazione cloud. È una best practice di registrazione Java non scritta tra gli ingegneri utilizzare tali soluzioni quando si è seri sulla gestione dei registri e ottenere il massimo da essi. Ad esempio, Sematext Logs, il nostro software di monitoraggio e gestione dei log, risolve tutti i problemi sopra menzionati e altro ancora.
Con una soluzione completamente gestita come i registri Sematext, non è necessario gestire un altro pezzo dell’ambiente: la soluzione di registrazione fai – da-te, in genere costruita utilizzando pezzi dello Stack elastico. Tali configurazioni possono iniziare piccole ed economiche, tuttavia, spesso crescono grandi e costose. Non solo in termini di costi di infrastruttura, ma anche di costi di gestione. Sai, tempo e libro paga. Spieghiamo di più sui vantaggi dell’utilizzo di un servizio gestito nel nostro post sul blog sulle migliori pratiche di registrazione.
L’avviso e l’aggregazione dei log sono cruciali anche quando si affrontano problemi. Alla fine, per le applicazioni Java, è possibile disporre di log di garbage collection una volta attivata la garbage collection e avviata l’analisi dei log. Tali registri correlati con le metriche sono una preziosa fonte di informazioni per la risoluzione dei problemi relativi alla garbage collection.
Sommario
Anche se Log4j 1.x ha raggiunto la sua fine di vita molto tempo fa è ancora presente in un gran numero di applicazioni legacy utilizzate in tutto il mondo. La migrazione alla sua versione più giovane è abbastanza semplice, ma può richiedere notevoli risorse e tempo e di solito non è una priorità assoluta. Soprattutto nelle grandi imprese in cui le procedure, i requisiti legali o entrambi richiedono audit seguiti da test lunghi e costosi prima che qualsiasi cosa possa essere modificata in un sistema già in esecuzione. Ma per quelli di noi che stanno appena iniziando o pensando alla migrazione – ricorda, Log4j 2.x è lì, è già maturo, veloce, sicuro e molto capace.
Ma indipendentemente dal framework che stai utilizzando per registrare le tue applicazioni Java, ti consigliamo vivamente di sposare i tuoi sforzi con una soluzione di gestione dei log completamente gestita, come i registri Sematext. Fare un tentativo! C’è una prova gratuita di 14 giorni disponibile per te per testarlo.
Registrazione felice!