ссылаясь на файл конфигурации log4j из файла конфигурации log4j на пути к классам - PullRequest
1 голос
/ 03 января 2011

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

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

В конце я хотел бы иметь возможность настроить ведение журнала для конкретного приложения для отладки и устранения неполадок без изменения общей конфигурации в файле JAR.

Ответы [ 3 ]

1 голос
/ 04 января 2011

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

По сути, я создал один файл common.jar, который содержит общий код.Этот jar содержит log4j.xml, который устанавливает уровень журнала в INFO и устанавливает для стандартного приложения appdout для common.jar.Эта конфигурация log4j используется в качестве базовой для всех других приложений.

В этом примере представьте, что этот класс находится внутри common.jar:

public class ThirdPartyLib 
{
    protected static final Logger log = LogManager.getLogger("third-party-lib");
    public void doSomething()
    {
        log.debug("Third Party App is about to Do something!");
        log.info("Third Party App just did something");
    }
}

Теперь все другие веб-приложения могут просто зависеть от common.jar.Например, представьте, что этот класс находится внутри myapp.war:

public class MyApp
{
    public void CallThirdParty()
    {
        ThirdPartyLib lib = new ThirdPartyLib();
        lib.doSomething();
    }
}

Поскольку log4j.xml находится внутри common.jar, этот код будет регистрировать что-то вроде этого.Другими словами, нет необходимости помещать log4j.xml в myapp.war:

2011-01-03 15:49:22,451 [main] INFO  third-party-lib - Third Party App just did something

Теперь, если вы хотите / должны контролировать вход в myapp.war, просто поместите log4j.xml внутри myapp..war и переопределить настройки из common.jar.Например, вы можете установить уровень DEBUG, и тогда вы увидите:

2011-01-03 16:03:22,928 [main] DEBUG third-party-lib - Third Party App is about to Do something!
2011-01-03 16:03:22,928 [main] INFO  third-party-lib - Third Party App just did something

ОБНОВЛЕНИЕ - Можно ли настроить каждое веб-приложение для входа в отдельный файл?

Да, определенно.Например, вы можете направлять журналы в RollingFileAppender вместо stdout внутри log4j.xml для myapp.war.Это удобно, потому что тогда вы можете хранить каждый отдельный журнал веб-приложения в отдельном файле.

Кроме того, я написал фильтр сервлетов (похожий на предложенный gigadot), который настраивает log4j для проверки того, существует ли log4j.xml на внешнем пути (вне войны каждого веб-приложения).Таким образом, файлы log4j.xml доступны за пределами войн, и мы можем устанавливать уровни журналов, не перезапуская контейнер сервлета (в данном случае tomcat).Если внешний файл log4j.xml не существует, по умолчанию он использует файл log4j.xml для каждого пути к классам приложений.

1 голос
/ 04 января 2011

Если у вас есть несколько файлов jar / war, каждый файл имеет свой собственный файл log4j.xml, и вам не нужно беспокоиться о том, какой файл log4j.xml загружается, вы можете явно загрузить конфигурацию самостоятельно.

Для проекта webapp, поместите следующий слушатель контекста в качестве первого слушателя в вашем файле web.xml. Это загрузит log4j с вашего пути предпочтения.

<listener>
    <listener-class>mycompany.server.listener.Log4JInitServletContextListener</listener-class>
</listener>

Реализация Log4JInitServletContextListener.

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

Как видите, вы можете использовать этот метод для программной загрузки log4j.xml в зависимости от условия.

package mycompany.server.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.xml.DOMConfigurator;

public class Log4JInitServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        org.w3c.dom.Element log4jConfigElement = parseFromInputStream(getClass().getResourceAsStream("/unique/package/name/in/common/jar/log4j.xml"););
        DOMConfigurator.configure(log4jConfigElement);
    }

    // omit the rest and implementation of parseFromInputStream method
}
0 голосов
/ 03 января 2011

Я не уверен, что это может помочь, но вы можете установить расположение файла свойств следующим образом:

java -Dlog4j.configuration=jar:file:/full/path/to/app.jar!/log4j.properties -jar app.jar 
...