java日志框架

8次阅读

共计 2544 个字符,预计需要花费 7 分钟才能阅读完成。

一、Java 日志概述
java 领域存在多种日志框架,目前常用的日志框架包括 Log4j 1,Log4j 2,Commons Logging,Slf4j,Logback,Jul。

Commons Logging 和 Slf4j 是日志门面 (门面模式是软件工程中常用的一种软件设计模式,也被称为正面模式、外观模式。它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用)。Log4j 和 Logback 则是具体的日志实现方案。可以简单的理解为接口与接口的实现,调用者只需要关注接口而无需关注具体的实现,做到解耦。
Commons Logging Apache 基金会所属的项目,是一套 Java 日志接口,之前叫 Jakarta Commons Logging,后更名为 Commons Logging。
Slf4j 类似于 Commons Logging,是一套简易 Java 日志门面,本身并无日志的实现。(Simple Logging Facade for Java,缩写 Slf4j)。
Logback 一套日志组件的实现 (Slf4j 阵营)。
Logback 必须配合 Slf4j 使用。由于 Logback 和 Slf4j 是同一个作者,其兼容性不言而喻。
比较常用的组合使用方式是 Slf4j 与 Logback 组合使用,Commons Logging 与 Log4j 组合使用。
Log4j Apache Log4j 是一个基于 Java 的日志记录工具。它是由 Ceki Gülcü首创的,现在则是 Apache 软件基金会的一个项目。Log4j 是几种 Java 日志框架之一。
Log4j 2 Apache Log4j 2 是 apache 开发的一款 Log4j 的升级产品。
Log4j 2 与 Log4j 1 发生了很大的变化,Log4j 2 不兼容 Log4j 1。
Jul (Java Util Logging), 自 Java1.4 以来的官方日志实现。

二、Commons Logging 与 Slf4j 实现机制对比
Commons Logging 是通过动态查找机制,在程序运行时,使用自己的 ClassLoader 寻找和载入本地具体的实现。详细策略可以查看 commons-logging-*.jar 包中的 org.apache.commons.logging.impl.LogFactoryImpl.java 文件。由于 Osgi 不同的插件使用独立的 ClassLoader,Osgi 的这种机制保证了插件互相独立, 其机制限制了 Commons Logging 在 Osgi 中的正常使用。Slf4j 在编译期间,静态绑定本地的 Log 库,因此可以在 Osgi 中正常使用。它是通过查找类路径下 org.slf4j.impl.StaticLoggerBinder,然后在 StaticLoggerBinder 中进行绑定。
如果是在一个新的项目中建议使用 Slf4j 与 Logback 组合,这样有如下的几个优点:

Slf4j 实现机制决定 Slf4j 限制较少,使用范围更广。由于 Slf4j 在编译期间,静态绑定本地的 LOG 库使得通用性要比 Commons Logging 要好。
Logback 拥有更好的性能。
Commons Logging 开销更高

三、Slf4j 与其他日志组件调用关系

jar 包名
说明

slf4j-log4j12-1.7.13.jar
Log4j1.2 版本的桥接器,你需要将 Log4j.jar 加入 Classpath。

slf4j-jdk14-1.7.13.jar
java.util.logging 的桥接器,Jdk 原生日志框架。

slf4j-nop-1.7.13.jar
NOP 桥接器,默默丢弃一切日志。

slf4j-simple-1.7.13.jar
一个简单实现的桥接器,该实现输出所有事件到 System.err. 只有 Info 以及高于该级别的消息被打印,在小型应用中它也许是有用的。

slf4j-jcl-1.7.13.jar
Jakarta Commons Logging 的桥接器. 这个桥接器将 Slf4j 所有日志委派给 Jcl。

logback-classic-1.0.13.jar(requires logback-core-1.0.13.jar)
Slf4j 的原生实现,Logback 直接实现了 Slf4j 的接口,因此使用 Slf4j 与 Logback 的结合使用也意味更小的内存与计算开销。

四、使用 Slf4j 时如何桥接遗留的 api
当我们在同一项目中使用不同的组件时应该如果解决不同组件依赖的日志组件不一致的情况呢?现在我们需要统一日志方案,统一使用 Slf4j,把他们的日志输出重定向到 Slf4j,然后 Slf4j 又会根据绑定器把日志交给具体的日志实现工具。Slf4j 带有几个桥接模块,可以重定向 Log4j,JCL 和 java.util.logging 中的 Api 到 Slf4j。

jar 包名
作用

log4j-over-slf4j-version.jar
将 Log4j 重定向到 Slf4j

jcl-over-slf4j-version.jar
将 Commons Logging 里的 Simple Logger 重定向到 slf4j

jul-to-slf4j-version.jar
将 Java Util Logging 重定向到 Slf4j

在使用 Slf4j 桥接时要注意避免形成死循环,在项目依赖的 jar 包中不要存在以下情况:

多个日志 jar 包形成死循环的条件
产生原因

log4j-over-slf4j.jar 和 slf4j-log4j12.jar 同时存在
由于 slf4j-log4j12.jar 的存在会将所有日志调用委托给 log4j。但由于同时由于 log4j-over-slf4j.jar 的存在,会将所有对 log4j api 的调用委托给相应等值的 slf4j, 所以 log4j-over-slf4j.jar 和 slf4j-log4j12.jar 同时存在会形成死循环

jul-to-slf4j.jar 和 slf4j-jdk14.jar 同时存在
由于 slf4j-jdk14.jar 的存在会将所有日志调用委托给 jdk 的 log。但由于同时 jul-to-slf4j.jar 的存在,会将所有对 jul api 的调用委托给相应等值的 slf4j,所以 jul-to-slf4j.jar 和 slf4j-jdk14.jar 同时存在会形成死循环

参考
https://www.cnblogs.com/chenh…

正文完
 0