@[toc]
前言
升级前提介绍:在线客服关于升级Log4j2记录日志的总结
本次升级样例项目:
- ddky-backManage-all
- ddky-report-web
参考:
http://logging.apache.org/log4j/2.x/manual/webapp.html#Servlet-2.5
升级web
修改pom
删除旧依赖
- 此处需要删除各包下引用的低版本log4j,使用excludes去除
- 可以使用mvn dependency:tree查看冲突和低版本log4j引用情况
- idea可以直接使用Digrams -> show dependencies
<!-- Log4j 删除旧版本 -->
<!--<dependency>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-api</artifactId>-->
<!--<version>${slf4j.version}</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.slf4j</groupId>-->
<!--<artifactId>slf4j-log4j12</artifactId>-->
<!--<version>${slf4j.version}</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>log4j</groupId>-->
<!--<artifactId>log4j</artifactId>-->
<!--<version>${log4j.version}</version>-->
<!--</dependency>-->
<!-- 排除log4j和logback依赖包 -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<exclusions>
<!-- 排除log4j1的方式 -->
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<!-- 排除logback的方式 -->
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 去除disconfig log4j1 -->
<dependency>
<groupId>com.baidu.disconf</groupId>
<artifactId>disconf-client</artifactId>
<version>2.6.35-ddky</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
<exclusions>
<!-- 排除log4j1的方式 -->
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<!-- 排除logback的方式 -->
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
...等等等
引入log4j2依赖:
版本统一使用:
- log4j-2.11.2
- disruptor-3.4.2
<!-- ***********Log4j2升级开始********** -->
<!-- log4j2依赖包 异步日志 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
<!-- slf4j门面包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- log4j2核心包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
<!-- log4j2门面包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<!-- 该包是 log4j 升级到 log4j2的必须包 使用该包 不需要修改以前的 Logger.getLogger()这种获取对象的方式 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.11.2</version>
</dependency>
<!-- 该包是slf4j 升级到 log4j2的必须包 使用该包 其他依赖jar中依赖slf4j 不会报错 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.2</version>
</dependency>
<!-- web项目需要引用此包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.11.2</version>
</dependency>
<!-- 桥接:告诉commons logging使用Log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.11.2</version>
<scope>runtime</scope>
</dependency>
<!-- ***********Log4j2升级结束********** -->
配置web.xml
升级web-app到2.5版本(推荐,由于公司项目servlet都采用2.5版本)
原先:
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
改为:
<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_2_5.xsd"
version="2.5">
修改原先的配置
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
添加新配置:
<!--日志升级开始-->
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
<!-- <dispatcher>ASYNC</dispatcher> -->
</filter-mapping>
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/classes/log4j2.xml</param-value>
<!--<param-value>classpath:log4j2.xml</param-value>-->
</context-param>
<!--<context-param>-->
<!--<param-name>log4jRefreshInterval</param-name>-->
<!--<param-value>1000</param-value>-->
<!--</context-param>-->
<!--日志升级结束-->
升级web-app到3.0版本(不推荐,升级改动范围大)
原先:
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
改为:
<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>/WEB-INF/classes/log4j2.xml</param-value>
<!--<param-value>classpath:log4j2.xml</param-value>-->
</context-param>
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
<!--日志升级结束-->
升级pom依赖servlet-api版本到3.0
创建resources/log4j2.xml
并备份和删除原先的log4j.properties
创建log4j2.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="30" strict="true">
<Properties>
<!-- 日志输出级别 -->
<Property name="LOG_DEBUG_LEVEL" value="debug"/>
<Property name="LOG_INFO_LEVEL" value="info"/>
<Property name="LOG_WARN_LEVEL" value="warn"/>
<!-- error级别日志 -->
<Property name="LOG_ERROR_LEVEL" value="error"/>
<!-- 在当前目录下创建名为log目录做日志存放的目录 -->
<!--<Property name="LOG_HOME" value="./log"/>-->
<Property name="LOG_HOME" value="E:\dd\codes\o2o\20160219\web\ddky_report_web\log"/>
<!-- 档案日志存放目录 -->
<Property name="LOG_ARCHIVE" value="${LOG_HOME}/archive"/>
<!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 -->
<Property name="LOG_MODULE_NAME" value="ddky-report-web"/>
<!-- 日志文件大小,超过这个大小将被压缩 -->
<Property name="LOG_MAX_SIZE" value="100 MB"/>
<!-- 保留多少天以内的日志 -->
<Property name="LOG_DAYS" value="30"/>
<!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 -->
<Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/>
<!--interval属性用来指定多久滚动一次-->
<Property name="TIME_BASED_INTERVAL" value="1"/>
</Properties>
<Appenders>
<!-- 控制台输出 -->
<Console name="STDOUT" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}"/>
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Console>
<!--只记录debug级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileDebug"
fileName="${LOG_HOME}/debug.log"
filePattern="${LOG_ARCHIVE}/debug-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<Filters>
<ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档-->
<!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false-->
<RollingRandomAccessFile name="RollingRandomAccessFileInfo"
fileName="${LOG_HOME}/info.log"
filePattern="${LOG_ARCHIVE}/info-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="false">
<Filters>
<!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器-->
<ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/>
<!--如果是info\warn输出-->
<ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次-->
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件-->
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!--只记录error级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileError"
fileName="${LOG_HOME}/error.log"
filePattern="${LOG_ARCHIVE}/error-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="false">
<Filters>
<ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!--只记录warn级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileWarn"
fileName="${LOG_HOME}/warn.log"
filePattern="${LOG_ARCHIVE}/warn-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="false">
<Filters>
<ThresholdFilter level="${LOG_WARN_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!-- 本机环境使用 -->
<!--<Root level="${LOG_DEBUG_LEVEL}">-->
<!--<AppenderRef ref="STDOUT"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileDebug"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileWarn"/>-->
<!--</Root>-->
<!-- 开发环境使用 -->
<Root level="${LOG_INFO_LEVEL}">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="RollingRandomAccessFileInfo"/>
<AppenderRef ref="RollingRandomAccessFileError"/>
<AppenderRef ref="RollingRandomAccessFileWarn"/>
</Root>
<!-- 生产预发布环境使用 -->
<!--<Root level="${LOG_INFO_LEVEL}" includeLocation="false">-->
<!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
<!--</Root>-->
<!-- 第三方日志系统 -->
<logger name="org.springframework.core" level="info" />
<logger name="org.springframework.beans" level="info" />
<logger name="org.springframework.context" level="info" />
<logger name="org.springframework.web" level="info" />
<logger name="org.jboss.netty" level="warn" />
<logger name="org.apache.http" level="warn" />
</Loggers>
</Configuration>
修改log4j2.xml中属性
- immediateFlush:如果使用异步日志,请设置为false,同步日志,请设置为true
- LOG_MODULE_NAME:模块名称,建议按照项目模块命名
配置log4j2.component.properties
# 设置异步日志系统属性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep
#AsyncLoggerConfig.RingBufferSize=10240
Service服务
打印druid sql—修改applicationContext.xml
添加如下配置:
<!-- druid 打印sql日志 -->
<bean id="log-filter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">
<property name="connectionLogEnabled" value="false"/>
<property name="statementLogEnabled" value="false"/>
<property name="resultSetLogEnabled" value="true"/>
<property name="statementExecutableSqlLogEnable" value="true"/>
</bean>
引入log-filter
log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="30" strict="true">
<Properties>
<!-- 日志输出级别 -->
<Property name="LOG_DEBUG_LEVEL" value="debug"/>
<Property name="LOG_INFO_LEVEL" value="info"/>
<Property name="LOG_WARN_LEVEL" value="warn"/>
<!-- error级别日志 -->
<Property name="LOG_ERROR_LEVEL" value="error"/>
<!-- 在当前目录下创建名为log目录做日志存放的目录 -->
<Property name="LOG_HOME" value="./log"/>
<!--<Property name="LOG_HOME" value="E:\dd\codes\log"/>-->
<!--<Property name="LOG_HOME" value="E:\dd\codes\o2o\20160219\web\ddky_report_web\log"/>-->
<!-- 档案日志存放目录 -->
<Property name="LOG_ARCHIVE" value="${LOG_HOME}/archive"/>
<!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 -->
<Property name="LOG_MODULE_NAME" value="ddky-backManage-all"/>
<!-- 日志文件大小,超过这个大小将被压缩 -->
<Property name="LOG_MAX_SIZE" value="100 MB"/>
<!-- 保留多少天以内的日志 -->
<Property name="LOG_DAYS" value="30"/>
<!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 -->
<Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/>
<!--interval属性用来指定多久滚动一次-->
<Property name="TIME_BASED_INTERVAL" value="1"/>
</Properties>
<Appenders>
<!-- 控制台输出 -->
<Console name="STDOUT" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}"/>
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Console>
<!--只记录debug级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileDebug"
fileName="${LOG_HOME}/debug.log"
filePattern="${LOG_ARCHIVE}/debug-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<Filters>
<ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档-->
<!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false-->
<RollingRandomAccessFile name="RollingRandomAccessFileInfo"
fileName="${LOG_HOME}/info.log"
filePattern="${LOG_ARCHIVE}/info-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<Filters>
<!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器-->
<ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/>
<!--如果是info\warn输出-->
<ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次-->
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件-->
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!--只记录error级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileError"
fileName="${LOG_HOME}/error.log"
filePattern="${LOG_ARCHIVE}/error-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<Filters>
<ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!--只记录warn级别以上的日志,与info级别的日志分不同的文件保存-->
<RollingRandomAccessFile name="RollingRandomAccessFileWarn"
fileName="${LOG_HOME}/warn.log"
filePattern="${LOG_ARCHIVE}/warn-%d{yyyy-MM-dd}-%i.log.gz"
immediateFlush="true">
<Filters>
<ThresholdFilter level="${LOG_WARN_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
<!--druid的日志记录追加器-->
<RollingRandomAccessFile name="druidSqlRollingFile" fileName="${LOG_HOME}/druid-sql.log"
filePattern="${LOG_ARCHIVE}/druid-sql-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
<SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${LOG_DAYS}"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!-- 本机环境使用 -->
<!--<Root level="${LOG_DEBUG_LEVEL}" includeLocation="true" additivity="true">-->
<!--<AppenderRef ref="STDOUT"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileDebug"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileWarn"/>-->
<!--</Root>-->
<!-- 开发环境使用 -->
<Root level="${LOG_INFO_LEVEL}" includeLocation="true" additivity="true">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="RollingRandomAccessFileInfo"/>
<AppenderRef ref="RollingRandomAccessFileError"/>
<AppenderRef ref="RollingRandomAccessFileWarn"/>
</Root>
<!--记录druid-sql的记录-->
<logger name="druid.sql.Statement" level="debug" additivity="false">
<appender-ref ref="druidSqlRollingFile"/>
</logger>
<!-- 生产预发布环境使用 -->
<!--<Root level="${LOG_INFO_LEVEL}" includeLocation="false" additivity="false">-->
<!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
<!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
<!--</Root>-->
<!-- 第三方日志系统 -->
<logger name="org.springframework.core" level="info" />
<logger name="org.springframework.beans" level="info" />
<logger name="org.springframework.context" level="info" />
<logger name="org.springframework.web" level="info" />
<logger name="org.jboss.netty" level="warn" />
<logger name="org.apache.http" level="warn" />
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
<Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
<logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
<Logger name="org.crsh.plugin" level="warn" />
<logger name="org.crsh.ssh" level="warn"/>
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
<Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
<logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
<logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<logger name="org.thymeleaf" level="warn"/>
</Loggers>
</Configuration>
配置log4j2.component.properties
# 设置异步日志系统属性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep
#AsyncLoggerConfig.RingBufferSize=10240
开关异步日志
通过修改log4j2.component.properties
属性
当需要开启异步日志时:
# 设置异步日志系统属性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep
当需要关闭异步日志,开启同步日志时:(直接注释配置即可)
# 设置异步日志系统属性
#log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
#AsyncLoggerConfig.WaitStrategy=Sleep
如何使用
@Slf4j 或 @Log4j2注解 和 手动创建Logger
- 通过引入lombok包, 直接在类上引用@Slf4j 或 @Log4j2注解
- 通过手动创建Logger类(slf4j或者log4j2)
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
测试示例:
package com.ddky;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CountDownLatch;
/**
* @program: 20160219
* @description:
* @author: zhouzhixiang
* @date: 2020-01-06
* @company: 叮当快药科技集团有限公司
**/
//@Slf4j
@Log4j2
public class Log4j2Test {
// 使用slf4j
private static final Logger log = LoggerFactory.getLogger(Log4j2Test.class);
private int totalThread = 50;
// 使用log4j2
// private static final Logger log = LogManager.getLogger(Log4j2Test.class);
@Test
public void testLog() {
log.info("Test*******************************************");
log.error("Test*******************************************");
log.warn("Test*******************************************");
log.debug("Test*******************************************");
}
// @Test
public void fixedPringting() throws InterruptedException {
log.info("log4j2 100万 start printing");
final CountDownLatch cdl = new CountDownLatch(totalThread);
long startTime = System.currentTimeMillis();
for (int i = 0; i < totalThread; i++) {
new Thread(() -> {
for (int j = 0; j < 200000; j++) {
log.info("log4j2 performance test " +j);
}
}).start();
cdl.countDown();
}
cdl.await();
long endTime = System.currentTimeMillis();
log.info("log4j2 100万 end cost time "+ (endTime - startTime));
}
public static void main(String[] args) throws InterruptedException {
log.info("log4j2 1000万 start printing");
Integer totalThread = 50;
final CountDownLatch cdl = new CountDownLatch(totalThread);
long startTime = System.currentTimeMillis();
for (int i = 0; i < totalThread; i++) {
new Thread(() -> {
for (int j = 0; j < 2000; j++) {
log.info("log4j2 performance test "+ j);
}
cdl.countDown();
}).start();
}
cdl.await();
long endTime = System.currentTimeMillis();
log.error("log4j2 1000万 end cost time = "+ (endTime - startTime));
}
@Test
public void isAsyncLog() {
log.info("是否为异步日志1:"+ AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志2:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志3:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志4:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志5:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志6:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志7:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志8:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志9:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志10:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志11:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志11:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志11:"+AsyncLoggerContextSelector.isSelected());
log.info("是否为异步日志11:"+AsyncLoggerContextSelector.isSelected());
}
@Test
public void testFori() {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
isAsyncLog();
}).start();
log.info(String.valueOf(i));
// log.error(String.valueOf(i));
// log.debug(String.valueOf(i));
// log.warn(String.valueOf(i));
}
}
}
注意事项
- 对于需要审计操作的日志,请开启同步日志,不建议开启异步日志。
- 引入jar依赖注意版本统一管理(以上引入未作版本管理,仅作参考)