Slf4j: una libreria per interfacciarsi ai sistemi di logging Java

Slf4j: una libreria per interfacciarsi ai sistemi di logging Java

In questo articolo vedremo come utilizzare la libreria Slf4j per poterci interfacciare ad una libreria di logging per Java, quale ad esempio log4j, java.util.logging oppure JCL. Slf4j fornisce infatti, un'astrazione dei sistemi di logging presenti nel panorama Java, offrendo una facade (letteralmente una "facciata" o meglio una interfaccia, è uno dei design pattern più noti nella programmazione ad oggetti) che permette di unificare la chiamata ai diversi sistemi di logging attraverso una interfaccia unica.

Tutorial GWT: creiamo un servizio GWT RPC
ICEfaces: installiamo il plugin per Eclipse e creiamo un progetto di esempio
TagSoup: un parser HTML per Java

In questo articolo vedremo come utilizzare la libreria Slf4j per poterci interfacciare ad una libreria di logging per Java, quale ad esempio log4j, java.util.logging oppure JCL. Slf4j fornisce infatti, un’astrazione dei sistemi di logging presenti nel panorama Java, offrendo una facade (letteralmente una “facciata” o meglio una interfaccia, è uno dei design pattern più noti nella programmazione ad oggetti) che permette di unificare la chiamata ai diversi sistemi di logging attraverso una interfaccia unica.

Il design pattern facade è possibile schematizzarlo tramite la seguente figura:

Il Design Pattern Facade

come si nota, la interfaccia facade fornisce un unico metodo (nel nostro caso la richiesta di logging), sarà poi lei a capire  a quale oggetto reale (che implementa il sistema di logging) delegare la chiamata.

Slf4j riesce a capire a quale sistema delegare il logging a deployment time, andando a ricercare nel classpath quale libreria jar è disponibile. Per poter supportare queste librerie, oltre al jar di implementazione (slf4j-api-version.jar), slf4j fornisce i cosiddetti Slf4j bindings che sono dei pacchetti jar uno per ogni sistema di logging supportato, questi comprendono:

  • slf4j-log4j12-version.jar: binding per log4j;
  • slf4j-jdk14-version.jar: binding per java.util.logging, chiamato anche Jdk 1.4 logging;
  • slf4j-jcl-version.jar: binding per la libreria Jakarta Commons Logging;
  • slf4j-nop-version.jar: binding per la libreria NOP che serve semplicemente per ignorare tutti gli statement di logging;
  • slf4j-simple-version.jar: binding per la libreria Simple, che è una implementazione molto semplice di un sistema di logging, che stampa tutti i messaggi sulla console System.err e solo quelli con livello maggiore di INFO.

Ognuno di questi binding è collegato a compile time con la rispettiva libreria di logging, ad esempio slf4j-log4j12-version.jar è collegato a compile time con la libreria di logging log4j. Nel classpath del nostro codice, oltre alla libreria base slf4j-api-version.jar, ci sarà uno  e uno soltanto di questi binding, non ne inseriamo mai più di uno!

La libreria di base chiama a sua volta uno dei binding

Possiamo scaricare la libreria e tutti i binsing dal sito:

http://www.slf4j.org/download.html

Quale potrebbe essere il motivo che ci spinge ad utilizzare questo livello di astrazione?

Ebbene in tutti quei casi in cui non vogliamo che il nostro codice imponga ad un utilizzatore finale quale libreria di logging utilizzare. Ad esempio se stiamo sviluppando una libreria che può essere utilizzata in codice di terze parti, è desiderabile che il nostro sistema di logging non vada in conflitto o si sovrapponga con il sistema di un’altra libreria o con il codice dell’utente. Nel caso in cui la nostra libreria venisse utilizzata in un sistema in cui è già presente un sistema di logging, non basterà altro che aggiungere il binding adeguato per la nostra libreria slf4j.

Come ulteriore esempio basta citare che il framework Hibernate utilizza slf4j proprio per astrarre dal sistema di logging che poi sarà effettivamente utilizzato nel software in cui sarà impiegato.

Vediamo ora un semplice utilizzo di slf4j, creiamo un nuovo Progetto Java in Eclipse (File -> New -> Java Project), creiamo una cartella lib e vi copiamo la libreria slf4j-api-version.jar, a questo punto dobiamo decidere quale sistema di logging utilizzare andando a copiare il binding adatto, supponiamo di voler utilizzare log4j, per cui avremo le seguenti librerie nella cartella lib (non dimentichiamoci di includerle nel Build Path del nostro progetto: click col tasto destro -> Build Path -> Configure Build Path):

  • slf4j-api-version.jar;
  • slf4j-log4j12-version-jar;
  • log4j-version.jar.

Scriviamo il codice seguente:

package it.appuntisoftware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestSlf4j {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(TestSlf4j.class);
logger.info("Test di Slf4j");
}
}

Otteniamo questo output sulla consolle:

log4j:WARN No appenders could be found for logger (it.appuntisoftware.TestSlf4j).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

questo perchè log4j si aspetta un file di configurazione di tipo log4j.properties, per vederne un esempio si legga questo articolo su log4j.

Possiamo testare il corretto funzionamento di slf4j utilizzando invece la libreria Simple, inclusa nel pacchetto che abbiamo scaricato dal sito del progetto, il cui  binding è incluso nel jar stesso, incluse nel pacchetto che abbiamo scaricato dal sito del progetto ed otteniamo questo output:


0 [main] INFO it.appuntisoftware.TestSlf4j - Test di Slf4j

infine possiamo usare il binding slf4j-nop-version, il quale cattura tutte le richieste di logging e non stampa alcunché! 🙂

COMMENTS

WORDPRESS: 0