Pergunta

Eu tenho um EAR com estruturas como:

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)

Eu quero que cada WAR para ter seu próprio registo de aplicação. Mas parece que a configuração acima não funciona. Log para APP1 e APP2 vai para log do APP1. Existe uma maneira de criar logs de aplicativos separados?

Foi útil?

Solução

Acontece que é impossível devido ao carregador de classe. A hierarquia do carregador de classe é semelhante:

carregador de classe de aplicativo -> Ejb carregador de classe -> guerra carregador de classe

Para ter um log sepearte para a guerra indivíduo, pode-se colocar guerra dentro log4j.jar e deixar o log4j usa o carregador de classe guerra. Mas como ambos app1-ejb.jar e app2-ebj.jar também precisa usar log4j, o log4j.jar só pode ser colocado no nível superior. Assim, o log4j está no nível carregador de classe do aplicativo.

Eu posso especificar uma única configuração log4j para fazer logon pacote diferente para diferentes arquivos. Mas para a biblioteca comum como a primavera, o log não pode ser sepearted.

Outras dicas

A razão por que não funcionou porque o log4j está presente no local raiz, mas deixar que cada guerra têm um log4j.jar em seu diretório WEB-INF / lib e remova o log4j.jar a partir da raiz.

Para obter mais informações sobre isso, consulte o meu artigo blog sobre este http://techcrawler.wordpress.com/

Você também pode fazer isso alterando dinamicamente a propriedade de arquivo no arquivo de propriedades usando o PropertyConfigurator no código.

Logback é uma solução viável para resolver este problema. Depois de ter olhar em torno de diferentes hacks para fazer este trabalho com log4j, decidimos mudar para Logback. Eu usei a seguinte configuração com Logback frasco dentro do webapp.

Um arquivo Logback dentro do webapp que incluem um arquivo externo:

    <?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} é substituído durante Maven filtrando pelo caminho exato, externo ao webapp do arquivo de configuração (algo como /opt/server/conf/loback.included.conf ).

E, em seguida, o conteúdo do logback.included.conf (este arquivo é parte do projetct, entregue com build-helper:attach-artifact, então ${project.artifactId} também é substituído durante a filtragem 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>

Apenas limitação, o conteúdo do arquivo incluído deve ser compatível com a do includer. Apenas escrever regras de fato.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top