简介

在系统开发中,日志是很重要的一个环节,日志写得好对于我们开发调试,线上问题追踪等都有很大的帮助。但记日志并不是简单的输出信息,需要考虑很多问题,比如日志输出的速度,日志输出对于系统内存,CPU的影响等,为此,出现了很多日志框架,以帮助开发者解决这些问题。

java中的常用日志框架

比较常用的有Log4j,SLF4j,Commons-logging,logback。当然,JDK本身也提供了java.util.logging包来提供对日志的支持。

Commons-loggin:是apache最早提供的日志的门面接口。它的主要作用是提供一个日志门面,使用者可以使用不同的日志实现。用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。common-logging内部有一个Simple logger的简单实现,但是功能很弱。

SLF4j:是Simple Logging Facade for Java的简称,即java的简单日志门面。类似于Apache Common-Logging,是对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑定真正的Log库。使用SLF4J时,如果你需要使用某一种日志实现,那么你必须选择正确的SLF4J的jar包的集合(各种桥接包)。

Log4j:经典的一种日志解决方案。内部把日志系统抽象封装成Logger 、appender 、pattern等实现。我们可以通过配置文件轻松的实现日志系统的管理和多样化配置。pache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等;用户也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,用户能够更加细致地控制日志的生成过程。这些可以通过一个 配置文件来灵活地进行配置,而不需要修改程序代码。

logback:也是一种日志实现。Logback是由log4j创始人设计的又一个开源日记组件。logback当前分成三个模块:logback-core,logback-classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日记系统如log4j或JDK14Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日记的功能。

各个框架之间的关系

上面说了这么多日志框架,它们之间是怎样的关系呢? 
1. commons-logging和slf4j是java中的日志门面,即它们提供了一套通用的接口,具体的实现可以由开发者自由选择。log4j和logback则是具体的日志实现方案。 
2. 它们可以理解为接口与实现类的关系 
3. 四个框架都可以在程序中使用,但是为了考虑扩展性,一般我们在程序开发的时候,会选择使用commons-logging或者slf4j这些日志门面,而不是直接使用log4j或者logback这些实现。即我们写代码的时候导入的类一般都是来自门面框架中的类,然后将某个日志的实现框架加入到项目中,提供真正的日志输出功能。 
4. 比较常用的搭配是commons-logging+log4j,slf4j+logback

下面的图描述的挺好: 

日志框架的门面模式

门面模式,是面向对象设计模中的结构模式,又称为外观模式。外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 
简单理解就是通过通过门面模式对外提供一个统一的调用接口,屏蔽子系统之间复杂的调用关系,对客户端来讲,使用起来更容易。

commons-logging和slf4j就是这样,它们提供了日志的更高层次的抽象,具体的实现使用者不需要关心,而且可以自由选择。

使用举例

在开发中,我们一般不会直接使用某个具体的日志框架(比如log4j和logback),而是使用commons-logging和slf4j,这样做的好处是,我们可以自由选择日志实现。 
特别是对于一些开源框架来说更是如此,在提供给其他人使用的时候,使用我们框架的人使用的日志框架是复杂多变的,不确定的,所以如果我们开源框架里选择了一个具体的日志实现,而碰巧这个日志实现的可扩展性和兼容性又不好,那么使用我们开源框架的人为了满足我们框架的日志,就只能跟我们框架用一样的日志实现,否则打印日志可能就会有问题。这样一来,使用我们框架的开发者的自由度就降低了。

基于commons-logging的日志使用

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class XXXService {
private static final Log log = LogFactory.getLog(XXXService.class);
public void doSomething(){
log.info("begin dosomething....");
}
}

基于slf4j的日志使用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XXXService {
private static final Logger logger = LoggerFactory.getLogger(XXXService.class);
public void doSomething() {
logger.info("begin dosomething...");
}
}

上面的两种方式,引入的包都是门面日志框架的包,而不是具体某个实现的包。

Commons-logging和SLF4j实现机制

使用门面模式,如果门面模式本身不提供日志实现,那么我们还是不能正确打印日志的。所以还需要通过门面模式能够找到其实现类。就跟接口与实现类一样。 
那么,日志的门面框架是如何与实现框架建立关系的呢?

Commons-logging

common-logging通过动态查找的机制,在程序运行时自动找出真正使用的日志库。由于它使用了ClassLoader寻找和载入底层的日志库,导致了象OSGI这样的框架无法正常工作,因为OSGI的不同的插件使用自己的ClassLoader。OSGI的这种机制保证了插件互相独立,然而却使Apache Commons-Logging无法工作。

SLF4j

slf4j在编译时静态绑定真正的Log库,因此可以再OSGI中使用。它是通过查找类路径下org.slf4j.impl.StaticLoggerBinder,然后绑定工作都在这类里面进行,如果发现类路径下有多个StaticLoggerBinder,会给出警告。

slf4j提供了针对各种日志框架的迁移方案,并未这些方案提供了各种桥接框架。 
关于SLF4j,它的官方文档讲解的很好,可以参考这里

为什么要用SLF4J+Logback 替换commons-logging+log4j?

  1. SLF4J是编译时绑定到具体的日志框架,性能优于采用运行时搜寻的方式的commons-logging
  2. SLF4J提供了更好的日志记录方式,带来下这几方面的好处:1、更好的可读性;2、不需要使用logger.isDebugEnabled()来解决日志因为字符拼接产生的性能问题。比如:logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol); 官方文档:这里
  3. logback支持了更方便的自定义日志,便于后期的日志分析,可以将日志格式化保存到各种存储引擎中,请点击这里 可以将日志写入到HBase等。

补充一点

分析下面两行代码的区别:

logger.info("my name is {}", "medusar");
logger.info("my name is " + "medusar");

在效率上,第一行比第二行更高,因为如果当前日志级别是ERROR,第一行不会进行字符串拼接,而第二行,无论日志级别是什么,都会先进行字符串拼接。 
所以为了解决这个问题,commons-logging等框架提供了下面的方式:

if (log.isDebugEnabled()){
log.debug("dddd"+"eee");
}

而slf4j却不需要,因为它的日志级别不满足的时候会进行字符串拼接。

参考资料

  1. http://www.cnblogs.com/zhuawang/p/3999235.html
  2. http://blog.csdn.net/yycdaizi/article/details/8276265
  3. https://segmentfault.com/a/1190000000370671
  4. http://singleant.iteye.com/blog/934593

转自:http://blog.onlycatch.com/post/cfbc30f8d1ba



												

Java日志框架(Commons-logging,SLF4j,Log4j,Logback)的更多相关文章

  1. Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)

    一.简介 JAVA日志在初期可能官方并没有提供很好且实用的规范,导致各公司或OSS作者选择自行造轮子,这也导致了目前初学者觉得市面上 Java 日志库繁杂的局面. 现在市面流行以 slf4j(Simp ...

  2. Java日志框架 (commons-logging,log4j,slf4j,logback)

    转自:http://blog.csdn.net/kobejayandy/article/details/17335407 如果对于commons-loging.log4j.slf4j.LogBack等 ...

  3. Java日志框架:SLF4J,Common-Logging,Log4J,Logback说明

    Log4j  Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog守护进程等 ...

  4. 日志框架之2 slf4j+logback实现日志架构 · 远观钱途

    如何从缤纷复杂的日志系统世界筛选出适合自己的日志框架以及slf4j+logback的组合美妙之处?此文可能有帮助 logback介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网 ...

  5. SpringBoot日志logback-spring.xml分环境log4j logback slf4j区别 springboot日志设置

    转载. https://blog.csdn.net/qianyiyiding/article/details/76565810 springboot按照profile进行打印日志log4j logba ...

  6. java日志框架系列(1):slf4j框架简介及依赖

    1.slf4j日志框架 1.简介 slf4j只是是日志规范,即只定义了接口,并没有实现这些接口. SLF4J的全称是Simple Logging Facade for Java,即简单日志门面.SLF ...

  7. java日志框架系列(4):logback框架xml配置文件语法

    1.xml配置文件语法 由于logback配置文件语法特别灵活,因此无法用DTD或schema进行定义. 1.配置文件基本结构 配置文件基本结构:以<configuration>标签开头, ...

  8. Java 日志框架终极教程

    概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的, ...

  9. slf4j log4j logback关系详解和相关用法

    slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...

随机推荐

  1. 取消a标签或者onclick在移动端点击时的背景颜色

    一.取消a标签在移动端点击时的蓝色 -webkit-tap-highlight-color: rgba(, , , ); -webkit-user-select: none; -moz-user-fo ...

  2. php中$this->是什么意思

    $this 的含义是表示    实例化后的 具体对象! 我们一般是先声明一个类,然后用这个类去实例化对象! 但是,当我们在声明这个类的时候,想在类本身内部使用本类的属性或者方法.应该怎么表示呢? 例如 ...

  3. List实体去重

    public static ArrayList<Room> removeDuplicate(List<Room> room) { Set<Room> set = n ...

  4. NumPy学习(索引和切片,合并,分割,copy与deep copy)

    NumPy学习(索引和切片,合并,分割,copy与deep copy) 目录 索引和切片 合并 分割 copy与deep copy 索引和切片 通过索引和切片可以访问以及修改数组元素的值 一维数组 程 ...

  5. 操作系统概述(os 笔记一)

    操作系统概述 操作系统的目标和功能 1.目标:作为用户/计算机接口 ​ 计算机的使用人群大致可以分为三类,终端用户,程序开发者,操作系统设计人员. 对于终端用户,即应用程序的用户来说,他们通常不关注计 ...

  6. DataGridView控件-[引用]

    DataGridView控件 DataGridView是用于Windows Froms 2.0的新网格控件.它可以取代先前版本中DataGrid控件,它易于使用并高度可定制,支持很多我们的用户需要的特 ...

  7. U3D面试题四

    1.配置Unity3D调试环境 在windows环境下,设置unity3d的编辑器调试环境方法: 点击“Edit‘---”Preferences“,弹出如下窗口 选择MonoDeveop即可. 在编辑 ...

  8. apache hbase 发布1.0.0版本

    今天apache发布了最新的hbase 1.0.0,下图是版本变迁历史: 详情参考: https://blogs.apache.org/hbase/entry/start_of_a_new_era

  9. Qt.Qt新安装之后出现Error while building/deploying (kit: Desktop Qt 5.7.0 GCC 64bit) When executing step "Make”

    出问题的环境: 操作系统: Ubuntu18.04 安装包: qt-opensource-linux-x64-5.8.0.run 现象: 新建一个Hello World项目, 试着运行, 出现以下提示 ...

  10. linux 监控工具netdata

    1. 背景 工作的关系,需要使用netdata将服务器信息实时.动态展示. 调研了netdata工具,记录一下,方便后续使用. 2. netdata介绍 2.1 netdata 能做什么? 可以参考: ...