Каков правильный способ инициализации для log4j2 в веб-приложении Spring MVC с использованием Java Config и без web.xml?

У меня есть веб-приложение Spring MVC (4.0) с log4j2. Это веб-приложение не использует файл web.xml и обеспечивает настройку через Java Config. Конфигурация Log4j2 должна выполняться во внешнем файле конфигурации, а не в пути к классам.

В предыдущем воплощении с web.xml у нас было

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>file:///path/to/log4j2.xml</param-value>
</context-param> 

и это сработало.

В новом мире без web.xml я попробовал это:

public class WebappInitializer 
extends AbstractAnnotationConfigDispatcherServletInitializer 
{

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("WebappInitializer.onStartup()");
        servletContext.setAttribute("log4jConfiguration", "file:///path/to/log4j2.xml");

Это не работает. Кажется, это происходит слишком поздно и в любом случае не работает. Журналы показывают:

ERROR StatusLogger No Log4j context configuration provided. This is very unusual.
WebappInitializer.onStartup()

и ведение журнала log4j не происходит.

Каков правильный способ заменить это объявление параметра контекста на web.xml в приложении Spring MVC без web.xml?

ОБНОВЛЕНИЕ:

Я могу решить эту проблему, добавив следующий файл web.xml:

<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">

    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>file:///path/to/log4j2.xml</param-value>
    </context-param> 

</web-app>

Конечно, должен быть лучший способ!


person Steve Cohen    schedule 01.07.2015    source источник


Ответы (3)


Я считаю, что вы можете перенастроить log4j2 в новый файл конфигурации во время выполнения, как это.

     LoggerContext context = (LoggerContext)LogManager.getContext(false);
     context.setConfigLocation(URI.create("path to file"));
     context.reconfigure();

Можно просто добавить это в свой onStartup.

person alan7678    schedule 02.07.2015

Вероятно, это слишком поздно, но вы можете сделать следующее, чтобы установить конфигурацию log4j2 на внешний путь:

public class ApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext)
        throws ServletException {
        servletContext.setInitParameter(Log4jWebSupport.LOG4J_CONFIG_LOCATION, "file:///path/to/log4j2.xml");
person Andy Ng    schedule 23.05.2016

Я не проверял это, но стоит попробовать следующее; замените вызов servletContext.setAttribute(…) в методе onStartup(…) следующим Log4jConfigurer вызов:

Log4jConfigurer.initLogging("file:///path/to/log4j2.xml")

Это в основном то, что происходит под капотом, когда вы используете log4jConfigLocation в <context-param> файла web.xml (через Log4jWebConfigurer, см. код).

Мне только интересно, будет ли это работать с log4j2, хотя я бы не ожидал, что способ <context-param> тоже будет работать с ним. Вы также использовали log4j2, когда все еще использовали файл web.xml?

person Chriki    schedule 02.07.2015
comment
С тех пор, как я вернулся к моему обходному пути с использованием минималистского web.xml, показанного выше, исчезла и другая проблема: когда не было web.xml, раз в два раза или около того горячее развертывание новой версии приложения приводило к сбою Tomcat с OutOfMemoryError. . Добавление минималистского web.xml привело к тому, что это исчезло. - person Steve Cohen; 02.07.2015
comment
Вы пробовали мое предложение с Log4jConfigurer? Мне интересно, работает ли это :-) Для этого OutOfMemoryError вы должны создать отдельный вопрос SO. - person Chriki; 03.07.2015
comment
Еще не было шанса. Мне нужно было пойти с чем-то работоспособным, чтобы добиться прогресса в работе над приложением. Сделав это, я посмотрю. И я также напишу отдельную проблему для OutOfMemoryError, если только ваш подход также не устранит ее. - person Steve Cohen; 03.07.2015
comment
К сожалению, ваше решение не работает, поскольку Log4jConfigurer зависит от DomConfigurator, которого нет в log4j2. Однако решение @alan7678, которое является более общим, работает с log4j2. Не уверен, что это работает с log4j1. Однако ошибка OutOfMemoryError сохраняется, если файл web.xml отсутствует. Как было сказано ранее, я напишу об этом еще один вопрос, если не смогу найти информацию об этом. - person Steve Cohen; 03.07.2015
comment
см. stackoverflow.com/questions/31211868/ для нового вопроса об OutOfMemory. - person Steve Cohen; 03.07.2015