有天上飞的概念,就要有落地的实现html
大哥大姐新年好,点赞转发不要少java
文本已收录至GitHub开源仓库 Lu_JavaNodes 码云仓库地址Lu_JavaNodes ,包含教程涉及全部思惟导图,案例代码和后续讲解视频,欢迎Star增砖添瓦。git
本文阅读技术要求:见过日志程序员
没见也不要慌,以下图,这就是日志,好了,你见过了。
github
日志的做用面试
- 记录系统中的操做
- 记录系统的运行情况
- 系统错误时候,根据日志分析缘由
在一家IT企业中,项目经理虎大力(龙套) 正在指挥 程序员鹿小明(精英龙套)开发一个大型的增删改查项目。为了开发这个项目。项目组仅有的程序员鹿小明天天工做996spring
one day,虎大力给鹿小明提出来一个新的需求,为了更好的进行公司的信息化建设,虎大力想要看到代码执行的状况,执行到某个业务的时候在控制台有所表示,例如:执行到查询方法的时候,须要在控制台上出现,这是一个打印方法的信息。设计模式
鹿小明一想,这好办啊,原本本身为了调试测试方便就写过不少打印语句,如今无非更多而已。因而就加班加点在全部的增删改查方法中都写了System.out.println()
打印语句。顺利完成了这个工做。api
一段时间岁月静好框架
one day,虎大力找到鹿小明:你这个代码里面System.out.println()
太多了,我须要你作成,测试时候显示,上线以后不显示。你去搞一下。
鹿小明因而左思右想:我要不要上线的时候把打印语句注释掉,测试的时候再打开呢?
可是想到要常常开关注释也不是个容易的事儿,因而鹿小明一咬牙,996变007,废寝忘食的更新出了 V2.0版本。他把日志打印封装成框架 logging-1.0.jar,能够进行统一的开关。顺利完成了这个工做。
一段时间岁月静好
one day,虎大力找到鹿小明:你这个日志框架功能太简单了 ,再搞点新功能,像输出到文件啊,异步啊都搞上。
鹿小明因而左思右想,007以后继续007,废寝忘食的更新出了 V3.0 版本,封装成一个新的框架logging-2.0.jar。顺利完成了这个工做。
一段时间岁月静好
one day,虎大力找到鹿小明:1.0和2.0的api不同,1.0换成2.0,2.0换成1.0 每次切换都要改代码,你改一下吧,改为能够想用哪一个用哪一个的。
鹿小明因而左思右想,007以后继续007,这个需求有点难,他从JDBC上找到了灵感,JDBC经过统一接口实现了驱动的切换,日志也能够。
因而,他爆肝搞出来一个日志接口层(日志门面),让 1.0 和 2.0的日志框架都实现这个接口,这样想用1.0的时候就导入1.0,想用2.0的时候就导入2.0 。顺利完成了这个任务。
而这个设计的结构也是如今主流日志框架:log4j logback log4j2 等的结构
日志门面(接口) | 日志实现 |
---|---|
SLF4J,commons-logging | Logback,Log4j |
经过它们就打印出了咱们常见的各类日志信息
日志框架实际上分为三个部分,除了上面提到的日志门面(接口)和日志库(实现),还有日志适配器
定义接口规范,不负责具体实现,也就是说之后代码中打印日志时调用的日志门面接口的方法。常见的有 SLF4J,commons-logging 都是这样。常见的日志门面有下面几种
日志门面(接口规范层) | 简介 |
---|---|
JCL(Jakarta Commons Logging) | 这个jar就是常见的 commons-logging.jar,也是Spring框架中使用的日志门面。因为上一次更新仍是在2014年,因此不建议使用 |
SLF4j(Simple Logging Facade for Java) | 这个jar能够说是最经常使用的日志jar包了 |
jboss-logging | 使用最少,一些特定的框架在使用 |
根据简单的分析,在咱们的代码中若是要选择一款 日志的接口规范的话,毫无疑问,只有 SLF4j 配得上咱们的项目。
日志库是日志功能的具体实现,早期就是为了替代 System.out 语句而出现的。经常使用的日志库以下:
日志库(日志实现) | 简介 |
---|---|
log4j | 最先诞生,用的也最多 |
logback | 最晚出现,和log4j同一做者,是log4j的升级版 |
log-jdk | jdk 在1.4版本出现的java.util.logging 简称 log-jdk |
在实际的开发中,log4j和logback的使用都很是的普遍,可是若是你如今要开发的是一个新项目,那么推荐使用 logback
这个东西是啥呢?要从历史提及,在日志框架的历史中,并非先有 日志门面(接口规范),后有日志库。实际的状况是 做者 先写出来 log4j 用了一段时间以后才有了 slf4j 。
Tips:
- slf4j log4j logback 是同一个爹(做者)
- log4j 能够等价于 鹿小明写的 1.0 那时候尚未接口规范
由于这个前后顺序的问题,就出现了一个很尴尬的状况,代码实现和接口不兼容,由于log4j的代码中没有实现slf4j的接口,因此要使用 slf4j+log4j的话,须要有个中间层(日志门面适配器)来解决接口的兼容问题。
举个例子:你买的超极本上没有网线插口怎么办呢?买个USB的转换器,这个装换器就是咱们说的中间层,也就是 日志门面适配器。 slf4j+“转换器”+log4j 才能正常工做。
经过这样的设计模式,slf4j不只兼容了log4j,还兼容了不少其余的日志框架。经过阅读slf4j官方文档 能够看到这样一张图
在图中标记了 1 2 3 4,对照前面的概念解释一下
标记1:这是只有接口规范,没有日志实现的状况,项目中只有接口没有实现也就不会有任何日志信息输出。
标记2:应用代码中使用logback做为日志库实现,经过图示能够看到logback是直接实现SLF4J接口的,不须要“转换器”。接口层+代码实现。这也是logback和log4j的区别之一。
标记3:应用代码中使用log4j做为日志库实现,这个图示在slf4j-api.jar以后,还有一个slf4j-log4j12.jar,他就是咱们提到过的“转换器”日志门面适配器。接口层+转换器+代码实现 的关系。
标记4:这个图示中也有转接头jar包,只不过这个jar包是为了兼容log-jdk。
那么问题来了,logback和log4j在使用上有什么区别?
日志门面适配器“接口实现转接器”解决了接口规范和实现之间不兼容的问题。咱们终于能够愉快的开始枯燥的日志打印了。
可是慢着,难道没有以为哪里不对吗?你品,你细品
虽然咱们的项目采用slf4j在快乐的打印日志,可是其余的框架用的可不是slf4j,譬如Spring(commons-logging)、Hibernate(jboss-logging),这种状况下 咱们的项目的就像一个国家有了不少套法律,到底听谁的, 因此咱们须要让别的框架和log4j一块儿统一使用slf4j进行输出日志?
咋能作到呢?这就要用到日志库适配器了。它也是一个转接头,举个栗子
slf4j 至关于只有type-c接口的苹果电脑。如今你有不少U盘想接到电脑上,可是U盘用的是USB接口,要怎么办呢?
买一个 type-c 转 USB的转换器便可
经过官方文档找到下面这张图—说明了 其余日志框架如何接入到slf4j上
这张图上有三个图示,因为三个的原理的都同样,咱们以左上角的为例作简单的讲解:
这张图咱们先竖着看,就是应用程序使用的logback作日志框架,接口规范+实现的简单关系。
接着咱们横着看,会看到 commons-logging log4j(以前说过log4j生的早)log-jdk,这些就是应用中其余框架Spring等使用的日志框架,想让这些框架统一接入到slf4j, 怎么办呢?
以commons-logging为例,若是你的项目中用了Spring,Spring就须要使用到commons-logging.jar ,怎么让 Spring 的日志最终经过 slf4j 输出呢?
1.咱们须要先排除 commons-logging.jar ,毕竟它压根儿就没有输出到slf4j的功能,可是排除以后spring会报错啊,不要慌 这就到了第二步。
2.用 jck-over-slf4j.jar 替换 commons-logging.jar, 这个包有什么做用呢?偷天换日,鸠占鹊巢,它就是咱们要找的转换器,一方面它的功能和commons-logging同样,彻底能够替代;另外一方面,能够无缝接入到slf4j。
这个中间转换器包就是就是日志库适配器。
简单吧,经过上述两步就能够实现 commons-logging 统一到slf4j 。
经过这样的逻辑,能够很简单的把log4j,log-jdk 也都能经过中间的转换包统一到slf4j,也就实现了slf4j一统日志江湖。
总结回顾好习惯
日志框架分为
1.日志门面,定义了日志的接口规范
2.日志库,实现日志具体功能的代码实现
3.日志门面适配器,又名 接口实现转换器
4.日志库适配器,又名 第三方接入slf4j转接头
注意
在使用 slf4j + 日志库 模式的时候,要防止日志库冲突,简单说就是 要么用 slf4j+log4j 要么用 slf4j+logback 千万不要两个都用!!!
恭喜你完成了本文的阅读,为你鼓掌!
本文讲解的内容是 日志框架的基本认识,关于日志框架在项目中的使用,以及开发中的日志规范,请持续关注。
本人拥有两年开发经验和三年Java大数据教学经验,曾帮助2000+学生成功就业和跳槽。