JCL、SLF4J、Log4J、Log4J2、LogBack和JUL之间的关系,你搞清楚了吗?

写在前面

日志组件是我们平时开发过程中必然会用到的组件。在系统中正确的打印日志至少有下面的这些好处:

  • 调试:在程序的开发过程中,必然需要我们不断的调试以达到程序能正确执行的状态 。记录日志可以让开发人员清楚的了解程序的运行状态定位问题;
  • 信息收集:在DT时代,谁掌握了数据谁就掌握了主动权。现在主流的日志系统可以非常方便的记录用户行为数据,格式化成便于进行大数据分析的格式;
  • 记录运行状态:应用程序投产之后,难免会出现生产事故,有了系统日志工程师可以根据日志迅速定位问题。

当然,硬币都具有两面性。引入日志组件也并不是没有缺点。

  • 代码冗余:光从实现业务逻辑的角度来讲,在应用程序中插入打印日志的代码打印一大堆日志是完全没必要的,这在一定程度上降低了代码的可读性;
  • 降低系统性能:这点很容易理解,因为需要进行日志打印处理,所以系统的运行速度肯定会有所降低。

综合比较日志组件优缺点,我们发现引入日志组件还是非常有必要的。

在我们平时的开发过程中,常用的日志组件有Log4J、Log4J2和LogBack等。代码中,我们一般都是像下面这样使用它们的。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableAdminServer
public class AppQuickStart {

    private static Logger logger = LoggerFactory.getLogger(AppQuickStart.class);

    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        logger.info("app begin to start...");
        SpringApplication.run(AppQuickStart.class, args);
        logger.info("app start success...");

    }
}

或者是像下面这样

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableAdminServer
public class AppQuickStart {

    private static final Log logger = LogFactory.getLog(AppQuickStart.class);
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName());
        logger.info("app begin to start...");
        SpringApplication.run(AppQuickStart.class, args);
        logger.info("app start success...");

    }
}

上面的两段代码很相似,是我们引入日志的模板代码,唯一有区别的地方是第一段代码引入了SLF4J的Jar包,第二段代码引入了common-logging的Jar包(后面简称JCL)。

刚开始接触日志组件的时候,我对这样的使用方式感到很疑惑:我们不是要用使用Log4J或者是LogBack打日志么,怎么完全没见到Log4JLogBack的影子,反而有冒出来两个新框架SLF4Jcommon-logging

那么这两个框架到底有什么作用?和Log4JLog4J2还有LogBack又是什么关系?如果你也有这样的疑问,说明你还是善于思考的。今天的文章就来介绍下JCLSLF4JLog4JLog4J2LogBacky以及JUL(JUL的存在感很低,哈哈~)之间的关系。

门面模式

学过设计模式的同学都会知道在23种设计模式中有一种模式叫门面模式

以上是门面模式的结构图。

在这个结构图中,出现了两个角色:

  • 门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
  • 子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

使用门面模式具有以下优点

  • 松散耦合: 门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
  • 简单易用: 门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。
  • 更好的划分访问层次: 通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。

JCLSLF4J

为什么要介绍上面的门面模式呢?因为现今主流的日志组件都是使用门面模式实现的。而JCLSLF4J就是门面模式中的Facade角色。

JCL官网对JCL的介绍:

The Logging package is an ultra-thin bridge between different logging implementations. A library that uses the commons-logging API can be used with any logging implementation at runtime. Commons-logging comes with support for a number of popular logging implementations, and writing adapters for others is a reasonably simple task. ——JCL官网

上面英文的大致意思是:JCL是不同日志实现之间的一座“桥梁”,JCL支持许多主流的日志实现。而且自己编写JCL的适配代码也很简单。

SLF4J的介绍:

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time. —— SLF4J官网

上面英文的大致意思是:SLF4J充当不同日志框架门面的角色,让用户可以自由切换底层的日志实现。

通过上面的介绍,我们可以知道JCLSLF4J都是日志门面(Facade),而Log4JLog4J2LogBack都是子系统角色(SunSystem),也就是具体的日志实现框架。他们的关系如下。

使用日志门面引入日志组件的最大优势是:将系统和具体的日志实现框架解耦合

假如说我们不使用日志门面,直接使用特定的日志框架(比如说Log4J)的API进行编程,那么我们势必会在每个类中都耦合Log4J的API,如果你的系统一直使用Log4j作为日志实现,那OK。一旦有一天你老板心血来潮觉得Log4J不能满足系统的需求了(这边只是举个栗子,Log4J还是很强大^_^),指派你将Log4J更换成其他的日志实现。我想此刻的你一定会有点懵逼。因为你需要修改每个类中耦合的Log4J API。

如果使用JCL或者SLF4J等日志门面很好的帮我们解决了这种问题,我们不需要修改代码,只需要更换日志实现框架即可。

Log4J、Log4J2和LogBack的有趣历史

使用过Log4JLogBack的同学肯定能发现,这两个框架的设计理念极为相似,使用方法也如出一辙。

其实这个两个框架的作者都是一个人,Ceki Gülcü,俄罗斯程序员。

Log4J 最初是基于Java开发的日志框架,发展一段时间后,作者Ceki Gülcü将Log4j捐献给了Apache软件基金会,使之成为了Apache日志服务的一个子项目。 又由于Log4J出色的表现,后续又被孵化出了支持C, C++, C#, Perl, Python, Ruby等语言的子框架。

然而,伟大的程序员好像都比较有个性。Ceki Gülcü由于不满Apache对Log4J的管理,决定不再参加Log4J的开发维护。“出走”后的Ceki Gülcü另起炉灶,开发出了LogBack这个框架(SLF4J是和LogBack一起开发出来的)。

LogBack改进了很多Log4J的缺点,在性能上有了很大的提升,同时使用方式几乎和Log4J一样,许多用户开始慢慢开始使用LogBack

由于受到LogBack的冲击,Log4J开始式微。终于,2015年9月,Apache软件基金业宣布,Log4j不在维护,建议所有相关项目升级到Log4j2

Log4J2是Apache开发的一个新的日志框架,改进了很多Log4J的缺点,同时也借鉴了LogBack,号称在性能上也是完胜LogBack。有兴趣的朋友可以测试下两者的性能。

这边顺带提下JUL这个日志组件。这个日志组件是JDK自带的日志框架。由于在使用便利性和性能上都欠佳,所以存在感一直不高。

简单总结

  • JCLSLF4J功能一样,都是日志门面,使用它们引入日志组件的目的是将系统和具体的日志实现之间解耦;
  • Log4JLog4J2LogBackJUL都是具体的日志实现。使用时要和门面日志搭配使用。

参考

原文地址:https://www.cnblogs.com/54chensongxia/p/12321446.html

时间: 2024-10-11 18:18:06

JCL、SLF4J、Log4J、Log4J2、LogBack和JUL之间的关系,你搞清楚了吗?的相关文章

Log4j,Log4j2,logback,slf4j日志学习

日志学习笔记 Log4j Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程. Log4j有7种不同的log级别,按照等级从低到高依次为:TRACE.DEBUG.INFO.WARN.ERROR.FATAL.OFF.如果配置为OFF级别,表示关闭log. Log4j支持两种格式的配置文件:properties和xml.包含三

Java日志框架SLF4J和log4j以及logback的联系和区别

1.SLF4J(Simple logging Facade for Java) 意思为简单日志门面,它是把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口,使用时只需要按照其提供的接口方法进行调用即可,由于它只是一个接口,并不是一个具体的可以直接单独使用的日志框架,所以最终日志的格式.记录级别.输出方式等都要通过接口绑定的具体的日志系统来实现,这些具体的日志系统就有log4j,logback,java.util.logging等,它们才实现了具体的日志系统的功能. 如何使用SL

Java日志commons-logging log4j slf4j之间的关系

一.之前进行日志操作一般都是在一个类中加入如下代码: import org.apache.log4j.Logger; //引入的是log4j的包 private static final Logger LOG = Logger.getLogger(Test.class); 二.后来看见别人的代码是这样写的: import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; //引入的是comm

初识log4j,logback和slf4j

1.日志输出格式说明: %n 换行:%m日志内容:%p 日志级别(ERROR>WARN>INFO>DEBUG一般最常用的就是这四个,其中如果要输出ibatis的sql语句必须使用DEBUG):%t当前线程名:%r程序启动到现在的毫秒数:%d日期和时间(常用的格式有:%d{date},%d{hh:mm:ss,sss}等等):%L源码行数:%C类名:%M方法名. 2.slf4j是java的一个api,它可以配合任何日志系统使用,包括log4j,logback等等.使用slf4j不必在类中声明

slf4j log4j logback

最先大家写日志都用log4j,后来作者勇于创新,又搞了个logback,又为了统一江湖,来了个slf4j,所以目前在代码中进行日志输出,推荐使用slf4j,这样在运行时,你可以决定到底是用log4j还是logback,根据他们不同的配置文件就可以搞定. 基本原理就是 slf4j  -->  adator --> log, 见下图: 但是对于之前的比较老的项目,还是在用log4j输出,是否有可能将其在不改动代码的前提下转到用logback输出了? 答案是有的,去掉运行时环境中的log4j的包和配

springboot的日志框架slf4j (使用logback输出日志以及使用)

1.为什么使用logback? --在开发中不建议使用System.out因为大量的使用会增加资源的消耗.因为使用System.out是在当前线程执行的,写入文件也是写入完毕之后才继续执行下面的程序.而使用Log工具不但可以控制日志是否输出,怎么输出,它的处理机制也是通知写日志,继续执行后面的代码不必等日志写完. --个人推荐使用SLF4J(Simple Logging Fa?ade For Java)的logback来输出日志,其比log4j效率高.     --Spring Boot 提供了

使用Slf4j集成Log4j2构建项目日志系统的完美解决方案

一.背景 最近因为公司项目性能需要,我们考虑把以前基于的log4j的日志系统重构成基于Slf4j和log4j2的日志系统,因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用log4j2而不是log4j是因为Log4j 1.x 在高并发情况下出现死锁导致cpu使用率异常飙升,而Log4j2.0基于LMAX Disruptor的异步日志在多线程环境下性能会远远优于Log4j 1.x和logback(官方数据是10倍以上). 关于slf4j的原理以及优点

slf4j 搭配 log4j2 处理日志

目录 关于 log4j 关于 slf4j 案例使用 关于 log4j Log4j + Slf4j 的使用组合最为常见,但是我们知道 Log4j 目前已经停止更新了.Apache推出了新的 Log4j2 来代替 Log4j,Log4j2 是对Log4j 的升级,与其前身 Log4j 相比有了显着的改进,并提供了许多 Logback 可用的改进,同时解决了 Logback 体系结构中的一些固有问题.因此,Log4j2 + Slf4j 应该是未来的大势所趋. 关于 slf4j LF4J不同于其他日志类

通过slf4j/log4j的MDC/NDC 实现日志追踪

在分布式系统或者较为复杂的系统中,我们希望可以看到一个客户请求的处理过程所涉及到的所有子系统\模块的处理日志. 由于slf4j/log4j基本是日志记录的标准组件,所以slf4j/log4j成为了我的重点研究对象. slf4j/log4j支持MDC,可以实现同一请求的日志追踪功能. 基本思路是: 实现自定义Filter,在接受到http请求时,计算eventID并存储在MDC中.如果涉及分布式多系统,那么向其他子系统发送请求时,需要携带此eventID. 源代码:https://github.c