2009-04-18 15 views
9

Ich habe eine EAR mit Strukturen wie:Wie konfiguriere ich mehrere log4j für verschiedene Kriege in einem einzelnen 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) 

ich jede IST will ihr eigenes Anwendungsprotokoll haben. Aber es scheint, dass die obige Konfiguration nicht funktioniert. Log für APP1 und APP2 geht in das Protokoll von APP1. Gibt es trotzdem separate App-Logs?

Antwort

7

Es stellt sich heraus, dass es aufgrund des Classloaders unmöglich ist. Die Classloader-Hierarchie ist wie:

Anwendung Classloader -> Ejb Classloader -> Krieg Classloader

Um ein sepearte Protokoll für einzelne Krieg zu haben, kann man innerhalb Krieg setzen log4j.jar und lassen Sie die log4j den Krieg verwendet Classloader. Da sowohl app1-ejb.jar als auch app2-ebj.jar log4j verwenden müssen, kann log4j.jar nur auf der obersten Ebene platziert werden. Das log4j befindet sich also auf der Ebene des Anwendungs-Klassenladeprogramms.

Ich kann eine einzelne log4j-Konfiguration angeben, um unterschiedliche Pakete in verschiedenen Dateien zu protokollieren. Aber für die gemeinsame Bibliothek wie Frühling kann der Baumstamm nicht getrennt werden.

+0

"Da sowohl app1-ejb.jar als auch app2-ebj.jar log4j verwenden müssen, kann log4j.jar nur auf der obersten Ebene platziert werden." Können Sie nicht einfach eine log4j.jar in jede WAR-Datei einfügen? – CodeClimber

0

Sie können das auch tun, indem Sie die FILE-Eigenschaft in der Eigenschaftendatei mithilfe des PropertyConfigurator im Code dynamisch ändern.

1

Der Grund, warum es nicht funktioniert, weil das log4j am Stammort vorhanden ist, stattdessen sollte jeder Krieg eine Log4j.jar in seinem Verzeichnis WEB-INF/lib haben und die log4j.jar aus dem Stamm entfernen.

Für weitere Informationen zu diesem meinem Blog finden Sie Artikel zu diesem http://techcrawler.wordpress.com/

0

Logback ist eine praktikable Lösung, um dieses Problem zu lösen. Nachdem wir uns verschiedene Hacks angeschaut haben, um dies mit log4j arbeiten zu lassen, haben wir uns entschieden, zu Logback zu wechseln. Ich habe die folgende Konfiguration mit Logback-Jar in der Webapp verwendet.

A Logback Datei im webapp, die eine externe Datei umfassen:

<?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} während Maven Filterung durch den genauen Pfad, außerhalb des webapp der Konfigurationsdatei (so etwas wie /opt/Server ersetzt wird, /conf/loback.included.conf).

Und dann wird der Inhalt der logback.included.conf (diese Datei ist Teil der projetct, mit build-helper:attach-artifact geliefert, so wird ${project.artifactId} auch bei Maven-Filterung ersetzt):

<?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> 

Nur Einschränkung der Inhalt des mitgelieferten Datei muss mit der des Includers übereinstimmen. Einfach Regeln schreiben.