Java日志体系总结
概要
本文的目的是搞清楚Java中各种日志Log之间是怎么的关系,如何作用、依赖,好让我们平时在工作中如果遇到“日志打不出”或者“日志jar包冲突”等之类的问题知道该如何入手解决,以及在各种场景下如何调整项目中的各个框架的日志输出,使得输出统一。
Log日志体系
在日常工作中我们可能看到项目中依赖的跟日志相关的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
) - 毕竟是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
关系/依赖
大概了解心路历程后,再详细看看它们之间的关系、依赖。
JCL
commons-logging
已经停止更新,最后的状态如下所示:
JCL支持日志组件不多,不过也有很人用的,例如Spring
现在用的也越来越少了,也不多讲了
SLF4J
因为当时Java的日志组件比较混乱繁杂,Ceki Gülcü推出slf4j后,也相应为行业中各个主流日志组件推出了slf4j的适配
图来源于官方文档
图的意思为如果你想用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用上实现组件,即上面说的。
图来源于官方文档
其实总的来说,无论就是以下几种情况
- 你在用JCL
使用jcl-over-slf4j.jar
适配 - 你在用log4j
使用log4j-over-slf4j.jar
适配 - 你在用JUL
使用jul-to-slf4j.jar
适配
我在网上盗一张图,给大家一个整体的依赖图(懒得画了)
让Spring统一输出
这就是为了对slf4j的适配做一个例子说明。
Spring是用JCL作为日志门面的,那我们的应用是slf4j + logback,怎么让Spring也用到logback作为日志输出呢?这样的好处就是我们可以统一项目内的其他模块、框架的日志输出(日志格式,日志文件,存放路径等,以及其他slf4j支持的功能)
很简单,就是加入jcl-over-slf4j.jar
就好了。
我又盗了一个图来说明
适配思路
其实很简单
- 你首先确认需要统一日志的模块、框架是使用哪个日志组件的,然后再找到sfl4j的适配器。
- 记得去掉无用的日志实现组件,只保留你要用的。
常见问题
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日志组件的关系,以及如何解决日常中常见日志相关的问题,希望对大家帮助。
参考资料
架构师必备,带你弄清混乱的JAVA日志体系!
10分钟搞定–混乱的 Java 日志体系
Java主流日志工具介绍和使用
https://www.slf4j.org/
Java日志体系总结相关推荐
- Java日志体系权威总结
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:http://r6d.cn/MSaE 概要 本文的目 ...
- java日志体系分析
写在前面 Java中日志框架种类繁多,我也是最近在学习mybatis过程中对日志的使用产生了困惑,所以这里个人做下总结,希望能帮助到和我有一样困惑的朋友,下面我们就开始吧! 1:java日志的发展历史 ...
- Java日志体系详解
一.日志框架的分类 1.1.门面型日志框架: JCL:Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging ...
- Java日志体系日志门面(Slf4j)日志实现(Log4j、Log4j2)详解
1.背景 近日发生两次因日志使用不当导致的线上问题: 1.应用明明配置了info日志级别,却打印大量的debug日志,导致磁盘IO较高,很快就报磁盘空间不足告警 2.应用服务启动后报StackOver ...
- Java 日志体系详解
欢迎关注方志朋的博客,回复"666"获面试宝典 本文的目的是搞清楚Java中各种日志Log之间是怎么的关系,如何作用.依赖,好让我们平时在工作中如果遇到"日志打不出&qu ...
- java -jar 怎么停止_图解Java日志体系
概要 本文的目的是搞清楚Java中各种日志Log之间是怎么的关系,如何作用.依赖,好让我们平时在工作中如果遇到"日志打不出"或者"日志jar包冲突"等之类的问题 ...
- 工作这么多年,很多人竟然还搞不清Java日志体系!
概要 本文的目的是搞清楚Java中各种日志Log之间是怎么的关系,如何作用.依赖,好让我们平时在工作中如果遇到"日志打不出"或者"日志jar包冲突"等之类的问题 ...
- 深入掌握Java日志体系,再也不迷路了
点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章.本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 对于一个应用程序来说日志记录是必 ...
- java日志体系(SLF4J,JCL)
平时我们引用日志包打印日志时发现和我们预料中的不一致,最常见的就是明明配置了但确不打印日志,所以我简单总结了下java的日志体系. 一.我们日前常用的日志有log4j,log4j2,logback,j ...
最新文章
- Unity3D 关于声音MissingComponentException报错
- TabLayout和ViewPager
- verilog仿真——$test$plusargs 和 $value$plusargs
- html5干货,干货:详解HTML5中常见的五大全局属性
- JAVA实现AES 解密报错Input length must be multiple of 16 when decrypting with padded cipher
- strtoupper 小写_PHP strtoupper()函数与示例
- python中msg函数_Python 中闭包函数和装饰器
- 代码刚提交暂存区,组长突然要我把新增代码 Commit另一分支怎么办?
- HDU 5136 Yue Fei's Battle
- 写一个函数,输入一个十六进制,输出相应的十进制数。
- linux内核mtd驱动程序与sd卡驱动程序,Linux内核MTD驱动程序与SD卡驱动程序(2)
- MSagent 学习笔记
- 人工智能知识全面讲解:最简单的神经元模型
- AUTOSAR 基础软件的内在安全
- 四、快速搭建一套现代化的个人独立博客系统,给爱写博客的你(part2 正文)
- mui 悬浮窗口实现
- 高中数学立体几何高考真题解题技巧(名师总结)
- 4天上线“战疫”小程序,腾讯敏捷在数字广东的落地实践
- Python学习笔记1环境搭建+Numpy
- 国医大师王绵之:汤药煎服经验谈
热门文章
- QIIME 2教程. 25可用和开发中插件AvailableFuturePlugins(2020.11)
- 生信宝典文章集锦,你想看的都在
- R语言ggplot2可视化:通过在element_text函数中设置ifelse判断条件自定义标签文本的显示格式:例如、粗体、斜体等
- python使用matplotlib可视化使用subplots子图、subplots绘制子图并为可视化的子图添加主标题(subplots main title)
- R语言ggplot2可视化:通过水平半小提琴图和抖动数据点可视化雨云图(Rain Cloud plots)、自定义雨云图中数据点的颜色(数据点的颜色和半小提琴图一致)
- R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:使用na_if()函数将0值替换为NA值、负收入替换为NA值
- R语言ggplot2可视化移除多余的图例信息实战
- python实现迭代的快速排序(Iterative Quick Sort)
- php中htpt,PHP中的HTTP协议
- Linux目录是否是否为空,在Linux上使用C检查目录是否为空