Java: come integrare slf4j e log4j
Lo scenario di utilizzo è questo:
Stiamo sviluppando una applicazione complessa, che utilizza come piattaforma di logging slf4j. Simple Logging Facade for Java (SLF4J) non è altro che questo:
The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.
La nostra applicazione utilizza ovviamente alcune librerie, qualcuna scritta da noi, altre scritte da terzi. Alcune di queste librerie utilizzano log4j. Lo scopo di questo esempio è mostrare come utilizzare il brigde:
per redirigere tutto il log proveniente da log4j verso slf4j.
In questo esempio abbiamo 3 progetti:
- Una libreria che utilizza log4j
- Una libreria che utilizza slf4j
- Un progetto che utilizza slf4j implementandolo con la sua implementazione nativa Logback
La libreria che utilizza log4j ne dichiara la dipendenza nel pom in questo modo:
<dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> |
invece la libreria che utilizza slf4j lo fa in questo modo:
<dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> </dependencies> |
Il progetto che utilizza Logback, e usa entrambe le librerie dichiara la dipendenza ad entrambe, ma esclude dalle sue dipendenze log4j:
<dependencies> <dependency> <groupId>it.nicola.esempi</groupId> <artifactId>libreria-che-usa-log4j</artifactId> <version>0.0.1</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>it.nicola.esempi</groupId> <artifactId>libreria-che-usa-sfl4j</artifactId> <version>0.0.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> </dependencies> |
Le prime due dipendenze sono le librerie, la terza dipendenza:
<dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.5</version> </dependency> |
è il bridge per che trasforma le chiamate a log4j a chiamate a slf4j. La quarta dipendenza:
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> |
è l’effettivo framework usato dal progetto per il logging.
Senza l’esclusione di log4j avremmo nel classpath finale del progetto anche log4j.jar, e non verrebbe quindi utilizzato il brigde, che non fa altro che andare a sostituire le chiamate di log4j.
Il progetto di esempio contiene solo questo codice:
public static void main( String[] args ) { logger.debug("Sono un progetto che utilizza due librerie"); LibreriaL4J.faiQualcosa(); LibreriaSLF4J.faiQualcosa(); } |
Se lo lancio ottengo questo:
18:24:03.920 [main] DEBUG i.n.esempi.progettoslf4j.Progetto - Sono un progetto che utilizza due librerie 18:24:03.928 [main] DEBUG i.n.e.l.LibreriaL4J - Sono una libreria che usa log4j 18:24:03.929 [main] DEBUG i.n.e.l.LibreriaSLF4J - Sono una libreria che usa slf4j |
quindi tutto il log, anche quello proveniente da log4j viene rediretto verso slf4j, e quindi logback.
Leave a Reply