1. Logback配置文件规则

日志服务一般都在ApplicationContext创建前就初始化了,所以日志配置可以独立于Spring的配置。我们也可以通过系统属性和传统的Spring Boot外部配置文件,实现日志控制和管理。

根据不同的日志系统,Spring Boot按如下“约定规则” 组织配置文件名加载日志配置文件,参见下表:

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置,如使用logback-spring.xml,而不是logback.xml

logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能,根据不同的开发环境设置不同的日志配置。

2. Logback读取配置或属性文件的步骤是

  • 步骤一: Logback在类路径下尝试查找logback.groovy的文件。
  • 步骤二: 如果没有找到logback.groovy文件,就在类路径下查找logback-test.xml文件。
  • 步骤三: 若也没有找到logback-test.xml文件,就会在类路径下查找logback.xml文件。

我们也可以自定义logback.xml名称,然后在application.properties中指定它,如下配置:

logging.config=classpath:log-config.xml

image-20201024182858595

3. logback-spring.xml 详情

3.1 同步日志配置

配置文件位置: src/main/resources/logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- scan :开启"热更新" scanPeriod:"热更新"扫描周期,默认 60 seconds(60秒)-->
<configuration scan="true" scanPeriod="300 seconds">

<!-- 设置日志文件名-->
<property name="LOG_NAME" value="log_demo" />
<!-- 最多保留30历史数据-->
<property name="LOG_MAX_DAY_HISTORY" value="30" />
<!--单个日志文件的最大大小-->
<!-- <property name="LOG_FILE_MAX_SIZE" value="10MB" />-->
<property name="LOG_FILE_MAX_SIZE" value="2KB" />
<!-- 在有 maxHistory 的限制下,进一步限制所有日志文件大小之和的上限,超过则从最旧的日志开始删除-->
<property name="LOG_TOTAL_SIZE_CAP" value="1GB" />


<!-- 自定义变量,用于配置日志输出格式,这个格式是尽量偏向 spring boot 默认的输出风格
%date:日期,默认格式 yyyy-MM-dd hhh:mm:ss,SSS 默认使用本机时区,通过 %d{yyyy-MM-dd hhh:mm:ss,SSS} 来自定义
%-5level:5个占位符的日志级别,例如" info"、"error"
%thread : 输出日志的线程
%class : 输出日志的类的完全限定名,效率低
%method : 输出日志的方法名
%line : 输出日志的行号,效率低
%msg : 日志消息内容
%n : 换行
-->
<property name="LOG_PATTERN" value="%date %-5level --- [%thread] %class.%method/%line : %msg%n"/>
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN_COLOURS" value="%date %green(%-5level) --- [%thread] %cyan(%class.%method/%line) : %msg%n"/>

<!--日志输出器. ch.qos.logback.core.ConsoleAppender : 输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 配置日志输出格式 -->
<pattern>${LOG_PATTERN_COLOURS}</pattern>
<!-- 使用的字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>

<!-- 日志输出器。ch.qos.logback.core.rolling.RollingFileAppender : 滚动输出到文件 -->
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 活动中的日志文件名(支持绝对和相对路径) -->
<file>logs/${LOG_NAME}.log</file>
<!-- 滚动策略. ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy : 按照大小和时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 何时触发滚动,如何滚动,以及滚动文件的命名格式
%d : 日期,默认格式 yyyy-MM-dd,通过 %d{yyyy-MM-dd hhh:mm:ss} 来自定义格式。logback 就是通过 %d 知道了触发滚动的时机
%i : 单个滚动周期内的日志文件的序列号
.zip : 将日志文件压缩成zip。不想压缩,可以使用.log 结尾
如下每天0点以后的第一日志请求触发滚动,将前一天的日志打成 zip 压缩包存放在 logs/app1/backup 下,并命名为 app1_%d_%i.zip
-->
<fileNamePattern>logs/${LOG_NAME}_%d{yyyy-MM-dd}_%i.zip</fileNamePattern>
<!--单个日志文件的最大大小-->
<maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
<!--删除n个滚动周期之前的日志文件(最多保留前n个滚动周期的历史记录)-->
<maxHistory>${LOG_MAX_DAY_HISTORY}</maxHistory>
<!-- 在有 maxHistory 的限制下,进一步限制所有日志文件大小之和的上限,超过则从最旧的日志开始删除-->
<totalSizeCap>${LOG_TOTAL_SIZE_CAP}</totalSizeCap>
</rollingPolicy>
<encoder>
<!-- 日志输出格式 -->
<pattern>${LOG_PATTERN}</pattern>
<!-- 使用的字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 根记录器 -->
<root level="info">
<!-- 使用 STDOUT、ROLLING 输出记录的日志-->
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLING"/>
</root>
</configuration>

3.2 异步日志配置

<?xml version="1.0" encoding="UTF-8"?>

<!-- scan :开启"热更新" scanPeriod:"热更新"扫描周期,默认 60 seconds(60秒)-->
<configuration scan="true" scanPeriod="300 seconds">

<springProperty scope="context" name="logPath" source="logging.file.path"/>
<!-- 设置日志文件名-->
<property name="LOG_NAME" value="log_demo_async" />
<!-- 最多保留30历史数据-->
<property name="LOG_MAX_DAY_HISTORY" value="30" />
<!--单个日志文件的最大大小-->
<!-- <property name="LOG_FILE_MAX_SIZE" value="10MB" />-->
<property name="LOG_FILE_MAX_SIZE" value="50KB" />
<!-- 在有 maxHistory 的限制下,进一步限制所有日志文件大小之和的上限,超过则从最旧的日志开始删除-->
<property name="LOG_TOTAL_SIZE_CAP" value="1GB" />


<!-- 自定义变量,用于配置日志输出格式,这个格式是尽量偏向 spring boot 默认的输出风格
%date:日期,默认格式 yyyy-MM-dd hhh:mm:ss,SSS 默认使用本机时区,通过 %d{yyyy-MM-dd hhh:mm:ss,SSS} 来自定义
%-5level:5个占位符的日志级别,例如" info"、"error"
%thread : 输出日志的线程
%class : 输出日志的类的完全限定名,效率低
%method : 输出日志的方法名
%line : 输出日志的行号,效率低
%msg : 日志消息内容
%n : 换行
-->
<property name="LOG_PATTERN" value="%date %-5level --- [%thread] %class.%method/%line : %msg%n"/>
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN_COLOURS" value="%date %green(%-5level) --- [%thread] %cyan(%class.%method/%line) : %msg%n"/>

<!--日志输出器. ch.qos.logback.core.ConsoleAppender : 输出到控制台-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 配置日志输出格式 -->
<pattern>${LOG_PATTERN_COLOURS}</pattern>
<!-- 使用的字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>

<!-- 日志输出器。ch.qos.logback.core.rolling.RollingFileAppender : 滚动输出到文件 -->
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 活动中的日志文件名(支持绝对和相对路径) -->
<file>${logPath}/${LOG_NAME}.log</file>
<!-- 滚动策略. ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy : 按照大小和时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 何时触发滚动,如何滚动,以及滚动文件的命名格式
%d : 日期,默认格式 yyyy-MM-dd,通过 %d{yyyy-MM-dd hhh:mm:ss} 来自定义格式。logback 就是通过 %d 知道了触发滚动的时机
%i : 单个滚动周期内的日志文件的序列号
.zip : 将日志文件压缩成zip。不想压缩,可以使用.log 结尾
如下每天0点以后的第一日志请求触发滚动,将前一天的日志打成 zip 压缩包存放在 logs/app1/backup 下,并命名为 app1_%d_%i.zip
-->
<fileNamePattern>${logPath}/${LOG_NAME}_%d{yyyy-MM-dd}_%i.zip</fileNamePattern>
<!--单个日志文件的最大大小-->
<maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
<!--删除n个滚动周期之前的日志文件(最多保留前n个滚动周期的历史记录)-->
<maxHistory>${LOG_MAX_DAY_HISTORY}</maxHistory>
<!-- 在有 maxHistory 的限制下,进一步限制所有日志文件大小之和的上限,超过则从最旧的日志开始删除-->
<totalSizeCap>${LOG_TOTAL_SIZE_CAP}</totalSizeCap>
</rollingPolicy>
<encoder>
<!-- 日志输出格式 -->
<pattern>${LOG_PATTERN}</pattern>
<!-- 使用的字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>

<!-- 异步日志 -->
<appender name="ASYNC-ROLLING" class="ch.qos.logback.classic.AsyncAppender">
<!-- 默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。-->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="ROLLING"/>
</appender>

<!-- 根记录器 -->
<root level="info">
<!-- 使用 STDOUT、ROLLING 输出记录的日志-->
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC-ROLLING"/>
</root>
</configuration>

为了看到效果,讲日志单文件最大值设置为2KB,以下是测试代码和运行效果图

新建Controller文件: src/main/java/com/hui/logdemo/controller/LogController.java

package com.hui.logdemo.controller;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;

@RestController
@Slf4j
public class LogController {
@RequestMapping("/log")
public String test(){
String text = "日志内容~~~";
// 重复40遍字符串
String join = String.join("", Collections.nCopies(40, text));
log.trace("这是 trace 类型日志... {}",join);
log.debug("这是 debug 类型日志... {}",join);
log.info("这是 info 类型日志... {}",join);
log.warn("这是 warn 类型日志... {}",join);
log.error("这是 error 类型日志... {}",join);
return "日志测试使用";
}
}

访问几次后效果图如下:

image-20201026094604225

4. 配置显示颜色

Logback 本身是支持彩色显示的,支持的颜色如下:

%black()
%red()
%green()
%yellow()
%blue()
%magenta()
%cyan()
%white()
%gray()
%boldRed()
%boldGreen()
%boldYellow()
%boldBlue()
%boldMagenta()
%boldCyan()
%boldWhite()
%highlight()

使用方式:

<!-- 彩色日志格式 -->
<property name="LOG_PATTERN_COLOURS" value="%date %green(%-5level) --- [%thread] %cyan(%class.%method/%line) : %msg%n"/>