Как подключить Log4j2 в Spring 4

Итак, Хьюстон Spring, у нас проблема.

В свой проект я решил подключить логирование (внезапно, да?) с использованием Log4j. Зашёл я к ним на сайт, посмотрел, что появилась новая версия Log4j — version 2, и добавил её в maven dependency. Но была проблема — логи не писались. Вообще никуда и никакие. Сначала думал, что не правильная конфигурация Log4j2, потому что консоль ругалась постоянно на:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Да и какие-никакие логи (от hibernate, например) — шли, укрепляя мою уверенность в кривую конфигурацию. А что там делает SLF4J, которого у меня в POM-файлах в помине нет я как-то не успевал задуматься :)

А через какое-то время стало не до логов (ведь всегда есть дебаг под рукой) и я перестал обращать на это внимание. Но потом всё вернулось к логированию снова. Столкнулся с проблемой, что REST контроллер не хотел принимать @RequestBody объекты. Постоянно ругался ошибкой 400 Bad Request. Понятно, что проблема в отправляемых данных, но вот где именно — одним дебагом было не обойтись, а помнить все классы, в которых происходит маппинг JSON в объекты или где обрабатываются методы помеченные аннотацией @RequestMapping — довольно сложно :)

Пришлось снова возвращаться к проблеме логирования. К слову — конфигурация Log4j2 была описана предельно простая:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Appenders>
		<File name="file" fileName="log4j2.log" append="true">
			<PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
		</File>
		<Console name="console" target="SYSTEM_OUT">
			<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
		</Console>
	</Appenders>
	<Loggers>
		<Root level="debug">
			<Appender-ref ref="file"/>
			<Appender-ref ref="console"/>
		</Root>
		<Logger name="org.springframework.web" level="debug">
			<Appender-ref ref="file"/>
			<Appender-ref ref="console"/>
		</Logger>
	</Loggers>
</Configuration>

Как видно — для всего Spring Web MVC установлен уровень DEBUG. Но — тишина. В Google — тишина. Потом я обратил внимание, ведь при запуске ругается на SLF4J, которого у меня в помине нет! Решил добавить мост для SLF4J в maven.

После чего стали происходить различные чудеса. Чаще всего это были ClassNotFoundException:

Failed to instantiate SLF4J LoggerFactory
Reported exception:
java.lang.NoClassDefFoundError: org/apache/logging/log4j/spi/AbstractLoggerAdapter

И прочие подобные. Через какое-то время я дошёл до ошибки:

java.lang.NoClassDefFoundError: org/apache/log4j/LogManager

И тут до меня дошло. Spring 4 использует SLF4J, который использует Log4j первой версии.

Дальше были попытки заставить использовать SLF4J вторую версию, но не получилось. В итоге, благодаря статье в блоге одного индусского программиста (печально, да? :) ) я нашёл как запретить из Spring 4 использование SLF4J. Но это было решение для Gradle, а у меня maven.

В maven можно запретить использовать зависимости, которые могут подтягивать подключаемые зависимости (взрыв мозга). Но глобального exclusion нету. Зато есть отличный обходной путь. Нужно добавить необходимые зависимости с областью видимости provided. Что не будет копировать их в папку lib:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.7</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
    <scope>provided</scope>
</dependency>

Обратите внимание, что версии я брал для своей версии Spring — 4.1.1.RELEASE.

Пересобираем, чистим папки временных файлов и данных вашего веб-сервера, чтобы там не осталось лишнего и радуемся:

2015-01-20 15:57:16,223 DEBUG [RMI TCP Connection(3)-127.0.0.1] env.MutablePropertySources (MutablePropertySources.java:111) - Adding [servletConfigInitParams] PropertySource with lowest search precedence
2015-01-20 15:57:16,223 DEBUG [RMI TCP Connection(3)-127.0.0.1] env.MutablePropertySources (MutablePropertySources.java:111) - Adding [servletConfigInitParams] PropertySource with lowest search precedence
2015-01-20 15:57:16,224 DEBUG [RMI TCP Connection(3)-127.0.0.1] env.MutablePropertySources (MutablePropertySources.java:111) - Adding [servletContextInitParams] PropertySource with lowest search precedence

Читайте также:

1 комментарий

  1. 07 Мар 2016

    […] Вернёмся к нашим проблемам логирования при использовании новой версии библиотеки Log4j2. Ранее мы разобрались, как заставить использовать библиотеку Log4j2 в Spring 4. […]

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *