log4j到log4j2升级迁移方案
序:这段时间因为维护的项目存在大量日志打印,严重拖慢整体响应时间,在做性能优化的工作中对这块内容进行了升级换代,由以前的log4j升级为log4j2,以实现日志异步打印。接下来记录一下这个费时半个月的迁移踩过的坑!
相关操作步骤:
1. 在项目中移除log4j的依赖,并添加log4j2的相关依赖.(选择log4j2的版本时请留意,2.10.x之后的版本是基于java9的!如果有使用到某些特性,请考虑当前项目的jdk版本!)
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.9.1</version>
</dependency>
我最开始使用的2.11.2版本,因为jdk原因退回到2.9.1(请注意如果你的项目是通过jenkins构建,请将api,core包的依赖直接添加进来!)
2.修改项目中所有的报错!(这些都是jar包替换造成的!注意log4j2在实现方面与log4j是有区别的,常用的3个为:自定义appender,自定义日志等级,获取logger的方式)
自定义appender方式:
@Plugin(
name = "CustomerAppender",
category = "Core",
elementType = "appender",
printObject = true
) public final class CustomerAppender extends AbstractOutputStreamAppender<CustomerRollingFileManager> { //TODO
//此部分为自定义内容 }
3.本文以maven依赖管理为例,查看dependencies树,确保项目中没有其他依赖的依赖引入log4j相关jar包
这个步骤自行解决~~举例如下:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
4.为步骤三中找到并移除的实现引入需要的桥接包!(此处注意大多数的项目中使用的 都是slf4j的框架,不同的版本使用Log4j2的实现需要的桥接包版本是不一样的!请仔细查看相关版本)
<!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>x.x.x</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>x.x.x</version>
</dependency>
请根据实际需要修改对应版本,建议在maven repository中查询版本对应关系
5.根据原有log4j.xml的配置文件改造log4j2.xml(原来通过java定义的日志等级可以迁移到此处)
<CustomLevels>
<CustomLevel name="BUSI" intLevel="350" />
</CustomLevels>
这里可以根据需要定义name,一级level,注意这个值与log4j定义的不太一样,具体请参考源码中的定义规则,我此处给的350在info等级以上
6.解决kafka日志推送问题.(log4j推送kafka一般是通过kafka-log4j-appender这个中间包去实现的,在lo4j2下需要更换推送方式,有内置的kafkaAppender,需要在依赖管理中根据需要推送的kafka服务端版本号添加对应的客户端版本号:kafka-clients)
<!--kafka日志推送-->
<Kafka name="kafkaAppender" topic="test" ignoreExceptions="true">
<PatternLayout pattern="${Console_Pattern}" />
<Property name="bootstrap.servers">x.x.x.x:端口号,x.x.x.x:端口号</Property>
<Property name="max.block.ms">2000</Property>
</Kafka>
此处还可以设置ignoreException=false;这个时候需要去对异常做处理,可以获取异常信息.
需要添加的kafka-clients依赖如下(请修改具体版本):
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>0.10.0.0</version>
</dependency>
7.解决容器问题!这个并非所有的容器都需要(至少tomcat不需要。。)目前我们服务器端使用的为jboss。在对日志升级后有可能出现对应业务日志打印到jboss的server日志中!这肯定是不允许的!解决办法:在项目的WEB-INF或者META-INF目录下添加:jboss-deployment-structure.xml文件,注意此处放置的位置和文件名都必须是这个!这是jboos规定的。此文件的作用是可以管理jboss的相关依赖,可以在此处排除它的log4j2的实包
<?xml version="1.0" encoding="UTF-8" ?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment> <exclude-subsystems>
<!-- 排除 javax.persistence.api 依赖 -->
<subsystem name="jpa" /> <!-- 排除 org.jboss.logging 依赖 -->
<subsystem name="logging" />
</exclude-subsystems> <exclusions>
<!-- 排除 org.apache.httpcomponents 依赖 -->
<module name="org.jboss.resteasy.resteasy-jaxrs" /> <!-- 排除 javax.persistence.api 依赖 -->
<module name="javaee.api" />
<module name="javax.persistence.api" />
<module name="org.hibernate" />
</exclusions> <dependencies> <!-- 排除 org.apache.httpcomponents 依赖 -->
<!-- <module name="org.apache.httpcomponents" export="true"/> --> <!-- 排除 org.jboss.logging 依赖 -->
<!-- <module name="org.jboss.logging" export="true" /> -- <!-- 排除掉jboss的 slf4j 和 log4j 实现,使用我们程序自己的包 -->
<!--<module name="org.apache.log4j" export="true" />-->
<!--<module name="org.slf4j" export="true" />-->
<module name="org.apache.commons.logging" export="true" />
<module name="org.jboss.logging.jul-to-slf4j-stub" export="true" /> </dependencies>
</deployment>
</jboss-deployment-structure>
请根据项目实际需要做相关排除
8.解决因为包装自定义的logger导致的日志记录中不能正常记录logger打印位置的问题。(这个问题对于直接使用原生logger的项目不会有)在log4j2的api包下我们会发现没有提供可以传递FQCN的接口!所以此处我们需要直接引入core下的具体实现。在实现类中有log.logIfEnabled()方法,此方法允许传入(FQCN,level,maker,message).
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger; public abstract class AbstractABFrameLogger { /** 线程栈查找方法深度 */
private final static int STACK_DEEP_SIZE = 2; /** log4j把传递进来的callerFQCN在堆栈中一一比较,相等后,再往上一层即认为是用户的调用类 */
final static String FQCN = AbstractABFrameLogger.class.getName(); protected Logger log; /**
*
* @param name name
*/
public AbstractABFrameLogger(String name) {
this.log = (Logger) LogManager.getLogger(name);
} /**
* 基本debug基本,封装打印信息
* @param objLogInfo Object
*/
public void debug(Object objLogInfo) {
log.logIfEnabled(FQCN,Level.DEBUG,null,objLogInfo);
} }
完成上述步骤后,整个log4j的升级工作也就差不多做完啦~恭喜
log4j到log4j2升级迁移方案的更多相关文章
- Slf4j与log4j及log4j2的关系及使用方法
Slf4j与log4j及log4j2的关系及使用方法 slf4j slf4j仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已,所以单独 ...
- Slf4j与log4j及log4j2、logbak的关系及使用方法
Slf4j与log4j及log4j2的关系及使用方法 slf4j slf4j仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已,所以单独 ...
- Ceph 集群整体迁移方案(转)
场景介绍:在我们的IDC中,存在着运行了3-6年的Ceph集群的服务器,这些服务器性能和容量等都已经无法满足当前业务的需求,在购入一批高性能机器后,希望将旧机器上的集群整体迁移到新机器上,当然,是保证 ...
- 蚂蚁金服 Service Mesh 渐进式迁移方案|Service Mesh Meetup 实录
小蚂蚁说: 本文是基于在 Service Mesher Meetup 上海站的主题分享<蚂蚁金服 Service Mesh 渐进式迁移方案>内容整理,完整的分享 PPT 获取方式见文章底部 ...
- Java logger组件:slf4j, jcl, jul, log4j, logback, log4j2
先说结论 建议优先使用logback 或 log4j2.log4j2 不建议和 slf4j 配合使用,因为格式转换会浪费性能. 名词:jcl 和 jul 标题中的 jcl 是 apache Jakar ...
- 转:Java logger组件:slf4j, jcl, jul, log4j, logback, log4j2
先说结论 建议优先使用logback 或 log4j2.log4j2 不建议和 slf4j 配合使用,因为格式转换会浪费性能. 名词:jcl 和 jul 标题中的 jcl 是 apache Jakar ...
- JCL、SLF4J、Log4J、Log4J2、LogBack和JUL之间的关系,你搞清楚了吗?
写在前面 日志组件是我们平时开发过程中必然会用到的组件.在系统中正确的打印日志至少有下面的这些好处: 调试:在程序的开发过程中,必然需要我们不断的调试以达到程序能正确执行的状态 .记录日志可以让开发人 ...
- 一文讲尽门面日志slf4j和log4j、log4j2、logback依赖jar引用关系
公众号Mac代码分割阅读链接 前言 之前都是使用SparkStreaming开发,最近打算学习一下Flink,就从官网下载了Flink 1.11,打算搞一个客户端,将程序提交在yarn上.因为Flin ...
- 不同场景下 MySQL 的迁移方案
一 目录 一 目录 二 为什么要迁移 三 MySQL 迁移方案概览 四 MySQL 迁移实战 4.1 场景一 一主一从结构迁移从库 4.2 场景二 一主一从结构迁移指定库 4.3 场景三 一主一从结构 ...
随机推荐
- 微信公众号开发C#系列-9、多公众号集中管理
1.概述 通过前面8篇关于微信开发相关文章的学习,我们已经对微信常用开发有了一个比较深入的了解.前面的文章都是基于某一特定公众号的,在现实业务中同一单位个体运营着不至一个公众号,此时就需要对多个公众号 ...
- Css-移动端适配总结
前言 工作以后,大部分的业务工作都是基于移动端H5的,开发过程中学习了很多东西,遇到过许多问题,诸如rem\em\css px\device px等,本文纯属个人的归纳总结,如有问题,请指出亲喷~ P ...
- 校园生活app结对开发第二天
昨天进行了android studio的安装与配置遇到很多问题,在gradel处遇到很多问题,安装版本错误等等,在百度和书籍的帮助下成功安装 今天要做登陆界面开发
- C# 连接/查询Jira
查询jira数据,如果是前端,可以按照如下格式直接访问,获取数据 http://jira.company.com/rest/api/2/search?jql=project = REM AND res ...
- ABAP案例:灵活读取SAP各表的数据
案例说明 RFC读取表中数据. Import 参数名称 Type spec. 参考打印 FIELDS_NAME1 TYPE CHAR25 TABLE_NAME1 TYPE CHAR25 WHE ...
- Asp.Net 将HTML中通过dom-to-image.js标签div内的内容转化为图片保存到本地
由于客户的需求,将js写出来的一个统计能够保存到本地.作为码奴的我只能慢慢搬砖咯!一开始使用的是html2canvas.js.功能是可以实现,但是有缺陷.话不多说开始搞! 1.引入几个JS库 ①:jq ...
- 重建程序员能力(3)-asp.net MVC框架增加Controller
MVC在微软中提供的框架目前只是发现是asp.net用.另 8年前,我做了个MVC的Windows APP框架如果有兴趣我日后会介绍给大家,欢迎大家关注.MVC的概念网站上有很多,大家去查阅一 ...
- 属于自己的MES(二)必备的主数据
MES在系统建设前,需要先进行一些必要的数据,这些主数据是支撑MES执行的关键. 1.BOM BOM通常称为“物料清单”,也就是产品结构,在化工.制药.食品.烟草领域也叫“配方”,它主要描述了物料的物 ...
- Orchard克死你 之 刚起步
从去年开始,一直想琢磨一个比较灵活的.Net框架用,经一个月的地毯式搜寻,把目标定位到2009年的微软开源项目Orchard,虽然起步甚晚,但对我们这些菜鸟,仍旧是有可学习之处,所以打算花大半年时间想 ...
- MVC 伪静态路由、MVC路由配置,实现伪静态。
前段时间,研究了一下mvc路由配置伪静态,在网上扒了很多最后还是行不通,所以我现在把这些心得整理出来,供大家分享: 1.mvc中默认路由配置是:http://localhost:24409/Home/ ...