简介

在系统开发中,日志是很重要的一个环节,日志写得好对于我们开发调试,线上问题追踪等都有很大的帮助。但记日志并不是简单的输出信息,需要考虑很多问题,比如日志输出的速度,日志输出对于系统内存,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. 《Android进阶之光》--RxJava

    No1: RxJava使用 dependencies{ compile 'io.reactivex:rxjava:1.2.0' compile 'io.reactivex:rxandroid:1.2. ...

  2. HDU 2795 Billboard【点修改】

    <题目链接> 题目大意: 有一块h*w的矩形广告板,要往上面贴广告,然后给n个1*wi的广告,要求把广告贴上去,而且要求广告要尽量往上贴并且尽量靠左, 求第n个广告的所在的位置,不能贴则为 ...

  3. python爬虫之下载文件的方式总结以及程序实例

    python爬虫之下载文件的方式以及下载实例 目录 第一种方法:urlretrieve方法下载 第二种方法:request download 第三种方法:视频文件.大型文件下载 实战演示 第一种方法: ...

  4. P1939【模板】矩阵加速(数列)

    P1939[模板]矩阵加速(数列)难受就难受在a[i-3],这样的话让k=3就好了. #include<iostream> #include<cstdio> #include& ...

  5. IntelliJ IDEA(九) :插件(转)

    最近项目比较忙,很久没有更新IDEA系列了,今天介绍一下IDEA的一些炫酷的插件,IDEA强大的插件库,不仅能给我们带来一些开发的便捷,还能体现我们的与众不同. 0|11.插件的安装 打开settin ...

  6. 线程、对称多处理和微内核(OS 笔记三)

    线程.对称多处理 ​ 这一部分继续深入探讨与进程管理相关的高级概念并了解多处理机的对称多处理技术. 进程和线程 到目前为止提出的进程的概念包含两个特点: 资源所有权 存放进程映像的虚拟地址空间 调度/ ...

  7. vue 解决双向绑定中 父组件传值给子组件后 父组件值也跟着变化的问题

    说明: 近日开发中碰见一个很诡异的问题,  父组件动态的修改对象 data 中的值, 然后将这个对象 data 传给子组件, 子组件拿到后将 data 中的值 乘以 100 ,发现父组件中的值也跟着变 ...

  8. QT-1-环境搭建QT5.4.1&MinGW4.9.1

    1.最近在电脑上尝试了搭建QT的环境,原本准备利用VS2013+QT5.51环境,虽然安装很容易但是部署程序时,我是没能做到部署到其他机器,原因还是DLL搞不定: 2.参考友善之臂的MiniTools ...

  9. BZOJ.5417.[NOI2018]你的名字(后缀自动机 线段树合并)

    LOJ 洛谷 BZOJ 考虑\(l=1,r=|S|\)的情况: 对\(S\)串建SAM,\(T\)在上面匹配,可以得到每个位置\(i\)的后缀的最长匹配长度\(mx[i]\). 因为要去重,对\(T\ ...

  10. AGC 015C.Nuske vs Phantom Thnook(思路 前缀和)

    题目链接 闻本题有格子,且何谓格子也 \(Description\) 给定\(n*m\)的蓝白矩阵,保证蓝格子形成的的同一连通块内,某蓝格子到达另一个蓝格子的路径唯一. \(Q\)次询问.每次询问一个 ...