日志分类

这张图非常清晰地展示了日志框架体系,建议收藏

image

日志框架分为两类,日志门面(facade)和日志实现

日志门面

日志门面定义了一组日志的接口规范,它并不提供底层具体的实现逻辑,比如常用的SLF4J(The Simple Logging Facade for Java),以及Apache Commons Logging

日志实现

日志实现则是日志具体的实现,包括日志级别控制、日志打印格式、日志输出形式(输出到数据库、输出到文件、输出到控制台等)。Log4jLog4j2Logback 以及 Java Util Logging 则属于这一类。

SLF4J

使用SLF4J经常会看到这样一行代码

private static final Logger logger = LoggerFactory.getLogger(Object.class);

LoggerSLF4J中的一个接口,这行代码就是通过LoggerFactory去拿SLF4J提供的一个Logger接口的具体实现,比如我们引入了Logback,这里就会拿到的实现类就是Logback

如果引入了Lombok,就可以使用注解@Slf4j替代这行代码

Log4j

log4j1十年前就停止维护了,github地址 ☞https://github.com/apache/logging-log4j1

log4j2log4j1的升级版本,github地址 ☞ https://github.com/apache/logging-log4j2,2021 年 12 月被曝出有漏洞的就是log4j2,漏洞详情,☞https://www.cve.org/CVERecord?id=CVE-2021-44228。

现在一般说Log4j 都是指log4j2

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.1</version>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.1</version>
  </dependency>
</dependencies>

这是使用log4j2要引入的maven依赖,如果log4j-core的版本低于2.15.0(除了2.12.2, 2.12.3, and 2.3.1)就有被黑的风险,就要升级了

Logback

Logback是作为的log4j 1.x项目的继承者,对比log4j 1.x有很大改进

github地址 ☞https://github.com/qos-ch/logback

image-1653041830944

log4j1SLF4JLogback看来都是同一个公司开发的,地址☞https://www.qos.ch/

  • logback-core,logback的核心模块,另外两个模块要依赖这个模块
  • logback-classic,这个模块实现了SLF4J的接口,可以搭配SLF4J使用;这个模块也可以看作是log4j 1.x的重大升级版本
  • logback-access,这个模块与Servlet容器(例如Tomcat和Jetty)集成,以提供HTTP访问日志功能。它是作用在Servlet容器级别上,jar包要放在容器内,不是像logback-classic作用在Web应用级别。☞https://logback.qos.ch/access.html

Spring Boot 中日志实现

创建一个Spring Boot 项目,版本是2.6.2,只有一个依赖spring-boot-starter-web

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>

这是这个项目日志相关的依赖图

image-1653041892468

从依赖图中可以看出,默认引入了logback-core,说明了Spring Boot默认使用的日志框架是logback

这里也引入了log4j-to-slf4j和log4j-api,很多开发者看到这里有log4j,纷纷去给Spring Boot项目提issue害怕log4j的漏洞,Spring Boot的维护者出来解释,这两个包只是从Log4j2apiSLF4J的适配器,是为了方便使用log4j2,但是其实是没有引入log4j-core,所以Spring Boot是安全的

我把log4j-to-slf4j和log4j-api这两个依赖去掉发现项目仍然能够正常启动的

后来我又试了一下在Spring Boot默认依赖下,使用log4j的方式创建Logger,虽然这段代码导入的都是log4j的的包,但是我发现底层还是使用的logback

image-1653041951898

参考

https://logback.qos.ch/

Spring Boot 日志各种使用姿势,是时候捋清楚了!