最近把项目的日志框架从 log4j 迁移到 logback,过程里遇到很多坑,记录下来

目标

本次迁移的目标就是用 slf4j+logback 的日志框架来取代目前的 slf4j+log4j

如何迁移

基于 slf4j+log4j 的无痛迁移

如果项目本身是采用的 slf4j+log4j 日志架构,迁移到 logback 就比较简单

第一步:修改依赖

原本是 slf4j+log4,依赖如下

org.slf4j  slf4j-apiorg.slf4j  slf4j-log4j12log4j  log4j

迁移到 slf4j+logback,依赖如下

org.slf4j  slf4j-apich.qos.logback  logback-classic

第二步:修改日志配置

logback 的配置文件为 logback.xml,替换掉 log4j.xml,以下示例,配置了输出日志到控制台及异步输出到文件,日志文件按日期滚动;同时支持使用 mdc 打印会话唯一标识 sid

<?xml version="1.0" encoding="UTF-8"?>%date{HH:mm:ss.SSS} [%-5level] [%logger:%L] %mdc{sid:--} - %msg%nUTF-8DEBUG${log.path}/${app.name}.log${log.path}/${app.name}.log.%d{yyyy-MM-dd}%date{HH:mm:ss.SSS} [%-5level] [%logger] %mdc{sid:--} - %msg%nUTF-8DEBUG0

第三步:web 项目初始化日志

增加如下依赖

org.logback-extensions logback-ext-spring 0.1.5

在 web.xml 里增加如下监听器

logbackConfigLocationclasspath:config/logback.xmlch.qos.logback.ext.spring.web.LogbackConfigListener

直接从 log4j 迁移

项目里依赖了其他一些库,可以用 maven 命令 mvn dependency:tree 来查看下,都有哪些库还用到了 log4j,如果这些库也是 slf4j+log4j 的架构那就万事大吉,但也有的库直接用的 log4j,这样就有点小麻烦了

根据 slf4j 的文档(http://www.slf4j.org/legacy.html),使用 log4j 桥接器 log4j-over-slf4j 来替换 log4j 依赖:即在所有依赖到 log4j 的库上排除 log4j 的依赖,并添加 log4j-over-slf4j 依赖,如下

com.refusea.framework framework-service compile       log4j       log4jorg.slf4j log4j-over-slf4j

其他日志框架(jul/jcl/log4j2/...) 和 log4j 类似,slf4j 为其他日志框架提供了 xxx-over-slf4j 桥接器,比如 jcl-over-slf4j,如果用到了对应的日志框架,只需要在依赖里排除该日志框架依赖,并添加对应的桥接器即可


这里要特别提一下 jul(java.util.logging),由于这个日志框架内置在 jdk 内,无法通过置换依赖的方式来桥接,所以需要项目自己调用一下桥接器的方法,在项目初始化时执行如下代码即可

SLF4JBridgeHandler.removeHandlersForRootLogger();SLF4JBridgeHandler.install();

也许是因为这个原因,jul 的桥接器名字是 jul-to-slf4j 而不是 jul-over-sl4fj

小心死循环

使用 slf4j 桥接方式时,需要注意避免死循环,以桥接 log4j 为例说明


slf4j+log4j 要用到 slf4j-log4j12,这个库的作用是将 log4j 适配到 slf4j,其调用逻辑如下图

sl4fj+log4j

如果在桥接 log4j 时系统里还存在 slf4j-log4j12 库,就会导致如下的调用逻辑

slf4j+log4j+log4j桥接死循环

可以发现这样会导致死循环,解决的办法很简单:从所有依赖里排除 slf4j-log4j12 库

maven-enforcer-plugin

现在你排除了所有可能导致死循环的依赖,但是某天你引入了一个新的依赖,一时疏忽,没有排查这个新的依赖是否传递了 slf4j-logj12,那就存在死循环的风险;另一方面,就算你能保证自己每次都不会疏忽,但是你能保证项目里的其他开发人员也会在引入新依赖时进行检查吗?

这种情况,可以使用 maven 插件 maven-enforcer-plugin 来帮我们检查,把你想要排除的依赖配置一次即可

org.apache.maven.pluginsmaven-enforcer-plugin3.0.0-M2enforceenforce3.2.5maven version must be 3.2.5 or above1.7log4j:*org.apache.logging.log4j:*commons-logging:commons-loggingorg.slf4j:slf4j-log4j12org.slf4j:slf4j-jclorg.slf4j:slf4j-jdk14DO NOT use any other logger framework beyond slf4j+logback

jcl 的坑

jcl,即 The Apache Commons Logging,也是广泛应用的日志框架,在迁移的过程中,我们会排除该日志组件并用 jcl-over-slf4j 来取代它,并通过 maven-enforcer-plugin 来避免将可能导致死循环的依赖打包

问题是这一套看上去无懈可击的流程有漏洞:没有 jcl,maven-assembly-plugin 这个插件无法工作;而且这个插件会把 jcl 强行塞到最终输出的 zip 里,并不会触发 maven-enforcer-plugin 配置的排除规则

经过一番研究,发现把 jcl 的 scope 设为 provided 可以解决这个问题

commons-logging    commons-logging    1.2provided

开发log4j配置_从 log4j 迁移到 logback相关推荐

  1. log4j配置_是时候了解一下log4j2各种配置的含义了!

    来源:http://i7q.cn/54K3Uw 1.日志框架 日志接口(slf4j) slf4j是对所有日志框架制定的一种规范.标准.接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具 ...

  2. 开发log4j配置_Spring 使用 Log4J 记录日志

    在 Spring 应用程序中使用 Log4J 的功能是非常容易的.下面的例子将带你通过简单的步骤解释 Log4J 和 Spring 之间的简单集成. 假设你已经在你的机器上安装了 Log4J,如果你还 ...

  3. java maven log4j配置_如何在Maven构建的Java项目中使用log4j

    参考: 说明: 本文仅仅作为项目开发过程中的记录,不提供详细的说明.按照步骤直接复制粘贴即可成功使用. 第一步:添加依赖 log4j log4j 1.2.17 第二步:添加配置文件 文件位置说明:直接 ...

  4. python开发环境配置_百度资讯搜索_python开发环境配置

    金生水起程序猿 2020年11月14日 11:20下载完成后就可以安装Python了,在安装过程中会弹出内容选择对话框,选中复选框Add Python 3.x to PATH,可以将Python的安装 ...

  5. vim java开发环境配置_搭建vim作为java开发环境(-)

    说明:本文的内容作为自己搭建环境的记录,内容基本是从网上查找来的,所以原作者看了不要太介意.另外本人是Mac电脑,请参照者注意了. javacomplete:是在vim开发中提供提示效果的插件. 1. ...

  6. java开发电脑配置_新电脑java开发环境配置(自用)

    一.jdk下载 注:java8是长期支持版本,并且比较稳定.java13只有半年维护期,而且新发布的版本可能不稳定,不建议在正式项目中使用 2.下载时会提示需要登陆账号,注册一个即可(我的是qq邮箱, ...

  7. log4j配置目标到mongodb

    首先,具体采用什么技术作为集中式存储方案在99%的应用中应该来说并没有多大区别,最重要的是要定期清理不必要的日志,以及日志格式设计(也可以重写org.log4mongo.MongoDbPatternL ...

  8. stone 的 log4j配置详解

    stone 的 log4j配置详解 Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过 ...

  9. log4j配置以及logback配置

    logback配置: logback.xml <?xml version="1.0" encoding="UTF-8"?><configura ...

最新文章

  1. UI布局分析工具-视图工具(Hierarchy Viewer)
  2. 网络营销专员浅析企业网站网络营销的多个优势!
  3. python网络安全宣传周_Python
  4. [转]matlab 函数三种定义方式
  5. c语言中tgx是什么函数,《高等数学》课后练习题
  6. python的开发环境有哪些系统_Win10下配置机器学习python开发环境
  7. PowerShell使用教程
  8. 阿里最喜欢问的多线程顺序打印的5种解法!
  9. 5-2计算机视觉的常见概念
  10. Android上传图片的两种方式
  11. 清零软件解决连供打印机喷嘴断墨和堵塞
  12. python控制小爱同学_GitHub - xinruoyusixian/Blinker-for-xiaoai: 基于micopython 的小爱同学的代码...
  13. c语言表示星期的英语单词周一到周日,sql 获取本周周一和周日
  14. 网页打印怎样去掉网址
  15. ESP8266本质是一个带wifi功能的单片机
  16. 手机电视的概念及其发展状况
  17. 数电学习(十一、D/A和A/D转换)
  18. 矢量在全球规则格网地形上的叠加绘制方法
  19. unity PUN PhotonView莫名奇妙viewID冲突
  20. java中bean是什么_java中bean是什么意思?有什么作用 | 学步园

热门文章

  1. SAP中采购订单状态与MRP的关系
  2. sap可配置BOM的主要流程
  3. 什么是SAP重复性生产
  4. 函数模块:CTVB_COMPARE_TABLES
  5. POPUP_TO_CONFIRM_WITH_MESSAGE
  6. 长沙经济复苏战打的如何?我们从高桥红星两个市场里找到了答案
  7. 导购电商成虎头蛇尾,真的不只是因为拼多多
  8. 42岁的波司登, 强势回归是为何?
  9. 不懂规矩站错位置,“代币”谄媚“区块链”逼于无奈
  10. python对字符串和集合的内存垃圾回收机制