讲老实话,JAVA 的日志江湖还真的是蛮乱的。
1996 年:远古形态
官方的远古形态,很久以前,我们会使用很粗暴的形式打印日志:
- System.out
- System.err
- Exception.printStackTrace
但是这种操作不能回味呀,想留个痕,不好意思,门都没有。
在 1996 年初,E.U.SEMPER(欧洲安全电子市场)项目决定编写自己的跟踪API,最后该 API 演变为Log4j。
1999 年:Log4j 出世
Apache 发布了 Log4J 的第一个版本。这是一个 Java 第一个基于角色模型的日志框架。Log4j 日志软件包一经推出就备受欢迎,当然这里必须要提到一个人,就是 Log4j 的主要贡献者,Ceki Gülcü
后来 Log4j 成为了 Apache 基金会项目中的一员,同时 Log4j 的火爆,让 Log4j 一度成为业内日志标杆。(据说 Apache 基金会还曾经建议 Sun 引入 Log4j 到 java 的标准库中,但是 sun 拒绝了)。
2002 年:JUL 和 JCL 粉墨登场
JUL: Java Util Logging 出世
Log4J 的诞生,迅速一统 JAVA 的日志江湖。这着实让 sun 感受到了压力。于是比葫芦画瓢,从 1.4 开始,也搞了个 Java Util Logging,并把其加到 Java API 中,这个时候,已经是 2002年,已经 6 年过去了。
但是天不遂人愿,老大的品味有些特别,内力太低,还是干不过 Log4J,无奈以烂尾收场。
JCL: Apache Common Logging
sun 想一统日志的江湖美梦破灭了,但终究有些人还是站 sun 的队。有些库使用了 JUL,有些库使用了 Log4J,因为配置不同,恭喜你,要搞两套配置。
为了和气生财,2002 年 8 月, Apache Common Logging 出世了,这个就是我们所熟知的 JCL(其内部也有对应简单的日志实现),支持运行时动态加载日志组件的实现,这野心很大,想一统日志抽象(就像以前的JDBC 一统数据库访问层),让日志产品去实现它的抽象,这样只要你的日志代码依赖的是 JCL 的接口,你就可以很方便的在 Log4j 和 JUL 之间做切换,也就是说,在你应用代码里,只需调用 JCL 的接口,底层实现可以是 Log4j,也可以是 Java Util Logging。
2005 年:SLF4J 联合 Logback 降维打击
Log4J 失了宠,能力不行,愁人, 同时 Ceki 不适应 Apache 的工作方式,离开了 Apache。
因为 JCL 又有接口,又有实现,遂抛弃,Ceki 在重新制定了一幅新的蓝图,SLF4J(Simple Logging Facade For Java)(日志门面接口,类似于 Commons Logging)。
但是由于 Slf4j 出来的较晚,而且还只是一个日志接口,所以之前已经出现的日志产品,如 JUL 和 Log4j 都是没有实现这个接口的,所以尴尬的是光有一个接口,没有实现的产品也是很憋屈啊,就算开发者想用Slf4j也是用不了,这时候,大佬做了两件事,震动江湖
- 创建对应的实现
Logback(Slf4j的实现)。 - 提供适配其他日志实现的桥接器
牛逼克拉斯
Ceki 回瑞典之后,创建了 QOS 公司,QOS 官网上是这样描述 Logback 的:The Generic,Reliable Fast&Flexible Logging Framework (一个通用,可靠,快速且灵活的日志框架)。
然后 Java 日志领域开始划分为两大阵营:JCL 和 SLF4J。
2012 年:Apache 的二胎计划
Apache 眼看 Log4j 有被 Logback 反超的势头,于 2012-07 重写了 Log4j 1.x,成立了新的项目 Log4j 2, Log4j 2 具有 Logback 的所有特性。
但是 Log4j 2 不是 Log4j1.x 升级,而是新项目 Log4j 2 ,因为Log4j 2是完全不兼容Log4j1.x。
并且很微妙的,Log4j 2几乎涵盖Logback所有的特性(这不是对着干是啥~而且还有抄袭的嫌疑。。。哈哈哈),更甚者的Log4j 2也搞了分离的设计,分化成log4j-api 和 log4j-core,这个 log4j-api 也是日志接口,log4j-core才是日志实现。
有点崩溃了
现在我们可有了 3 个日志接口,以及 4 个日志实现。当然 Apache 也知道该做啥,为了让大家可以接入自己的 Log4j2,不就是桥的事么,Apache 也麻溜的推出了它的桥接包,乱。
2013 年:门面的统一
JCL 在 Apache 大树的笼罩下,有很大的用户基数。但有证据表明,形式正在发生变化。2013 年底有人分析了 GitHub 上 30000 个项目,统计出了最流行的 100 个 Libraries,可以看出 Slf4j 的发展趋势更好。
SLF4J 基本上是当今 Java 日志的既成事实的标准。所以,大家看到了不管是 Spark、Flink、Hadoop、Hive 等等框架,都是基于 SLF4J 来使用日志的。
SLF4J 和 JCL 不一样,可以看到 JCL 中对其他日志框架的支持,都是静态加载 JAR 包的。而 SLF4J 使用了 Java Service Loader 机制,可以在运行时,在 CLASSPATH 使用日志实现框架。我们可以把它理解为是 JCL 的一个更高级的升级版本。在编译时,我们仅需依赖 SLF4J,而在运行时使用任何类型的日志库。
参考资料: