Как правильно отключить log4j2
Если кто-то не работает внутри веб-приложения, как правильно отключить Log4j2? Я вижу только noop LogManager.shutdown()
3 ответа
Для этого нет общедоступного API, но вы можете использовать
((LifeCycle) LogManager.getContext()).stop();
Если у вас есть интерес к общедоступному API для этого, пожалуйста, проголосуйте или добавьте комментарий здесь: https://issues.apache.org/jira/browse/LOG4J2-124
Обновить:
В Log4j 2.5 можно звонить Configurator.shutdown()
, С Log4j 2.6 вы можете позвонить LogManager.shutdown()
,
БиблиотекаLog4j-Web является предпочтительным способом правильной очистки ресурсов в Web-приложении.
Чтобы включить его, добавьте такую зависимость в ваш pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
<scope>runtime</scope>
</dependency>
Он будет работать "из коробки" в среде Servlet 3.*. Если вы используете более старую спецификацию сервлета, подробности о том, как включить надлежащую очистку для log4j2, доступны здесь: https://logging.apache.org/log4j/2.x/manual/webapp.html
Объяснение и история позади
Внутреннее использование Log4j 2 - это то, что они называют ShutdownRegistrationStrategy. Он состоит из класса, который регистрирует один или несколько обратных вызовов выключения, которые будут вызваны в соответствующее время. Они предоставляют интерфейс с именем ShutdownCallbackRegistry
и их реализация по умолчанию называется DefaultShutdownCallbackRegistry
, Эта реализация регистрирует себя как отключение JVM, с Runtime.getRuntime().addShutdownHook()
,
В соответствии с некоторыми проблемами в системе отслеживания ошибок Log4j 2 ( LOG4J2-868 и LOG4J2-658) правильным способом было бы обеспечить собственную реализацию ShutdownCallbackRegistry
интерфейс. Поскольку нет общедоступного API для завершения Log4j 2, это единственный реальный и действительный способ архивировать это.
Предложенное решение
Итак, что я сделал, чтобы это исправить, так это то, что я реализовал свою собственную версию ShutdownCallbackRegistry
интерфейс. Он в основном выполняет те же действия, что и реализация по умолчанию, но вместо того, чтобы регистрироваться как перехватчик завершения, он ждет, пока не будет вызван вручную. Это стало возможным благодаря внутреннему хранению экземпляра объекта в статическом поле. Затем вам нужно вызвать только один статический метод для запуска процедуры завершения работы, поэтому я назвал его StaticShutdownCallbackRegistry
,
Вы можете найти полное решение и инструкции на https://github.com/DjDCH/Log4j-StaticShutdown и использовать его в своих собственных проектах. В конце концов, вам нужно всего лишь сделать что-то подобное в вашем приложении:
StaticShutdownCallbackRegistry.invoke();
Я не могу без сомнения сказать, что это идеальное решение и что моя реализация идеальна, но я попытался сделать это правильно (в соответствии с отсутствующей документацией об этом). Я буду рад услышать ваши отзывы, если вы найдете это решение подходящим или нет.