日志系统的发展
我们日常接触到的日志系统有很多种,log4j,JUL(jdk 自带),logback 等,我们可以直接根据对象的日志 API 进行使用。但是考虑到 API 各不相同,所以出现了 JCL(Jakarta Commons Logging)、slf4j 等日志 API 框架。日志 API 框架只是统一的 API,其底层的具体的日志记录工作还是由 log4j、JUL、logback 等承担。
如何选择和搭配日志系统
目前来说,新应用使用 logback 是首选,一些老系统中很可能使用的是 log4j 等。目前 slf4j 对 logback 和 log4j 都支持,对 JCL 也提供了桥接方法,将 JCL 的 api 转化 slf4j 的 API。贴一张 Webx 中的图足以说明一切
组装日志系统
由于存在 JCL,SLF4j 两大日志框架,logback、log4j、JUL 日志系统所以理论上有这么多种日志系统的搭配。
JUL
log4j
logback
jcl+log4j
slf4j+slf4j-log4j12+log4j
slf4j+logback
jcl-over-slf4j+slf4j+logback
jcl-over-slf4j+slf4j+slf4j-log4j12+log4j
其中 slf4j+slf4j-log4j12+log4j、slf4j+logback 是主流,推荐使用。
多种日志工具共存时的解决方案
当依赖了一些三方库时,可能会出现多种日志共存的问题,无法保证每种日志抽象库都使用一样的实现类,此时需要制定固定的日志库。主流的日志库都提供了扩展方式
JUL(java.util.logging)
通过 LogManager.getLogManager().getLogger(“”).addHandler() 方法,可以添加日志具体实现 LogManager.getLogManager().getLogger(“”).addHandler(new SLF4JBridgeHandler()); 继承 java.util.logging.Handler 类,在实现中使用具体的 Logger 库即可实现例子:jul-to-slf4j(https://www.slf4j.org/api/org…)
JCL(org.apache.commons.logging)j
通过制定环境变量 LogFactory,org.apache.commons.logging.LogFactorySystem.setProperty(“org.apache.commons.logging.LogFactory”,”com.answern.claimv2.framework.log.LogFactoryImplAdapter”); 继承 org.apache.commons.logging.LogFactory 类,实现自己的 LogFactory 即可还有另外一种暴力的方式:不引入 commons-logging 包,而是创建 jcl 的一些同名类,在实现中直接使用具体的日志库。jcl-over-slf4j(https://mvnrepository.com/art…)就是一个典型的例子. 相同功能的还有 spring-jcl(https://mvnrepository.com/art…)
log4j
log4j 提供了 java 对原生 spi 机制的支持建立 MEATA-INF/services/org.apache.logging.log4j.spi.Provider 文件继承 org.apache.logging.log4j.spi.Provider 类,实现自己的 LoggerContextFactory 即可实现例子:log4j-to-slf4j(https://logging.apache.org/lo…)
SLFJ4J
slf4j 官方介绍了使用方式,通过引入不同的 jar 包来使用具体的日志库。由于 slf4j 拆分做的很好,当多种日志库共存时,若不引入 slf4j-xxx.jar 时,不会加载相应的日志库。所以若日志冲突时,使用 slf4j 的三方库只需要 include/exclude 相应的实现库即可。
编写自己的框架 / 类库时该如何选择日志库
由于日志库多种多样,如果盲目引入 jcl 或者 slf4j 时,可能会对具体使用的项目造成影响。所以最合适的方式是内嵌一套日志抽象,内部动态的去选择加载哪个日志库。主流的成熟框架都会这么做,尽可能的保持兼容性。
例如 spring/mybatis/freemarker/dubbo 这些框架,都有一套内嵌的日志抽象,打印日志时只需要调用内嵌的日志即可做到全兼容。
参考
https://www.jianshu.com/p/54c…
https://www.slf4j.org/