一、写在前面
首先,推荐一篇优秀的介绍slf4j的优秀文章 https://juejin.im/post/5c7e2445f265da2de71370f2
springboot的默认日志依赖为slf4j+logback,本文也是主要讲slf4j+logback
本文的特点是会举很多通俗易懂的例子,让大家通过例子来学习使用slf4j。
二、什么是slf4j
2.1 什么是slf4j
刚刚接触slf4j,对这个名词的全称惊到了,Simple Logging Facade for Java,简称SLF4J。翻译为 简单的日志Facade对于java,就是说明这个日志依赖是为java而生的。
2.2 slf4j、logback和log4j的关系
相信很多人听说过slf4j,log4j,logback,JDK Logging等跟日志框架有关的词语,所以这里也简单介绍下他们之间的关系。
首先slf4j可以理解为规则的制定者,是一个抽象层,定义了日志相关的接口。
log4j,logback,JDK Logging都是slf4j的实现层,只是出处不同,当然使用起来也就各有千秋,这里放一张网上的图更明了的解释了他们之间的关系:
可以看到logback是直接实现的slf4j,而其他的中间还有一个适配层,至于原因也很简单,因为logback和slf4j的作者是一个人。
2.3 在springboot中使用slf4j+logback日志框架
在Spring boot使用是非常方便的,不需要我们有什么额外的配置,因为Spring boot默认支持的就是slf4j+logback的日志框架,想要灵活的定制日志策略,只需要我们在src/main/resources下添加配置文件即可,只是默认情况下配置文件的命名需要符合以下规则:
logback.xml
logback-spring.xml
其中logback-spring.xml是官方推荐的,并且只有使用这种命名规则,才可以配置不同环境使用不同的日志策略这一功能。
三、直接面对案例,建议各位同学跟我一起练
随便建一个springboot项目,以下6个案例每个案例一个配置哦
3.1、通过springboot的默认配置,对log进行自定义输出
注: Springboot默认日志格式
时间日期 -> 日志级别 -> 线程ID -> 分隔符 -> 线程名 -> Logger名(通常对应的是类名) -> 日志内容
1 输出到程序的同一个目录下 log/log-can.log
2 自定义日志格式
3 日志水平的level=info
4 日志大小为10m
logging.file=log/log-can.log
logging.level.root=info
logging.file.max-size=20MB
logging.pattern.console=%boldRed(%d{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %boldCyan(%msg%n)
logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
3.2、根据不同的日志等级打印不同的颜色
创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置
<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
<configuration scan="true" scanPeriod="10 seconds">
<!--设置重要-->
<property name="CONSOLE_LOG_PATTERN"
value="%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
3.3、日志持久化到本地
创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<property name="log.path" value="log" />
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
</encoder>
</appender>
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/log-can.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
</configuration>
3.4 异步日志持久化到本地
创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<property name="log.path" value="log" />
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
</encoder>
</appender>
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/log-can.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</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"/>
</appender>
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="ASYNC" />
</root>
</configuration>
3.5 异步日志持久化到本地,按时间滚动产生日志文件
创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<property name="log.path" value="log" />
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
</encoder>
</appender>
<!-- 按时间滚动产生日志文件 -->
<appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/log-can.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 只保留近七天的日志 -->
<maxHistory>7</maxHistory>
<!-- 用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</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 ="ROL-FILE-LOG"/>
</appender>
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="ASYNC" />
</root>
</configuration>
3.6 异步日志持久化到本地,按时间和文件大小滚动产生日志文件
并且会随着spring.profiles.active=dev的变化,dev时打印到控制台,prod时数据持久化到本地
创建一个 logback-spring.xml,放置到src/main/resources下,不需要另外配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<property name="log.path" value="log" />
<!--输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
</encoder>
</appender>
<!-- 按时间和文件大小滚动产生日志文件 -->
<appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/log-can.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 单个文件的最大内存 -->
<maxFileSize>100MB</maxFileSize>
<!-- 只保留近七天的日志 -->
<maxHistory>7</maxHistory>
<!-- 用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志 -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!-- 只处理INFO级别以及之上的日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</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 ="ROL-SIZE-FILE-LOG"/>
</appender>
<!-- 指定开发环境基础的日志输出级别为DEBUG,并且绑定了名为STDOUT的appender,表示将日志信息输出到控制台 -->
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</springProfile>
<!-- 指定生产环境基础的日志输出级别为INFO,并且绑定了名为ASYNC的appender,表示将日志信息异步输出到文件 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="ASYNC" />
</root>
</springProfile>
</configuration>
四、logback-spring.xml说明
使用slf4j+logback在application.yml可以不进行任何配置,直接在src/main/resources添加logback-spring.xml
4.1 < configuration >:根节点,有三个属性
- scan:当配置文件发生修改时,是否重新加载该配置文件,两个可选值true or false,默认为true。
- scanPeriod:检测配置文件是否修改的时间周期,当没有给出时间单位时默认单位为毫秒,默认值为一分钟,需要注意的是这个属性只有在scan属性值为true时才生效。
- debug:是否打印loback内部日志信息,两个可选值true or false,默认为false。
4.2 < appender >:定义日志策略的节点
< appender >:定义日志策略的节点,一个日志策略对应一个,一个配置文件中可以有零个或者多该节点,但一个配置文件如果没有定义至少一个,虽然程序不会报错,但就不会有任何的日志信息输出,也失去了意义,该节点有两个必要的属性:
- name:指定该节点的名称,方便之后的引用。
- class:指定该节点的全限定名,所谓的全限定名就是定义该节点为哪种类型的日志策略
- 我们需要将日志输出到控制台,就需要指定class的值为:ch.qos.logback.core.ConsoleAppender
- 需要将日志输出到文件,则class的值为: ch.qos.logback.core.FileAppender等
4.3 < logger >:用来设置某个包或者类的日志打印级别
< logger >:用来设置某个包或者类的日志打印级别,并且可以引用绑定日志策略,有三个属性:
- name:用来指定受此约束的包或者类。
- level:可选属性,用来指定日志的输出级别,如果不设置,那么当前会继承上级的级别。
- additivity:是否向上级传递输出信息,两个可选值true or false,默认为true。
在该节点内可以添加子节点,该节点有一个必填的属性ref,值为我们定义的节点的name属性的值。
4.4 < root >:根< logger >一个特殊的< logger >
< root >:根< logger >一个特殊的< logger >,即默认name属性为root的< logger >,因为是根< logger >,所以不存在向上传递一说,故没有additivity属性,所以该节点只有一个level属性。
介绍了根节点的三个主要的子节点,下面再介绍两个不那么重要但可以了解的子节点:
4.5 < contextName >:设置上下文名称
< contextName >:设置上下文名称,每个都关联到上下文,默认上下文名称为default,但可以使用设置成其他名字,用于区分不同应用程序的记录,一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称,一般来说我们不用这个属性,可有可无。
4.6 < property >:用来定义变量的节点
< property >:用来定义变量的节点,定义变量后,可以使${}来使用变量,两个属性,当定义了多个< appender >的时候还是很有用的:
- name:变量名
- value:变量值