2009-05-15 21 views
82

Ho un'applicazione esistente che fa tutto il suo logging contro log4j. Usiamo un certo numero di altre librerie che usano anche log4j, o log contro Commons Logging, che finisce usando log4j sotto le copertine nel nostro ambiente. Una delle nostre dipendenze registra anche su slf4j, che funziona anche bene poiché alla fine delega anche a log4j.Come inviare java.util.logging a log4j?

Ora, vorrei aggiungere ehcache a questa applicazione per alcune esigenze di memorizzazione nella cache. Le versioni precedenti di ehcache utilizzavano la registrazione delle risorse comuni, che avrebbe funzionato perfettamente in questo scenario, ma a partire da version 1.6-beta1 hanno rimosso la dipendenza da commons-logging e lo hanno invece sostituito con java.util.logging.

Non avendo familiarità con la registrazione JDK integrata disponibile con java.util.logging, c'è un modo semplice per fare in modo che i log inviati a JUL vengano registrati su log4j, quindi posso usare la mia configurazione esistente e configurare per ogni registrazione proveniente da ehcache?

Guardando le javadocs per luglio, sembra che ho potuto istituire un gruppo di variabili d'ambiente per modificare l'LogManager implementazione viene utilizzata, e forse l'uso che per avvolgere log4j Logger s nella classe luglio Logger. È questo l'approccio corretto?

È un po 'ironico che l'utilizzo di una registrazione JDK incorporata da una libreria possa causare un tale mal di testa quando (la maggior parte) il resto del mondo utilizza invece le librerie di terze parti.

risposta

36

Un approccio che ho usato con successo è quello di utilizzare slf4j come la mia API di registrazione principale. Quindi ho slf4j bind a log4j. Le dipendenze di terze parti che utilizzano altri framework (come JUL) possono essere da bridged a slf4j.

+2

buon collegamento, ma penso che si intende # lug-to-slf4j – araqnid

+0

Buona cattura. Ho aggiornato la risposta di conseguenza. Grazie! – overthink

+0

Questo sembra un buon approccio, tranne che non riesco a farlo funzionare :( –

3

Il sito slf4j credo abbia un bridge per passare eventi java.util.logging tramite slf4j (e quindi a log4j).

Sì, il download di SLF4J contiene jul-to-slf4j che credo faccia proprio. Contiene un gestore JUL per passare i record a SLF4J.

+0

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j –

18

Utilizziamo il SLF4J sul nostro progetto attuale e ha funzionato molto bene per noi. SLF4J è scritto da Ceki Gülcü, il creatore di Log4J, e ha fatto un ottimo lavoro. Nel nostro codice utilizziamo direttamente le API di registrazione SLF4J e configuriamo SLF4J in modo che le chiamate dalle API Jakarta Commons Logging (JCL), java.util.logging (JUL) e Log4J siano tutte collegate alle API SLF4J. Dobbiamo farlo perché, come voi, utilizziamo librerie di terze parti (open source) che hanno scelto API di registrazione diverse.

Nella parte inferiore di SLF4J, lo si configura per utilizzare un'implementazione particolare del registratore. Viene fornito con un logger interno o "semplice" e puoi sostituirlo con Log4J, JUL o Logback. La configurazione viene eseguita semplicemente facendo cadere diversi file jar nel classpath.

Inizialmente, abbiamo utilizzato l'implementazione Logback, anch'essa scritta da Ceki Gülcü. Questo è molto potente. Tuttavia, abbiamo deciso di implementare la nostra applicazione sul server di applicazioni Java EE Glassfish, il cui visualizzatore di log prevede messaggi in formato JUL. Così oggi sono passato da Logback a JUL e in pochi minuti ho sostituito due contenitori di logback con un jar SLF4J che lo collega all'implementazione JUL.

Così come @ overthink, raccomando vivamente di utilizzare SLF4J nella configurazione.

+7

Quante volte Ceki ha bisogno di reinventare un framework/fascade di registrazione? –

+0

@mP: la registrazione potrebbe non essere affascinante, ma è un'esigenza cruciale per il software di livello commerciale su larga scala. E SLF4J risolve il problema dell'integrazione del codice che utilizza disparati framework di registrazione (resi più urgenti da Sun che ha scelto di sviluppare java.utils.logging invece di adottare Log4J). –

+3

@mP, slf4j era necessario perché il cattivo lavoro di Sun l'ha fatto con JUL. Logback è un fork di log4j, non un nuovo progetto. –

2

@Yishai - Grazie per aver pubblicato il collegamento al mio wiki. L'esempio in questo caso reindirizza JUL a Log4J e l'ho eseguito in un sistema di produzione per alcuni anni. JBoss 5.x ha già reindirizzato JUL a Log4J, quindi l'ho rimosso al momento dell'aggiornamento.Ne ho uno più recente che reindirizza a SLF4J, che uso ora su alcune cose. Lo posterò quando avrò la possibilità.

Tuttavia, SLF4J sia già informata:

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j

12

C'è un'alternativa più semplice rispetto SLF4J per colmare luglio con log4j, consultare http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

Non vi resta che mettere il luglio-log4j-bridge nel classpath e aggiungere una proprietà di sistema:

-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager 

luglio-log4j-ponte non è in Maven centrale e può b e recuperati da questo repository:

<repository> 
    <id>psmith</id> 
    <url>http://people.apache.org/~psmith/logging.apache.org/repo</url> 
    <releases> 
    <enabled>false</enabled> 
    </releases> 
</repository> 

e quindi utilizzato con:

<dependency> 
    <groupId>org.apache.logging</groupId> 
    <artifactId>apache-jul-log4j-bridge</artifactId> 
    <version>1.0.0-SNAPSHOT</version> 
    <scope>test</scope> 
    <exclusions> 
    <exclusion> 
     <groupId>log4j</groupId> 
     <artifactId>apache-log4j-component</artifactId> 
    </exclusion> 
    </exclusions> 
</dependency> 

E 'anche possibile ricostruirlo da fonti con i seguenti passi:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. modifica pom.xml, sostituisci la dipendenza su log4j: log4j: 1.2.15 con log4j: apache-log4j-extras: 1.2.17 e rimuovi la dipendenza da apache-log4j-compon ent
  3. pacchetto mvn
+0

Non è più semplice se si utilizza già SLF4J. :) –

+3

Penso che sia più semplice perché può essere fatto senza modificare il codice, devi solo aggiungere una proprietà di sistema. SLF4J non propone ancora un meccanismo simile, puoi cambiare il codice o il file 'logging.properties'. –

+1

Questo non esiste in log4j2, sfortunatamente :( – BeepDog