Java 日志体系详解 秒速五厘米 2022-09-17 05:13 123阅读 0赞 ## 概要 ## 本文的目的是搞清楚Java中各种日志Log之间是怎么的关系,如何作用、依赖,好让我们平时在工作中如果遇到“日志打不出”或者“日志jar包冲突”等之类的问题知道该如何入手解决,以及在各种场景下如何调整项目中的各个框架的日志输出,使得输出统一。 ## Log日志体系 ## 在日常工作中我们可能看到项目中依赖的跟日志相关的jar包有很多,`commons-logging.jar`、`log4j.jar`、`sl4j-api.jar`、`logback.jar`等等,眼花缭乱。我们要正确的配置,使得jar包相互作用生效之前,就先要理清它们之间的关系。 ### 背景/发展史 ### 那就要从Java Log的发展历程开始说起。 1. `log4j`(作者Ceki Gülcü)出来时就等到了广泛的应用(注意这里是直接使用),是Java日志事实上的标准,并成为了Apache的项目 2. Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增加了`JUL`(`java.util.logging`) 3. 毕竟是JDK自带的,JUL也有很多人用。同时还有其他日志组件,如SimpleLog等。这时如果有人想换成其他日志组件,如log4j换成JUL,因为api完全不同,就需要改动代码。 4. Apache见此,开发了`JCL`(Jakarta Commons Logging),即`commons-logging-xx.jar`。它只提供一套通用的日志接口api,并不提供日志的实现。很好的设计原则嘛,依赖抽象而非实现。这样应用程序可以在运行时选择自己想要的日志实现组件。 5. 这样看上去也挺美好的,但是log4j的作者觉得JCL不好用,自己开发出`slf4j`,它跟JCL类似,本身不提供日志具体实现,只对外提供接口或门面。目的就是为了替代JCL。同时,还开发出`logback`,一个比log4j拥有更高性能的组件,目的是为了替代log4j。 6. Apache参考了logback,并做了一系列优化,推出了`log4j2` ### 关系/依赖 ### 大概了解心路历程后,再详细看看它们之间的关系、依赖。 #### JCL #### `commons-logging`已经停止更新,最后的状态如下所示: ![48de56721360110367abe1775dac4e37.png][] JCL支持日志组件不多,不过也有很人用的,例如Spring 现在用的也越来越少了,也不多讲了 #### SLF4J #### 因为当时Java的日志组件比较混乱繁杂,Ceki Gülcü推出slf4j后,也相应为行业中各个主流日志组件推出了slf4j的适配 图来源于官方文档 ![4ea12542bbe15b4e0ab2fb055ec40cb6.png][] 图的意思为如果你想用slf4j作为日志门面的话,你如何去配合使用其他日志实现组件,这里说明一下(注意jar包名缺少了版本号,在找版本时也要注意版本之间是否兼容) * slf4j + logback `slf4j-api.jar` \+ `logback-classic.jar` \+ `logback-core.jar` * slf4j + log4j `slf4j-api.jar` \+ `slf4j-log4j12.jar` \+ `log4j.jar` * slf4j + jul `slf4j-api.jar` \+ `slf4j-jdk14.jar` * 也可以只用slf4j无日志实现 `slf4j-api.jar` \+ `slf4j-nop.jar` ### SLF4J的适配 ### slf4j支持各种适配,无论你现在是用哪种日志组件,你都可以通过slf4j的适配器来使用上slf4j。 只要你切换到了slf4j,那么再通过slf4j用上实现组件,即上面说的。 图来源于官方文档 ![4078dedaea381b4f9d63252b3fb2076a.png][] 其实总的来说,无非就是以下几种情况 * JCL --> `jcl-over-slf4j.jar`适配 * log4j -->`log4j-over-slf4j.jar`适配 * JUL-->`jul-to-slf4j.jar`适配 ![cd930af3b89103c670dbbe09a028c1b3.png][] Spring统一输出 这就是为了对slf4j的适配做一个例子说明。 Spring是用JCL作为日志门面的,那我们的应用是slf4j + logback,怎么让Spring也用到logback作为日志输出呢?这样的好处就是我们可以统一项目内的其他模块、框架的日志输出(日志格式,日志文件,存放路径等,以及其他slf4j支持的功能) 很简单,就是加入`jcl-over-slf4j.jar`就好了。 ![589dbaa5a8c5d57fc01117e5f6f127a9.png][] #### 适配思路 #### 其实很简单 1. 你首先确认需要统一日志的模块、框架是使用哪个日志组件的,然后再找到sfl4j的适配器。 2. 记得去掉无用的日志实现组件,只保留你要用的。 ## 常见问题 ## slf4j的日志加载会在程序启动时把日志打出来,所以一定要注意,它会说明加载是否成功,加载了那个日志实现。 slf4j已经对错误作了说明官网说明 下面讲一下可能经常遇到的问题 ### Failed to load class org.slf4j.impl.StaticLoggerBinder ### 没找到日志实现,如果你觉得你已经写上了对应的日志实现依赖了,那你要检查一下了,一般来说极有可能是版本不兼容。 ### Multiple bindings ### 找到多个日志实现,slf4j会找其中一个作为日志实现。 ## 代码规范 ## 阿里对此的代码规范: > 【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。 > import org.slf4j.Logger; > import org.slf4j.LoggerFactory; > private static final Logger logger = LoggerFactory.getLogger(Abc.class); ## 总结 ## 文章帮大家梳理了Java日志组件的关系,以及如何解决日常中常见日志相关的问题,希望对大家帮助。 source: //albenw.github.io/posts/854fc091 ![a985075e108319939cb5752c0107afe1.png][] 最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式:关注公众号并回复 java 领取,更多内容陆续奉上。 **明天见(。・ω・。)ノ♡** [48de56721360110367abe1775dac4e37.png]: /images/20220828/3104c03d073c41bdb7d8f4c1ede8b001.png [4ea12542bbe15b4e0ab2fb055ec40cb6.png]: /images/20220828/38fb27e3a9a948ce9e8fd5e97d031bc8.png [4078dedaea381b4f9d63252b3fb2076a.png]: /images/20220828/c596a8c8a8fb49a2878ac3060d76a665.png [cd930af3b89103c670dbbe09a028c1b3.png]: /images/20220828/3c74d0fa22db4a9797ec7ed0cc0d5fa6.png [589dbaa5a8c5d57fc01117e5f6f127a9.png]: /images/20220828/1bfd0f560a32459b8a4ae9658c4a8763.png [a985075e108319939cb5752c0107afe1.png]: /images/20220828/2c5b9dc201a84a72ae6dc70dbd50a920.png
还没有评论,来说两句吧...