spring mvc log日誌由log4j橋接至log4j2

簡介

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 日誌文件系統配置

What's New in Maven

slf4j與jul、log4j1、log4j2、logback的集成原理

關於slf4j log4j log4j2的jar包配合使用的那些事

Java日誌框架:slf4j作用及其實現原理

 

發佈了48 篇原創文章 · 獲贊 55 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章