java 日志桥接

log4j -> log4j2 桥接

去掉 log4j 1.x jar,添加log4j-1.2-api.jar,配合 log4j-api-2.x.x.jar 和 log4j-core-2.x.x.jar 即可,依赖如下

log4j-1.2-api.jar log4j-api-2.x.x.jar log4j-core-2.x.x.jar

log4j2 -> log4j 桥接

不建议。

本来log4j在2015年停止更新后,就建议转向log4j2,并提供了到log4j2的桥接接口。

所以反过来log4j2到log4j是不建议这么做的,log4j2也没有提供直接支持。

但理清了上面的jar包作用,就会发现,可以通过 log4j2 -> slf4j -> log4j 的方式来实现。

需要的jar包,根据依赖关系分别是:

log4j-api-2.x.x.jar log4j-to-slf4j.jar slf4j-api-x.x.x.jar slf4j-log4j12-x.x.x.jar l log4j-1.2.17.jar

slf4j

同时有日志输出和转接功能。

核心jar包是 slf4j-api-x.x.x.jar

因为一般slf4j 只作为桥接用,如果要搭配 slf4j 自带的简单日志输出,那么就加上 slf4j-simple.jar

log4j -> slf4j

将代码中的log4j日志桥接到 slf4j,需要如下jar包

log4j-over-slf4j-x.x.x.jar slf4j-api-x.x.x.jar

log4j2 -> slf4j

将代码中的log4j2日志桥接到 slf4j,需要如下jar包

log4j-api-2.x.x.jar log4j-to-slf4j-2.x.x.jar slf4j-api-x.x.x.jar

slf4j -> log4j

将slf4j日志,采用log4j实现进行输出,需要如下jar包

slf4j-api-x.x.x.jar slf4j-log4j12.jar log4j-1.2.17.jar

slf4j -> log4j2

将slf4j日志,采用log4j2实现进行输出,需要如下jar包

slf4j-api-x.x.x.jar log4j-slf4j-impl.jar log4j-api.jar log4j-core.jar

slf4j的代理绑定和输出组合起来,就实现了从一种日志框架,转到另一种日志实现框架的效果。

建议在这三种日志混用的情况下,采用如下方案

log4j -> log4j2 slf4j -> log4j2

日志系统桥接器

日志系统桥接器说白了就是一种偷天换日的解决方案。

比如log4j-over-slf4j,即log4j -> slf4j的桥接器,这个库定义了与log4j一致的接口(包名、类名、方法签名均一致),但是接口的实现却是对slf4j日志接口的包装,即间接调用了slf4j日志接口,实现了对日志的转发。

但是,jul-to-slf4j是个意外例外,毕竟JDK自带的logging包排除不掉啊,其实是利用jdk-logging的Handler机制,在root logger上install一个handler,将所有日志劫持到slf4j上。要使得jul-to-slf4j生效,需要执行

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

spring boot中的日志初始化模块已经包括了该逻辑,故无需手动调用。在使用其他框架时,建议在入口类处的static{ }区执行,确保尽早初始化。

日志桥接器使用

log4j -> slf4j,slf4j -> log4j两个桥接器同时存在会出现什么情况?

互相委托,无限循环,堆栈溢出。

slf4j -> logback,slf4j -> log4j两个桥接器同时存在会如何?

两个桥接器都会被slf4j发现,在slf4j中定义了优先顺序,优先使用logback,仅会报警,发现多个日志框架绑定实现;但有一些框架中封装了自己的日志facade,如果其对绑定日志实现定义的优先级顺序与slf4j不一致,优先使用log4j,那整个程序中就有两套日志系统在工作。

为达到统一使用slf4j & logback的目的,必须要做4件事:

  1. 引入slf4j & logback日志包和slf4j -> logback桥接器;
  2. 排除common-logging、log4j、log4j2日志包;
  3. 引入jdk-logging -> slf4j、common-logging -> slf4j、log4j -> slf4j、log4j2 -> slf4j桥接器;
  4. 排除slf4j -> jdk-logging、slf4j -> common-logging、slf4j -> log4j、slf4j -> log4j2桥接器

*ps*:log4j2桥接器由log4j2提供,其他桥接器由slf4j提供。

如果再严谨一点,还要排除掉slf4j-simple、slf4j-nop两个框架,不过这两个一般没人用。

maven首先遵循路径最短优先原则,即直接引入最优先,传递依赖层级越浅,越优先。若依然无法仲裁,则遵循优先声明原则,在pom中声明靠前的优先

如何进行日志系统转换?

在实际的日志转换过程中,SLF4J其实是充当了一个中介的角色。例如当我们一个项目原来是使用LOG4J进行日志记录,但是我们要换成LogBack进行日志记录。

此时我们需要先将LOG4J转换成SLF4J日志系统,再从SLF4J日志系统转成LogBack日志系统。

从日志框架转向SLF4J
  • jul-to-slf4j:jdk-logging到slf4j的桥梁
  • log4j-over-slf4j:log4j1到slf4j的桥梁
  • jcl-over-slf4j:commons-logging到slf4j的桥梁
从SLF4J转向具体的日志框架
  • slf4j-jdk14:slf4j到jdk-logging的桥梁
  • slf4j-log4j12:slf4j到log4j1的桥梁
  • log4j-slf4j-impl:slf4j到log4j2的桥梁
  • logback-classic:slf4j到logback的桥梁
  • slf4j-jcl:slf4j到commons-logging的桥梁

不能同时使用

  1. jcl-over-slf4j 和 slf4j-jcl
  2. log4j-over-slf4j 和 slf4j-log4j12
  3. jul-to-slf4j 和 slf4j-jdk14

例如我们一开始使用的是 Log4J 日志框架,现在我们希望转成 LogBack 框架,那么我们首先需要加入 log4j-over-slf4j.jar 将 Log4J 转成 SLF4J,之后再加入 logback-classic.jar 将 SLF4J 转成 LogBack。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值