2009-04-18 14 views
9

Ho un EAR con strutture come:Come configurare più log4j per diversi conflitti in un singolo EAR?

APP.ear 
- APP1.war 
    - WEB-INF/classes/log4j.properties 
- APP2.war 
    - WEB-INF/classes/log4j.properties 
- app1-ejb.jar 
- app2-ejb.jar 
- log4j.jar 
- spring.jar 
- commons-lang.jar (...and other jar) 

voglio ciascun WAR da avere il proprio registro di applicazione. Ma sembra che la configurazione di cui sopra non funziona. Accedi per APP1 e APP2 passa al registro di APP1. Esiste comunque la possibilità di creare registri delle app separati?

risposta

7

Si scopre che è impossibile a causa del classloader. La gerarchia è come classloader: classloader

Applicazione -> Ejb classloader -> classloader guerra

Per avere un registro sepearte per la guerra individuale, può essere messo dentro log4j.jar guerra e lasciare che il log4j utilizza il classloader guerra. Ma poiché anche app1-ejb.jar e app2-ebj.jar devono utilizzare log4j, il file log4j.jar può essere posizionato solo al livello più alto. Quindi il log4j è sul livello del programma di caricamento delle applicazioni.

Posso specificare un singolo log4j config per registrare diversi pacchetti in file diversi. Ma per la biblioteca comune come la primavera, il registro non può essere sepolto.

+0

"Tuttavia, sia come app1-ejb.jar che app2-ebj.jar devono utilizzare log4j, il file log4j.jar può essere posizionato solo al livello più alto." Non puoi semplicemente includere un log4j.jar in ciascuno dei file WAR? – CodeClimber

0

È anche possibile farlo cambiando dinamicamente la proprietà FILE nel file delle proprietà utilizzando PropertyConfigurator nel codice.

1

Il motivo non ha funzionato perché il log4j è presente nella posizione di root, invece ogni war ha un Log4j.jar nella sua directory WEB-INF/lib e rimuove il log4j.jar dalla root.

Per maggiori informazioni consultare il mio blog articolo su questo http://techcrawler.wordpress.com/

0

Logback è una soluzione praticabile per affrontare questo problema. Dopo aver esaminato diversi hack per farlo funzionare con log4j, abbiamo deciso di passare a Logback. Ho usato la seguente configurazione con il logback jar all'interno della webapp.

file di

A Logback all'interno della webapp che includono un file esterno:

<?xml version="1.0" encoding="UTF-8" ?> 
    <configuration scan="true" scanPeriod="10 seconds"> 
     <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> 
      <resetJUL>true</resetJUL> 
     </contextListener> 

     <contextName>${project.artifactId}</contextName> 

     <jmxConfigurator /> 

     <include file="${logback.configuration.filepath}" /> 
    </configuration> 

${logback.configuration.filepath} è sostituito durante la filtrazione Maven dal percorso esatto, esterno alla webapp del file di configurazione (qualcosa come /opt/server /conf/loback.included.conf).

E poi, il contenuto del logback.included.conf (questo file fa parte della projetct, consegnato con build-helper:attach-artifact, così ${project.artifactId} è anche sostituito durante la filtrazione Maven):

<?xml version="1.0" encoding="UTF-8" ?> 
    <included> 
     <appender name="file" class="ch.qos.logback.core.FileAppender"> 
      <file>/var/log/server/${project.artifactId}.log</file> 
      <encoder> 
       <pattern>[@/%contextName] %date{ISO8601} [%-5level] %thread:[%logger] %msg%n</pattern> 
      </encoder> 
     </appender> 

     <root level="INFO"> 
      <appender-ref ref="file" /> 
     </root> 
    </included> 

unica limitazione, il contenuto della dotazione il file deve essere conforme a quello del comprender. Basta scrivere regole di fatto.

Problemi correlati