日志框架选型、依赖关系梳理
在刚接触日志框架的初期一定是迷茫的,项目代码里千奇百怪的日志打印方法,接口来自各种各样的jar包,所以在此梳理一下依赖关系,也给自己解惑。
一、门面日志
Facade门面,更底层一点说就是接口。它允许用户以自己的喜好,在项目中有不同的实现,白话的意思就是门面框架定义通用接口,实现类取决于你引入哪种实现(logback或者log4j,log4j2)。
- commons-logging,Apache出品的门面日志框架,现在不再使用,了解即可。
- Slf4j ,英文全称为“Simple Logging Facade for Java”,为java提供的简单日志Facade
使用门面框架是为了解耦,如果你的项目想更换底层实现,替换jar包即可,无需手动修改代码。
二、依赖关系
使用slf4j需要首先导入「slf4j-api.jar」, (springboot parent已经依赖)
和log4j配合,需要导入「log4j.jar」,以及桥接包「slf4j-log412.jar」。
log4j2配合需要导入log4j2的「log4j-api.jar」、「log4j-core.jar」和桥接包「log4j-slf4j-impl.jar」。
logback只需要导入「logback-classic.jar」和「logback-core.jar」即可(springboot parent已经依赖),不需要桥接包。
三、日志加载原理
slf4j从LoggerFactory.getLogger()开始,到底干了什么
原理就是就是让ClassLoader从classpath(依赖的jar)中找到「StaticLoggerBinder」这个类,然后利用他来返回log4j、logback中的Logger,然后打印日志。
所谓的桥接包,就是实现StaticLoggerBinder类,用来连接slf4j和日志框架。因为log4j和log4j2刚开始没有StaticLoggerBinder这个类,为了不改变程序结构,只能重新写一个新的jar来实现StaticLoggerBinder。而logback出现slf4j之后,于是在logback本身的jar中实现了StaticLoggerBinder,所以就不需要桥接包。
框架选型
- 在比较关注性能的地方,选择Logback或自己实现高性能Logging API可能更合适。推荐:
slf4j + logback
. - 在已经使用了Log4j的项目中,如果没有发现问题,继续使用可能是更合适的方式:推荐组合为:
slf4j + log4j2
在性能测试上,log4j2性能略高于logback。提高性能的一点可以从异步写入入手,唯一缺点是当写队列满的时候会丢弃DEBUG,INFO级别的日志(可配置)。
注意问题:Class path contains multiple SLF4J bindings
原因是在项目中找到了多个日志实现,即logback与log4j或log4j2不能共存,否则无法确定实现类,使用 maven hepler排除掉不需要的即可。
内容来自以下文章: