一、Logback 日志

Logback 是 SpringBoot 内置的日志处理框架,你会发现 spring-boot-starter 其中包含了 spring-boot-starter-logging,该依赖内容就是 Spring Boot 默认的日志框架 logback。

官方文档:http://logback.qos.ch/manual/

1、SpringBoot 默认 Logback 配置

在我们启动 SpringBoot,发现我们并没有主动去配置过任何和日志打印的相关配置,但是控制台却打印了相关的启动日志。

因为 SpringBoot 为 Logback 提供了默认的配置文件 base.xml,base.xml 文件里定义了默认的 root 输出级别为 INFO。

2、日志级别

日志记录器(Logger)的行为是分等级的。如下表所示:

从下往上分为:TRACE,DEBUG,INFO,WARN, ERROR, ALL 和 OFF

默认情况下,spring boot 从控制台打印出来的日志级别只有 INFO 及以上级别

可以自行在application.yml中配置日志级别

1
2
3
4
# 设置日志级别
logging:
level:
root: ERROR

这种方式能将 ERROR 级别以及以上级别的日志输出到控制台上,其他级别将不会输出

二、自定义 logback 的配置文件

spring boot 内部使用 Logback 作为日志实现的框架。

在 resources 中创建 logback-spring.xml (默认日志文件的名字,这样会被 Spring 容器自动加载,无需自己配置)

基本配置说明

1、configuration

日志配置的根节点

1
<configuration></configuration>

2、contextName

<contextName>是<configuration>的子节点。

每个 logger 都关联到 logger 上下文,默认上下文名称为“default”。

但可以使用<contextName>设置成其他名字,用于区分不同的应用程序。

1
<contextName>atguiguSrb</contextName>

3、property

<property>是<configuration>的子节点,用来定义变量。

<property> 有两个属性:namevaluename的值是变量的名称,value是变量的值。

通过<property>定义的值会被插入到 logger 上下文中。定义变量后,可以使“${}”来使用变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 日志的输出目录 -->
<property name="log.path" value="D:/project" />

<!--控制台日志格式:彩色日志-->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>

<!--文件日志格式-->
<!--展示在文本文件中,没必要展示颜色-->
<!--%thread:具体哪个线程, %file:具体哪个文件,%line:在这个文件中的第几行,-->
<property name="FILE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" />

<!--编码-->
<property name="ENCODING"
value="UTF-8" />

控制台日志格式:

%yellow(%date{yyyy-MM-dd HH:mm:ss}):用黄色显示时间日期格式

%highlight:高亮显示日志级别

%-5level:都占 5 个字节(方便对齐,比如[ERROR]和[INFO ])

%green(%logger):用绿色显示日志记录器的名字(在哪个类里面,就显示哪个类的类全名)

%msg:输出具体 msg 消息

%n 换行

4、appender

<appender>是<configuration>的子节点,是负责写日志的组件

  • <appender>有两个必要属性nameclassname指定 appender 名称,class指定 appender 的全限定名
  • <encoder>对日志进行格式化
  • <pattern>定义日志的具体输出格式
  • <charset>编码方式

① 控制台日志配置

1
2
3
4
5
6
7
8
9
<!-- 控制台日志 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--控制台日志格式name="CONSOLE_LOG_PATTERN"-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!--日志编码方案property name="ENCODING"-->
<charset>${ENCODING}</charset>
</encoder>
</appender>

② 文件日志配置

<file>表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。

<append>默认 true,日志被追加到文件结尾,如果是 false,服务重启后清空现存文件。

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- 日志的输出目录name="log.path" -->
<file>${log.path}/log.log</file>
<append>true</append>
<encoder>
<!--文件日志格式name="FILE_LOG_PATTERN"-->
<pattern>${FILE_LOG_PATTERN}</pattern>
<!--日志编码方案-->
<charset>${ENCODING}</charset>
</encoder>
</appender>

5、logger

<logger>可以是<configuration>的子节点,用来设置某一个包或具体某一个类的日志打印级别、指定

name:用来指定受此 logger 约束的某一个包或者具体的某一个类

level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默认继承上级的级别

<logger>可以包含零个或多个<appender-ref>元素,标识这个 appender 将会添加到这个 logger

1
2
3
4
5
6
7
8
<!-- 日志记录器  -->
<!--日志记录器的名字,一般以包名的形式定义(相当于记录范围为com.atguigu)-->
<logger name="com.atguigu" level="INFO">
<!-- 往控制台记录日志 -->
<appender-ref ref="CONSOLE" />
<!-- 往文件记录日志 -->
<appender-ref ref="FILE" />
</logger>

三、多环境配置

在一个基于 Spring boot 开发的项目里,常常需要有多套环境的配置:开发,测试以及产品。

使用springProfile 可以分别配置开发(dev),测试(test)以及生产(prod)等不同的环境。

logback-spring.xml中进行配置

只需要修改application.yml中修改不同的环境,就可以在日志中自动配对对应的日志记录环境

注意:配置了多环境配置的话,上面配置的单独的 logger 日志记录器就不需要了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 开发环境和测试环境 -->
<!--dev名字要和application.yml配置文件中的spring:profiles:active:dev名字一致-->
<springProfile name="dev,test">
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
</springProfile>

<!-- 生产环境 -->
<springProfile name="prod">
<logger name="com.atguigu" level="ERROR">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</logger>
</springProfile>

四、滚动日志

问题:生产环境下,如果系统长时间运行,那么日志文件会变得越来越大,系统读取和写入日志的时间会越来越慢,严重的情况会耗尽系统内存,导致系统宕机。

解决方案:可以设置滚动日志。

1、设置时间滚动策略

RollingFileAppender 是 Appender 的另一个实现,表示滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将旧日志备份到其他文件

<rollingPolicy>是<appender>的子节点,用来定义滚动策略。

  • TimeBasedRollingPolicy:最常用的滚动策略,根据时间来制定滚动策略。
  • <fileNamePattern>:包含文件名及转换符, “%d”可以包含指定的时间格式,如:%d{yyyy-MM-dd}。如果直接使用 %d,默认格式是 yyyy-MM-dd。
  • <maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且<maxHistory>是 6,则只保存最近 6 个月的文件,删除之前的旧文件。注意,删除旧文件时,那些为了归档而创建的目录也会被删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>

<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式,比如:log-rolling-2021-07-02.0,2021年7月2日的第一个归档日志 -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--归档日志文件保留的最大数量(一天一篇日志,相当于日志保留天数)-->
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>

2、设置触发滚动时机

放在<rollingPolicy>的子节点的位置,基于实践策略的触发滚动策略

<maxFileSize>设置触发滚动条件:单个文件大于 100M 时生成新的文件

1
2
3
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>

五、完整的日志配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>atguiguSrb</contextName>
<!-- 日志的输出目录 -->
<property name="log.path" value="D:/" />

<!--控制台日志格式:彩色日志-->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<!-- value:颜色、时间日期格式、高亮,都占5个字节(方便对齐,比如error和info)、logger日志记录器的名字,用绿色显示,输出具体msg消息、%n换行-->

<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/>

<!--文件日志格式-->
<!--展示在文本文件中,没必要展示颜色-->
<!--%thread:具体哪个线程, %file:具体哪个文件,%line:在这个文件中的第几行,-->
<property name="FILE_LOG_PATTERN"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" />

<!--编码-->
<property name="ENCODING"
value="UTF-8" />

<!-- 控制台日志 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--控制台日志格式name="CONSOLE_LOG_PATTERN"-->
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<!--日志编码方案-->
<charset>${ENCODING}</charset>
</encoder>
</appender>

<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- 日志的输出目录name="log.path" -->
<file>${log.path}/log.log</file>
<!--ture:追加日志而不是新建日志-->
<append>true</append>
<encoder>
<!--文件日志格式name="FILE_LOG_PATTERN"-->
<pattern>${FILE_LOG_PATTERN}</pattern>
<!--日志编码方案-->
<charset>${ENCODING}</charset>
</encoder>
</appender>

<!-- 日志记录器 -->
<!--日志记录器的名字,一般以包名的形式定义(相当于记录范围为com.atguigu)-->
<!--<logger name="com.atguigu" level="INFO">-->
<!-- &lt;!&ndash; 往控制台记录日志 &ndash;&gt;-->
<!-- <appender-ref ref="CONSOLE" />-->
<!-- &lt;!&ndash; 往文件记录日志 &ndash;&gt;-->
<!-- <appender-ref ref="FILE" />-->
<!--</logger>-->


<!-- 滚动日志 -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!-- 要区别于其他的appender中的文件名字 -->
<file>${log.path}/log-rolling.log</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>

<!-- 设置滚动日志记录的滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档路径以及格式,比如:log-rolling-2021.01.01.log -->
<fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--归档日志文件保留的最大数量(一天一篇日志,相当于日志保留天数)-->
<maxHistory>15</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--500M一个日志文件-->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>

<!-- 开发环境和测试环境 -->
<!--dev名字要和application.yml配置文件中的spring:profiles:active:dev名字一致-->
<springProfile name="dev">
<logger name="com.atguigu" level="INFO">
<appender-ref ref="CONSOLE" />
<!--设置文件日志为滚动日志-->
<appender-ref ref="ROLLING_FILE" />
</logger>
</springProfile>

<!-- 生产环境 -->
<springProfile name="prod">
<logger name="com.atguigu" level="ERROR">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</logger>
</springProfile>

</configuration>