一、概述
对于一个web项目来说,日志框架是必不可少的,日志的记录可以帮助我们在开发以及维护过程中快速的定位错误。slf4j
,log4j
,logback
,JDK Logging
等这些日志框架都是我们常见的日志框架,本文主要介绍这些常见的日志框架关系和SpringBoot整合Sfl4j+logback的实践。
二、日志系统介绍
1.日志系统介绍
首先slf4j
可以理解为规则的制定者,是一个抽象层,定义了日志相关的接口。log4j
,logback
,JDK Logging
都是slf4j
的实现层,只是出处不同,当然使用起来也就各有千秋。
2.为什么使用Sfl4j+logback?
slf4j
+logback
是这些组合中最常见的日志搭配。总结起来起核心的优势有:(1)使用slf4j
+logback
的性能更高;(2)slf4j
和logback
框架的作者是同一个,所以兼容性更好。
三、SpringBoot整合Sfl4j+logback的实践
网上很多教程说明配置Sfl4j+logback时,都会要求引入logback-classic等依赖,这在使用Spring框架的时候确实是必须的,但在使用Springboot框架是没必须的,因为在spring-boot-starter中已经整合了Sfl4j+logback日志系统。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
1.添加logback-spring.xml配置文件
以下是一个logback-spring.xm的常见配置,我们以以下这个模板来说明其中配置项的含义。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 一般根节点不需要写属性了,使用默认的就好 -->
<configuration>
<contextName>demo</contextName>
<!-- 该变量代表日志文件存放的目录名 -->
<property name="log.dir" value="logs"/>
<!-- 该变量代表日志文件名 -->
<property name="log.appname" value="eran"/>
<!--定义一个将日志输出到控制台的appender,名称为STDOUT -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 内容待定 -->
</appender>
<!--定义一个将日志输出到文件的appender,名称为FILE_LOG -->
<appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">
<!-- 内容待定 -->
</appender>
<!-- 指定com.demo包下的日志打印级别为INFO,但是由于没有引用appender,所以该logger不会打印日志信息,日志信息向上传递 -->
<logger name="com.demo" level="INFO"/>
<!-- 指定最基础的日志输出级别为DEBUG,并且绑定了名为STDOUT的appender,表示将日志信息输出到控制台 -->
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
1.标签
定义日志策略的节点,一个日志策略对应一个<appender>
,一个配置文件中可以有零个或者多该节点,但一个配置文件如果没有定义至少一个<appender>
,虽然程序不会报错,但就不会有任何的日志信息输出,也失去了意义。该节点有两个必要的属性:
- name:指定该节点的名称,方便之后的引用。
- class:指定该节点的全限定名,所谓的全限定名就是定义该节点为哪种类型的日志策略,比如我们需要将日志输出到控制台,就需要指定class的值为ch.qos.logback.core.ConsoleAppender;需要将日志输出到文件,则class的值为ch.qos.logback.core.FileAppender等。
2.标签
用来设置某个包或者类的日志打印级别,并且可以引用绑定日志策略,在该节点内可以添加子节点<appender-ref>
,该节点有一个必填的属性ref
,值为我们定义的<appender>
节点的name
属性的值。该节点有三个属性:
- name:用来指定受此约束的包或者类。
- level:可选属性,用来指定日志的输出级别,如果不设置,那么当前会继承上级的级别。
- additivity:是否向上级传递输出信息,两个可选值true or false,默认为true。
3.标签
- 根
<logger>
一个特殊的<logger>
,即默认name
属性为root
的<logger>
,因为是根<logger>
,所以不存在向上传递一说,故没有additivity
属性,所以该节点只有一个level
属性。
常见的配置如下:
<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
异步写入日志AsyncAppender
。AsyncAppender并不处理日志,只是将日志缓冲到一个BlockingQueue里面去,并在内部创建一个工作线程从队列头部获取日志,之后将获取的日志循环记录到附加的其他appender上去,从而达到不阻塞主线程的效果。因此AsynAppender仅仅充当事件转发器,必须引用另一个appender来写日志。常见的配置如下:
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold >0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref ="FILE_LOG"/>
</appender>
2.代码中添加日志逻辑
添加好logback-spring.xml配置文件后,就可以在代码中添加日志逻辑,添加也很简单,只需要通过log.info()这样的方式来实现。
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class TestController01 {
@RequestMapping("/hello")
public String index() {
log.debug("hello world0.");
log.info("hello world.");
log.warn("hello world1.");
log.error("hello world2.");
return "Hello World.";
}
}
Slf4j有四个级别的log level可供选择,级别从上到下由低到高,优先级高的将被打印出来。
- debug:简单来说,对程序调试有利的信息都可以debug输出
- info:对用户有用的信息
- warn:可能会导致错误的信息
- error:顾名思义,发生错误的地方
为了简化创建logger对象的逻辑,可以直接使用lombok的@Slf4j的注解,只需要在pom文件中引入以下依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
具体代码实现和配置文件:https://github.com/yangnk/SpringBoot_Learning/tree/master/SpringbootLogDemo
四、其他
推荐一个IDEA中日志查看插件:Grep Console。这是一个帮你分析控制台日志的插件,可以对不同级别的日志进行不同颜色的高亮显示,具体效果如下:
参考资料
- slf4j官网:https://www.slf4j.org/manual.html
- 一步一步带你熟悉SpringBoot 配置slf4j+logback:https://blog.csdn.net/weixin_49307478/article/details/126836019
- SpringBoot整合logback,slf4j:https://blog.csdn.net/weixin_42259925/article/details/103954982