Domanda

Ho un EAR con strutture come:

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 ogni WAR di avere il proprio registro di applicazione. Ma sembra che la configurazione di cui sopra non funziona. Log per APP1 e APP2 va a registro di APP1. Esiste un modo per creare registri app separate?

È stato utile?

Soluzione

Si scopre che è impossibile a causa del programma di caricamento classe. La gerarchia classloader è come:

classloader Applicazione -> Ejb classloader -> classloader guerra

Per avere un registro sepearte per la guerra individuale, si può mettere dentro log4j.jar guerra e lasciare che il log4j utilizza il classloader guerra. Ma sia come app1-ejb.jar e app2-ebj.jar anche bisogno di utilizzare log4j, il log4j.jar può essere eseguito solo al livello più alto. Così il log4j è sul livello di applicazione di caricamento classe.

Posso specificare una singola configurazione log4j per accedere pacchetto differente di file diversi. Ma per la libreria comune come la primavera, il registro non può essere sepearted.

Altri suggerimenti

Il motivo non ha funzionato perché il log4j è presente al percorso principale, lasciate invece ogni guerra hanno un log4j.jar nella sua directory WEB-INF / lib e rimuovere il log4j.jar dalla radice.

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

È anche possibile farlo modificando dinamicamente la proprietà del file nelle proprietà del file utilizzando il PropertyConfigurator nel codice.

Logback è una soluzione praticabile per affrontare questo problema. Dopo aver un'occhiata in giro diversi hack per fare questo lavoro con log4j, abbiamo deciso di passare a Logback. Ho usato la seguente configurazione con vaso Logback all'interno della webapp.

Un file 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} viene 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 è parte del projetct, consegnato con build-helper:attach-artifact, così ${project.artifactId} viene anche sostituito durante il filtraggio 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>

Solo limitazione, il contenuto del file incluso deve essere compatibile con quella del Includer. Basta scrivere le regole di fatto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top