Log4j configureAndWatch () порождает тысячи потоков - PullRequest
2 голосов
/ 27 августа 2009

Итак, у нас есть наше приложение J2EE, использующее Log4j, вот так

public class CustomerController 
{
    private static Logger logger = Logger.getLogger(CustomerController.class);

     public CustomerService customerservice = null;

     public CustomerController() throws Exception 
     {
           PropertyConfigurator.configureAndWatch("c:\log4j.property", 50000);

            customerservice = ServiceManagerSingleton.getCustomerServiceInstance();
     }
}

Таким образом, мы можем изменить уровень журнала в реальном времени. Очень кстати. Большинство наших классов настроены так же, как этот контроллер. Мы используем шаблон синглтона, чтобы у нас был только один экземпляр класса eash; один вызов PropertyConfigurator.configureAndWatch () для каждого класса, один раз.

Проблема: примерно два раза в неделю наш сервер приложений умирает и создает кучу данных. Используя Heap Analyzer от IBM, мы видим, что существует множество потоков, связанных с Log4j:

 808 (0%) [200] 9 org/apache/log4j/PropertyWatchdog 0x14282ad8

Всего около 30000. Так что это, вероятно, причина внезапного сбоя.

  1. Правильно ли мы это настраиваем?
  2. Что происходит со всеми этими потоками при повторном развертывании EAR?

Ответы [ 4 ]

7 голосов
/ 27 августа 2009

Как часто создаются экземпляры CustomerController? Один раз за запрос? Потому что я считаю, что configureAndWatch () будет порождать новый поток при каждом вызове.

Кроме того, если вы не в курсе, документация log4j предостерегает от использования этой функции в среде J2EE:

Поскольку configureAndWatch запускает отдельный поток wathdog и поскольку нет способа остановить этот поток в log4j 1.2, метод configureAndWatch небезопасен для использования в средах J2EE, в которых приложения перерабатываются.

Я знаю, что вы не используете Spring, но, по моему мнению, класс Spring Log4jWebConfigurer имеет лучшее объяснение о том, почему эта функция опасна в J2EE:

ПРЕДУПРЕЖДЕНИЕ: Поток сторожевого таймера Log4j не прерывается до выключения виртуальной машины; в частности, он не завершается при завершении работы LogManager. Поэтому рекомендуется не использовать обновление файла конфигурации в рабочей среде J2EE; сторожевой поток не будет останавливаться при закрытии приложения.

Обновление: Глядя на источник log4j, каждый вызов configureAndWatch () действительно создает новый поток .

4 голосов
/ 27 августа 2009

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

Вы должны быть уверены, что метод PropertyConfigurator.configureAndWatch вызывается только один раз. Один из способов сделать это - поместить что-то в JNDI.

Многое из этого будет зависеть от того, что сервер приложений вам дает. Например, мы используем JBoss, и Log4J настроен как его часть, и вы просто изменяете файл log4j.xml, чтобы включить в него то, что нужно вашим классам. JBoss гарантирует, что это делается динамически.

РЕДАКТИРОВАТЬ: Здесь - это инструкции для Websphere по созданию настраиваемой службы, внутри которой вы создадите свою конфигурацию log4J и выполните мониторинг файла. Пара предостережений. Вам нужно будет добавить log4j.jar в classpath самого сервера приложений, чтобы он был доступен для войны или ушей (я уверен, что это будет работать в любом случае), и пользовательская служба, скорее всего, не будет работа внутри уха.

Здесь - это альтернатива, которая будет держать все на войне или слух, но за счет динамической загрузки изменений в журнале.

0 голосов
/ 27 августа 2009

Все регистраторы используют один и тот же файл конфигурации, поэтому, если каждый класс, использующий регистратор, содержит этот код инициализации, каждый вызов configureAndWatch (), скорее всего, создаст новый поток наблюдателя. (IMHO, Log4j должен знать лучше и включать не более одного потока-наблюдателя на файл конфигурации, но, очевидно, это не так)

0 голосов
/ 27 августа 2009

Вы смотрели logback, преемник log4j? Он имеет дело с перезагрузкой своей конфигурации либо в потоке или через JMX . Оба подхода позволяют избежать головной боли, вызванной вызовом PropertyConfigurator.configureandWatch () или DOMConfigurator.configurator. Интересно отметить, что подход в потоке включен через файл конфигурации (никакой пользовательский код не требуется).

...