簡介
spring mvc的日誌系統可以配置很多版本,比如log4j、log4j2、logback等等,在參考資料中介紹了Spring mvc如何直接集成log4j2,我們這裏介紹的是,如何將原系統中的log4j改爲使用log4j2.
操作步驟
1. 刪除原Spring mvc中對log4j的依賴
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
2、添加log4j2的依賴,其中og4j2的版本我選擇的是, <log4j2.version>2.11.2</log4j2.version>,其中jul(java util logging)jcl (apache commons-logging)的依賴可以不用添加
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
</dependency>
3、 添加log4j到log4j2的橋接包
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
4、添加log4j2的配置文件 log4j2.xml, 內容根據自己喜好更改,下面這個只是作爲參考(直接在resources目錄底下添加)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<properties>
<property name="LOG_HOME">logs/</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36}
- %msg%n"/>
</Console>
<RollingRandomAccessFile name="infoLog" fileName="${LOG_HOME}/app.log"
filePattern="${LOG_HOME}/app.%d{yyyy-MM-dd}-%i.log.gz" append="true">
<PatternLayout pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread]
[%level][%class][%line]:%message%n"/>
<Filters>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
</Filters>
<Policies>
<!-- 對應 filePattern維度,此處爲天數-->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!--mybatis debug log-->
<AsyncLogger name="log4j.logger.org.mybatis" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<AsyncLogger name="log4j.logger.java.sql" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<AsyncLogger name="log4j.logger.java.sql.Connection" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<AsyncLogger name="log4j.logger.java.sql.Statement" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<AsyncLogger name="log4j.logger.java.sql.PreparedStatement" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<AsyncLogger name="log4j.logger.java.sql.ResultSet" level="debug" additivity="false">
<!--<appender-ref ref="Console"/>-->
<AppenderRef ref="infoLog"/>
</AsyncLogger>
<!--TRACE、DEBUG、INFO、WARN、ERROR和FATAL-->
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
5、最重要的,其他的都不需要更改,比如mybatis-config.xml保留原樣即可,不要將logImpl的value改爲LOG4J2,不然,如果mybatis的版本如果過低的話,會報一些錯誤,比如:
Cause: org.apache.ibatis.logging.LogException: Error setting Log implementation. Cause: java.lang.reflect.InvocationTargetException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4853)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.logging.LogException: Error setting Log implementation. Cause: java.lang.reflect.InvocationTargetException
at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:434)
at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:340)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 21 more
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.logging.LogException: Error setting Log implementation. Cause: java.lang.reflect.InvocationTargetException
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:109)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:92)
at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:428)
... 24 more
Caused by: org.apache.ibatis.logging.LogException: Error setting Log implementation. Cause: java.lang.reflect.InvocationTargetException
at org.apache.ibatis.logging.LogFactory.setImplementation(LogFactory.java:131)
at org.apache.ibatis.logging.LogFactory.useCustomLogging(LogFactory.java:83)
at org.apache.ibatis.session.Configuration.setLogImpl(Configuration.java:213)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.settingsElement(XMLConfigBuilder.java:218)
at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:103)
... 26 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.ibatis.logging.LogFactory.setImplementation(LogFactory.java:127)
... 30 more
Caused by: java.lang.NoClassDefFoundError: org/apache/logging/log4j/spi/AbstractLoggerWrapper
at org.apache.ibatis.logging.log4j2.Log4j2AbstractLoggerImpl.<init>(Log4j2AbstractLoggerImpl.java:39)
at org.apache.ibatis.logging.log4j2.Log4j2Impl.<init>(Log4j2Impl.java:34)
... 35 more
其他情況
1、如果spring mvc中,log4j使用的是slf4j+log4j的模式,那麼在執行上面第一步的時候,除了刪除log4j的依賴外,還需要刪除slf4j-log4j12的依賴
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
在添加log4j2的依賴過程中,增加log4j2到slf4j的依賴包
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
2、簡單介紹一下log4j2中依賴包的作用
log4j-api:log4j2定義的API
log4j-core:log4j2上述API的實現
log4j-1.2-api:將log4j日誌轉接到log4j2的轉接包
log4j-jcl:commons-logging到log4j2的橋樑
log4j-jul:java util logging 到log4j2的橋樑
log4j-web: 保證容器關閉或取消部署Web應用程序時,正確清理日誌資源(關閉數據庫連接,關閉文件等)
log4j-slf4j-impl:slf4j到log4j2的橋樑
參考資料
Spring MVC + Slf4j + Log4j2 日誌文件系統配置
slf4j與jul、log4j1、log4j2、logback的集成原理
關於slf4j log4j log4j2的jar包配合使用的那些事