@[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
org.apache.zookeeper
zookeeper
3.4.6
log4j
log4j
org.slf4j
slf4j-log4j12
com.baidu.disconf
disconf-client
2.6.35-ddky
commons-io
commons-io
log4j
log4j
com.github.sgroschupf
zkclient
0.1
log4j
log4j
org.slf4j
slf4j-log4j12
...等等等
引入log4j2依赖:
版本统一使用:
- log4j-2.11.2
- disruptor-3.4.2
com.lmax
disruptor
3.4.2
org.slf4j
slf4j-api
1.7.25
org.apache.logging.log4j
log4j-core
2.11.2
org.apache.logging.log4j
log4j-api
2.11.2
org.apache.logging.log4j
log4j-1.2-api
2.11.2
org.apache.logging.log4j
log4j-slf4j-impl
2.11.2
org.apache.logging.log4j
log4j-web
2.11.2
org.apache.logging.log4j
log4j-jcl
2.11.2
runtime
配置web.xml
升级web-app到2.5版本(推荐,由于公司项目servlet都采用2.5版本)
原先:
改为:
修改原先的配置
org.springframework.web.util.Log4jConfigListener
log4jConfigLocation
classpath:log4j.properties
添加新配置:
org.apache.logging.log4j.web.Log4jServletContextListener
log4jServletFilter
org.apache.logging.log4j.web.Log4jServletFilter
log4jServletFilter
/*
REQUEST
FORWARD
INCLUDE
ERROR
log4jConfiguration
/WEB-INF/classes/log4j2.xml
升级web-app到3.0版本(不推荐,升级改动范围大)
原先:
改为:
添加新配置:
log4jConfiguration
/WEB-INF/classes/log4j2.xml
isLog4jAutoInitializationDisabled
true
升级pom依赖servlet-api版本到3.0
创建resources/log4j2.xml
并备份和删除原先的log4j.properties
创建log4j2.xml文件
修改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
添加如下配置:
引入log-filter
log4j2.xml配置
配置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)
org.projectlombok
lombok
${lombok.version}
测试示例:
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依赖注意版本统一管理(以上引入未作版本管理,仅作参考)