Как настроить несколько log4j для разных войн в одном EAR? - PullRequest
9 голосов
/ 18 апреля 2009

У меня есть 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)

Я хочу, чтобы у каждой WAR был свой журнал приложений. Но, похоже, вышеуказанная конфигурация не работает. Журнал для APP1 и APP2 идет в журнал APP1. Есть ли возможность создавать отдельные журналы приложений?

Ответы [ 4 ]

8 голосов
/ 20 апреля 2009

Оказывается, это невозможно из-за загрузчика классов. Иерархия загрузчика классов выглядит так:

Приложение classloader -> Ejb classloader -> war classloader

Чтобы иметь отдельный журнал для отдельной войны, можно поместить log4j.jar в войну и позволить log4j использовать загрузчик классов войны. Но так как и app1-ejb.jar, и app2-ebj.jar также должны использовать log4j, log4j.jar можно разместить только на верхнем уровне. Таким образом, log4j находится на уровне загрузчика классов приложений.

Я могу указать одну конфигурацию log4j для записи разных пакетов в разные файлы. Но для обычной библиотеки, такой как spring, журнал не может быть отделен.

1 голос
/ 22 июня 2010

Причина, по которой это не сработало, потому что log4j присутствует в корневом каталоге, вместо этого пусть каждая война имеет Log4j.jar в своем каталоге WEB-INF / lib и удаляет log4j.jar из корневого каталога.

Для получения дополнительной информации об этом см. Мою статью в блоге об этом http://techcrawler.wordpress.com/

0 голосов
/ 28 сентября 2011

Logback является жизнеспособным решением для решения этой проблемы. После просмотра различных хаков для работы с log4j, мы решили переключиться на Logback. Я использовал следующую конфигурацию с jar Logback внутри веб-приложения.

Файл Logback внутри веб-приложения, который включает внешний файл:

    <?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} заменяется во время фильтрации Maven точным путем, внешним по отношению к веб-приложению файла конфигурации (что-то вроде / opt / server / conf / loback.included.conf ).

И затем содержимое logback.included.conf (этот файл является частью проекта, поставляемого с build-helper:attach-artifact, поэтому ${project.artifactId} также заменяется во время фильтрации 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>

Единственное ограничение, содержимое включаемого файла должно соответствовать одному из включаемых файлов. На самом деле просто пишу правила.

0 голосов
/ 23 сентября 2009

Вы также можете сделать это, динамически изменяя свойство FILE в файле свойств, используя PropertyConfigurator в коде.

...