本文的目的是搞清楚Java中各类日志Log之间是怎么的关系,如何做用、依赖,好让咱们平时在工做中若是遇到“日志打不出”或者“日志jar包冲突”等之类的问题知道该如何入手解决,以及在各类场景下如何调整项目中的各个框架的日志输出,使得输出统一。java
在平常工做中咱们可能看到项目中依赖的跟日志相关的jar包有不少,commons-logging.jar
、log4j.jar
、sl4j-api.jar
、logback.jar
等等,眼花缭乱。咱们要正确的配置,使得jar包相互做用生效以前,就先要理清它们之间的关系。程序员
那就要从Java Log的发展历程开始提及。面试
log4j
(做者Ceki Gülcü)出来时就等到了普遍的应用(注意这里是直接使用),是Java日志事实上的标准,并成为了Apache的项目设计模式
Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增长了JUL
(java.util.logging
)api
毕竟是JDK自带的,JUL也有不少人用。同时还有其余日志组件,如SimpleLog等。这时若是有人想换成其余日志组件,如log4j换成JUL,由于api彻底不一样,就须要改动代码。网络
Apache见此,开发了JCL
(Jakarta Commons Logging),即commons-logging-xx.jar
。它只提供一套通用的日志接口api,并不提供日志的实现。很好的设计原则嘛,依赖抽象而非实现。这样应用程序能够在运行时选择本身想要的日志实现组件。多线程
这样看上去也挺美好的,可是log4j的做者以为JCL很差用,本身开发出slf4j
,它跟JCL相似,自己不替供日志具体实现,只对外提供接口或门面。目的就是为了替代JCL。同时,还开发出logback
,一个比log4j拥有更高性能的组件,目的是为了替代log4j。架构
Apache参考了logback,并作了一系列优化,推出了log4j2
框架
大概了解心路历程后,再详细看看它们之间的关系、依赖。编辑器
commons-logging
已经中止更新,最后的状态以下所示:
JCL支持日志组件很少,不过也有很人用的,例如Spring 如今用的也愈来愈少了,也很少讲了
由于当时Java的日志组件比较混乱繁杂,Ceki Gülcü推出slf4j后,也相应为行业中各个主流日志组件推出了slf4j的适配 图来源于官方文档
图的意思为若是你想用slf4j做为日志门面的话,你如何去配合使用其余日志实现组件,这里说明一下(注意jar包名缺乏了版本号,在找版本时也要注意版本之间是否兼容)
slf4j + logbackslf4j-api.jar
+ logback-classic.jar
+ logback-core.jar
slf4j + log4jslf4j-api.jar
+ slf4j-log4j12.jar
+ log4j.jar
slf4j + julslf4j-api.jar
+ slf4j-jdk14.jar
也能够只用slf4j无日志实现slf4j-api.jar
+ slf4j-nop.jar
slf4j支持各类适配,不管你如今是用哪一种日志组件,你均可以经过slf4j的适配器来使用上slf4j。只要你切换到了slf4j,那么再经过slf4j用上实现组件,即上面说的。图来源于官方文档
其实总的来讲,不管就是如下几种状况
你在用JCL 使用jcl-over-slf4j.jar
适配
你在用log4j 使用log4j-over-slf4j.jar
适配
你在用JUL 使用jul-to-slf4j.jar
适配
我在网上盗一张图,给你们一个总体的依赖图(懒得画了)
这就是为了对slf4j的适配作一个例子说明。Spring是用JCL做为日志门面的,那咱们的应用是slf4j + logback,怎么让Spring也用到logback做为日志输出呢?这样的好处就是咱们能够统一项目内的其余模块、框架的日志输出(日志格式,日志文件,存放路径等,以及其余slf4j支持的功能) 很简单,就是加入jcl-over-slf4j.jar
就行了。我又盗了一个图来讲明
其实很简单
你首先确认须要统一日志的模块、框架是使用哪一个日志组件的,而后再找到sfl4j的适配器。
记得去掉无用的日志实现组件,只保留你要用的。
slf4j的日志加载会在程序启动时把日志打出来,因此必定要注意,它会说明加载是否成功,加载了那个日志实现。slf4j已经对错误做了说明官网说明下面讲一下可能常常遇到的问题
没找到日志实现,若是你以为你已经写上了对应的日志实现依赖了,那你要检查一下了,通常来讲极有多是版本不兼容。
找到多个日志实现,slf4j会找其中一个做为日志实现。
阿里对此的代码规范:
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(Abc.class);
文章帮你们梳理了Java日志组件的关系,以及如何解决平常中常见日志相关的问题,但愿对你们帮助。
小编总结了2020面试题,这份面试题的包含的模块分为19个模块,分别是: Java 基础、容器、多线程、反射、对象拷贝、Java Web 、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM 。
关注公众号:程序员白楠楠
架构师必备,带你弄清混乱的JAVA日志体系!10分钟搞定–混乱的 Java 日志体系Java主流日志工具介绍和使用https://www.slf4j.org/