slf4j jcl jul log4j1 log4j2 logback各组件系统日志切换

目录
  • 各种jar包总结
    • slf4j转向某个实际的日志框架:
    • 某个实际的日志框架转向slf4j:
  • 集成总结
    • commons-logging与其他日志框架集成
    • slf4j与其他日志框架集成
  • 日志系统之间的切换
    • log4j无缝切换到logback
      • 1 案例
      • 2 切换原理
    • jdk-logging无缝切换到logback
      • 1 案例
      • 切换原理
    • commons-logging切换到logback
      • 使用案例
      • 切换原理
    • 常用的日志场景切换解释
      • 1 左上图
      • 2 右上图
      • 3 左下图
  • 冲突说明
    • jcl-over-slf4j 与 slf4j-jcl 冲突
    • log4j-over-slf4j 与 slf4j-log4j12 冲突
    • jul-to-slf4j 与 slf4j-jdk14 冲突
  • 结束语

系列文章已完成,目录如下:

jdk-logging log4j logback日志系统实现机制原理介绍

commons-logging与jdk-logging、log4j1、log4j2、logback的集成原理

slf4j与jul、log4j1、log4j2、logback的集成原理

各种jar包总结

log4j1:

log4j:log4j1的全部内容

log4j2:

log4j-api:log4j2定义的API

log4j-core:log4j2上述API的实现

logback:

logback-core:logback的核心包

logback-classic:logback实现了slf4j的API

commons-logging:

commons-logging:commons-logging的原生全部内容

log4j-jcl:commons-logging到log4j2的桥梁

jcl-over-slf4j:commons-logging到slf4j的桥梁

slf4j转向某个实际的日志框架:

场景介绍:如 使用slf4j的API进行编程,底层想使用log4j1来进行实际的日志输出,这就是slf4j-log4j12干的事。

slf4j-jdk14:slf4j到jdk-logging的桥梁

slf4j-log4j12:slf4j到log4j1的桥梁

log4j-slf4j-impl:slf4j到log4j2的桥梁

logback-classic:slf4j到logback的桥梁

slf4j-jcl:slf4j到commons-logging的桥梁

某个实际的日志框架转向slf4j:

场景介绍:如 使用log4j1的API进行编程,但是想最终通过logback来进行输出,所以就需要先将log4j1的日志输出转交给slf4j来输出,slf4j再交给logback来输出。将log4j1的输出转给slf4j,这就是log4j-over-slf4j做的事

这一部分主要用来进行实际的日志框架之间的切换(下文会详细讲解)

jul-to-slf4j:jdk-logging到slf4j的桥梁

log4j-over-slf4j:log4j1到slf4j的桥梁

jcl-over-slf4j:commons-logging到slf4j的桥梁

集成总结

commons-logging与其他日志框架集成

1 commons-logging与jdk-logging集成:

需要的jar包:

commons-logging

2 commons-logging与log4j1集成:

需要的jar包:

commons-logging

log4j

3 commons-logging与log4j2集成:

需要的jar包:

commons-logging

log4j-api

log4j-core

log4j-jcl(集成包)

4 commons-logging与logback集成:

需要的jar包:

logback-core

logback-classic

slf4j-api、jcl-over-slf4j(2个集成包,可以不再需要commons-logging)

5 commons-logging与slf4j集成:

需要的jar包:

jcl-over-slf4j(集成包,不再需要commons-logging)

slf4j-api

slf4j与其他日志框架集成

slf4j与jdk-logging集成:

需要的jar包:

slf4j-api

slf4j-jdk14(集成包)

slf4j与log4j1集成:

需要的jar包:

slf4j-api

log4j

slf4j-log4j12(集成包)

slf4j与log4j2集成:

需要的jar包:

slf4j-api

log4j-api

log4j-core

log4j-slf4j-impl(集成包)

slf4j与logback集成:

需要的jar包:

slf4j-api

logback-core

logback-classic(集成包)

slf4j与commons-logging集成:

需要的jar包:

slf4j-api

commons-logging

slf4j-jcl(集成包)

日志系统之间的切换

log4j无缝切换到logback

1 案例

我们已经在代码中使用了log4j1的API来进行日志的输出,现在想不更改已有代码的前提下,使之通过logback来进行实际的日志输出。

已使用的jar包:

log4j

使用案例:

private static final Logger logger=Logger.getLogger(Log4jTest.class);
public static void main(String[] args){
	if(logger.isInfoEnabled()){
		logger.info("log4j info message");
	}
}

上述的Logger是log4j1自己的org.apache.log4j.Logger,在上述代码中,我们在使用log4j1的API进行编程

现在如何能让上述的日志输出通过logback来进行输出呢?

只需要更换一下jar包就可以:

第一步:去掉log4j jar包

第二步:加入以下jar包

log4j-over-slf4j(实现log4j1切换到slf4j)

slf4j-api

logback-core

logback-classic

第三步:在类路径下加入logback的配置文件

原理是什么呢?

2 切换原理

看下log4j-over-slf4j就一目了然了:

我们可以看到,这里面其实是简化更改版的log4j。去掉log4j1的原生jar包,换成该简化更改版的jar包(可以实现无缝迁移)。

但是简化更改版中的Logger和原生版中的实现就不同了,简化版中的Logger实现如下(继承了Category):

public class Category {
    private String name;
    protected org.slf4j.Logger slf4jLogger;
    private org.slf4j.spi.LocationAwareLogger locationAwareLogger;
    Category(String name) {
        this.name = name;
        slf4jLogger = LoggerFactory.getLogger(name);
        if (slf4jLogger instanceof LocationAwareLogger) {
            locationAwareLogger = (LocationAwareLogger) slf4jLogger;
        }
    }
}

从上面可以看到简化版中的Logger内部是使用slf4j的API来生成的,所以我们使用的简化版的Logger会委托给slf4j来进行输出,由于当前类路径下有logback-classic,所以slf4j会选择logback进行输出。从而实现了log4j到logback的日志切换。

下面的内容就只讲解日志系统到slf4j的切换,不再讲解slf4j选择何种日志来输出

jdk-logging无缝切换到logback

1 案例

private static final Logger logger=Logger.getLogger(JulSlf4jLog4jTest.class.getName());
public static void main(String[] args){
	logger.log(Level.INFO,"jul info a msg");
	logger.log(Level.WARNING,"jul waring a msg");
}

可以看到上述是使用jdk-logging自带的API来进行编程的,现在我们想这些日志交给logback来输出

解决办法如下:

第一步:加入以下jar包:

jul-to-slf4j (实现jdk-logging切换到slf4j)

slf4j-api

logback-core

logback-classic

第二步:在类路径下加入logback的配置文件

第三步:在代码中加入如下代码:

static{
	SLF4JBridgeHandler.install();
}

切换原理

先来看下jul-to-slf4j jar包中的内容:

我们看到只有一个类:SLF4JBridgeHandler

它继承了jdk-logging中定义的java.util.logging.Handler,Handler是jdk-logging处理日志过程中的一个处理器(具体我也没仔细研究过),在使用之前,必须要提前注册这个处理器,即上述的SLF4JBridgeHandler.install()操作,install后我们就可以通过这个handler实现日志的切换工作,如下:

protected Logger getSLF4JLogger(LogRecord record) {
    String name = record.getLoggerName();
    if (name == null) {
        name = UNKNOWN_LOGGER_NAME;
    }
    return LoggerFactory.getLogger(name);
}

在处理日志的过程中,使用了slf4j的原生方式LoggerFactory来获取一个slf4j定义的Logger来进行日志的输出

而slf4j则又会选择logback来进行实际的日志输出

commons-logging切换到logback

使用案例

使用的jar包

commons-logging

案例如下:

private static Log logger=LogFactory.getLog(JulJclTest.class);
public static void main(String[] args){
	if(logger.isTraceEnabled()){
		logger.trace("commons-logging-jcl trace message");
	}
}

可以看到我们使用commons-logging的API来进行日志的编程操作,现在想切换成logback来进行日志的输出(这其实就是commons-logging与logback的集成)

解决办法如下:

第一步:去掉commons-logging jar包(其实去不去都无所谓)

第二步:加入以下jar包:

jcl-over-slf4j(实现commons-logging切换到slf4j)

slf4j-api

logback-core

logback-classic

第三步:在类路径下加入logback的配置文件

切换原理

这个原理之前都已经说过了,可以看下commons-logging与logback的集成

就是commons-logging通过jcl-over-slf4j 来选择slf4j作为底层的日志输出对象,而slf4j又选择logback来作为底层的日志输出对象。

常用的日志场景切换解释

上面把日志的切换原理说清楚了,下面就针对具体的例子来进行应用

先来看下slf4j官方的一张图:

下面分别详细说明这三个案例

1 左上图

现状:

目前的应用程序中已经使用了如下混杂方式的API来进行日志的编程:

现在想统一将日志的输出交给logback

commons-logging

log4j1

jdk-logging

解决办法:

加入以下jar包:

第一步:将上述日志系统全部无缝先切换到slf4j

  • 去掉commons-logging(其实去不去都可以),使用jcl-over-slf4j将commons-logging的底层日志输出切换到slf4j
  • 去掉log4j1(必须去掉),使用log4j-over-slf4j,将log4j1的日志输出切换到slf4j
  • 使用jul-to-slf4j,将jul的日志输出切换到slf4j

第二步:使slf4j选择logback来作为底层日志输出

slf4j-api

logback-core

logback-classic

下面的2张图和上面就很类似

2 右上图

现状:

目前的应用程序中已经使用了如下混杂方式的API来进行日志的编程:

现在想统一将日志的输出交给log4j1

commons-logging

jdk-logging

解决办法:

加入以下jar包:

第一步:将上述日志系统全部无缝先切换到slf4j

  • 去掉commons-logging(其实去不去都可以),使用jcl-over-slf4j将commons-logging的底层日志输出切换到slf4j
  • 使用jul-to-slf4j,将jul的日志输出切换到slf4j

第二步:使slf4j选择log4j1来作为底层日志输出

加入以下jar包:

slf4j-api

log4j

slf4j-log4j12(集成包)

3 左下图

现状:

目前的应用程序中已经使用了如下混杂方式的API来进行日志的编程:

现在想统一将日志的输出交给jdk-logging

commons-logging

log4j

解决办法:

第一步:将上述日志系统全部无缝先切换到slf4j

  • 去掉commons-logging(其实去不去都可以),使用jcl-over-slf4j将commons-logging的底层日志输出切换到slf4j
  • 去掉log4j1(必须去掉),使用log4j-over-slf4j,将log4j1的日志输出切换到slf4j

第二步:使slf4j选择jdk-logging来作为底层日志输出

加入以下jar包:

slf4j-api

slf4j-jdk14(集成包)

冲突说明

仍然是这里的内容slf4j官网的冲突说明

其实明白上面介绍的各jar包的作用,就很容易理解

jcl-over-slf4j 与 slf4j-jcl 冲突

jcl-over-slf4j: commons-logging切换到slf4j

slf4j-jcl : slf4j切换到commons-logging

如果这两者共存的话,必然造成相互委托,造成内存溢出

log4j-over-slf4j 与 slf4j-log4j12 冲突

log4j-over-slf4j : log4j1切换到slf4j

slf4j-log4j12 : slf4j切换到log4j1

如果这两者共存的话,必然造成相互委托,造成内存溢出。但是log4j-over-slf4内部做了一个判断,可以防止造成内存溢出:

即判断slf4j-log4j12 jar包中的org.slf4j.impl.Log4jLoggerFactory是否存在,如果存在则表示冲突了,抛出异常提示用户要去掉对应的jar包,代码如下,在slf4j-log4j12 jar包的org.apache.log4j.Log4jLoggerFactory中:

jul-to-slf4j 与 slf4j-jdk14 冲突

jul-to-slf4j : jdk-logging切换到slf4j

slf4j-jdk14 : slf4j切换到jdk-logging

如果这两者共存的话,必然造成相互委托,造成内存溢出

结束语

至此,这个日志系列就算终于完成了。它注重于日志系统之间的交互与集成,所以想深入研究单个日志系统的架构的话,就需要各位自行去深入研究了,希望大家以后多多支持我们!

(0)

相关推荐

  • 详解记录Java Log的几种方式

    在Java中记录日志的方式有如下几种: 一.System.out.println(最简单) 1.输出到控制台:System.out.println("XXX"); 2.输出到指定文件: import java.io.PrintStream; PrintStream ps = new PrintStream("D:\\test.txt"); System.setOut(ps); System.out.println("XXX"); 二.java.u

  • jdk-logging log4j logback日志系统实现机制原理介绍

    目录 1 需要解决的疑惑 2 jdk自带的logging 2.1 使用案例 2.2 简单过程分析: 3 log4j1 3.1 使用案例 3.1.1 需要的jar包 3.1.2 使用方式 3.2 获取Logger的原理 3.3 主要对象总结 4 log4j2 4.1 背景介绍 4.2 log4j2的使用案例 4.2.1 需要的jar包 4.2.2 使用方式 4.3 使用过程简单分析 4.4 主要对象总结 5 logback 5.1 使用案例 5.1.1 需要的jar包 5.1.2 使用方式 5.3

  • 使用Logback设置日志级别

    Logback设置日志级别 使用Logback设置日志的设置方式现在已经有很多文章说明,本文重点说明不同设置方式的区别和用途.首先列举常用的三种方式,接下来说明其区别. appender中的LevelFilter: 级别过滤器,根据日志级别进行过滤.如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志 <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppende

  • Logback与Log4j2日志框架性能对比与调优方式

    目录 前言 性能测试 logback 同步日志 异步日志(队列扩容) 异步日志(半队列扩容) log4j2 同步日志 异步日志(队列扩容) 异步日志(日志淘汰策略) 异步日志(半队列扩容) 异步日志(等待策略) 性能调优 异步日志 日志可靠性 Logback Log4j2 日志抛弃策略 Log4j2 Logback 日志等待策略 TimeoutWaitStrategy YieldWaitStrategy 队列容量 Logback Log4j2 长度计算公式 消费瓶颈 消费TPS 请求TPS 消费

  • 基于logback 实现springboot超级详细的日志配置

    前言 java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日志框架就能够用 slj4f 调用).其中性能最高的应该使 logback 了,而且 springboot 默认使用的也是 logback 日志,所以本篇将会详细的讲解 logback 的日志配置方案. 本篇主要内容如下: •logback 配置文件的构成 •如何将日志输出到文件 •如何按时间,按大小切分日志 •如何将让一个日志文件中只有

  • slf4j jcl jul log4j1 log4j2 logback各组件系统日志切换

    目录 各种jar包总结 slf4j转向某个实际的日志框架: 某个实际的日志框架转向slf4j: 集成总结 commons-logging与其他日志框架集成 slf4j与其他日志框架集成 日志系统之间的切换 log4j无缝切换到logback 1 案例 2 切换原理 jdk-logging无缝切换到logback 1 案例 切换原理 commons-logging切换到logback 使用案例 切换原理 常用的日志场景切换解释 1 左上图 2 右上图 3 左下图 冲突说明 jcl-over-slf

  • jcl与jul log4j1 log4j2 logback日志系统机制及集成原理

    目录 apache commons-logging 1 简单的使用案例 2 使用原理 1 获取LogFactory的过程 2 根据LogFactory获取Log的过程 commons-logging与jul集成 1 需要的jar包 2 使用案例 3 使用案例分析 1 获取获取LogFactory的过程 2 根据LogFactory获取Log的过程 commons-logging与log4j1集成 1 需要的jar包 4.2 使用案例 3 使用案例分析 1 获取获取LogFactory的过程 2

  • slf4j与jul、log4j1、log4j2、logback的集成原理

    目录 slf4j 1 简单的使用案例 2 使用原理 1 获取ILoggerFactory的过程 2 根据ILoggerFactory获取Logger的过程 slf4j与jdk-logging集成 1 需要的jar包 2 使用案例 3 使用案例原理分析 1 获取ILoggerFactory的过程 2 根据ILoggerFactory获取Logger的过程 slf4j与log4j1集成 1 需要的jar包 2 使用案例 3 使用案例原理分析 1 获取对应的ILoggerFactory 2 根据ILo

  • SpringBoot快速集成Logback日志组件

    目录 前言 引入: 配置: 开发: 结语 前言 在前一节的分享中,慕歌向大家介绍了如何使用spring boot 实现简单的邮寄发送服务,用于验证码服务或者是通知服务.如果大家有兴趣,慕歌还想向大家进一步分享,如何在使用第三方服务,实现手机短信通知服务,就是那个我们每天都会使用到的短信验证码,通知服务.这一节慕歌想带来spring boot日志系统的分享,以及慕歌自己的实现的简易日志记录,慕歌会将日志同时保存在文件和数据库之中. 引入: 如果我们使用 logback 就无需额外引入依赖,在spr

  • log4j2 项目日志组件的实例代码

    在项目运行过程中,常常需要进行功能调试以及用户行为的跟踪和记录,部分人习惯使用System.out,但这并不建议,它仅仅是使用方便但不便于维护也无扩展性.相比log4j的话,log4j可以控制日志信息的输送目的地.输出格式以及级别等等,使我们能够更加细致地控制日志的生成过程. Log4j2是对Log4j1的升级,在性能和功能上有显著的改进,包括多线程中吞吐量的增强.占位符的支持.配置文件自动重新加载等 一.入门介绍 1.下载jar包 pox.xml <dependencies> <dep

  • Java ASM使用logback日志级别动态切换方案展示

    目录 背景 logback简介 解决方案 方案一:logback自动扫描更新 方案二:ASM动态修改字节码 延伸扩展 背景 一切皆有因果,所有事情,都有事件驱动.本方案的日志级别切换是由这样的背景下产生的: 单个生产环境上,有几百近千个微服务 日志级别切换不重启服务,要求即时生效果 由业务开发人员去修改代码或增加相关依赖配置等涉及面广,推动进度慢 后期动态实时过滤垃圾日志,减少io和磁盘空间成本 logback简介 在跟敌人发起战争之前,只有先发解敌方的情况,才能做到百战百胜.要想对logbac

  • 混乱的Java日志体系及集成jar包梳理分析

    目录 一.困扰的疑惑 log4j Logback SLF4J Apache Common-Logging 二.how to use 三.结束 一.困扰的疑惑 目前的日志框架有 jdk 自带的logging,log4j1.log4j2.logback ,这些框架都自己定制了日志 API ,并且有相应的实现: 目前用于实现日志统一的框架 Apache commons-logging(jcl).slf4j ,遵循「面向接口编程」的原则,这两大框架可以让用户在程序运行期间去选择具体的日志实现系统(log

  • 详解slf4j+logback在java工程中的配置

    本文主要介绍一下slf4j+logback在java工程中的配置,面向的读者主要是已经对slf4j+logback有一定了解的同学,但是在文章开头也做了一些知识铺垫,下面咱们进入正题. 在介绍slf4j+logback配置之前,首先对日志组件logback进行介绍. (一)日志组件logback的介绍及配置使用方法 一.logback的介绍     Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classi

随机推荐