Spring Boot 3.x 整合 Logback 日志框架(支持异步写入)

Spring Boot 3.x 整合 Logback 日志框架(支持异步写入)

在构建任何应用程序时,良好的日志管理都是必不可少的。日志可以帮助我们监控、调试和跟踪代码的运行情况。

1. 添加日志配置文件

/resources 资源目录下,创建名为 logback-spring.xml 日志配置文件:

文件内容如下:

xml 复制代码
<configuration>
    <!-- 引用 Spring Boot 的 logback 基础配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />

    <!-- 应用名称 -->
    <property scope="context" name="appName" value="auth"/>
    <!-- 自定义日志输出路径,以及日志名称前缀 -->
    <property name="LOG_FILE" value="./logs/${appName}.%d{yyyy-MM-dd}"/>
    <!-- 每行日志输出的格式 -->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>

    <!-- 文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件的命名格式 -->
            <fileNamePattern>${LOG_FILE}-%i.log</fileNamePattern>
            <!-- 保留 30 天的日志文件 -->
            <maxHistory>30</maxHistory>
            <!-- 单个日志文件最大大小 -->
            <maxFileSize>10MB</maxFileSize>
            <!-- 日志文件的总大小,0 表示不限制 -->
            <totalSizeCap>0</totalSizeCap>
            <!-- 重启服务时,是否清除历史日志,不推荐清理 -->
            <cleanHistoryOnStart>false</cleanHistoryOnStart>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 本地 dev 开发环境 -->
    <springProfile name="dev">
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
        <root level="INFO">
            <appender-ref ref="CONSOLE"/> <!-- 输出控制台日志 -->
            <appender-ref ref="FILE"/> <!-- 打印日志到文件中。PS: 本地环境下,如果不想打印日志到文件,可注释掉此行 -->
        </root>
    </springProfile>

    <!-- 其它环境 -->
    <springProfile name="prod">
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
        <root level="INFO">
            <appender-ref ref="FILE"/> <!-- 生产环境下,仅打印日志到文件中 -->
        </root>
    </springProfile>

</configuration>

说一下日志配置文件中,每项配置都是干啥的:

  • 基础配置和属性定义
makefile 复制代码
<include resource="org/springframework/boot/logging/logback/defaults.xml" />

上述配置用于引用 Spring Boot 的默认 Logback 基础配置。

perl 复制代码
<property scope="context" name="appName" value="auth"/>
<property name="LOG_FILE" value="./logs/${appName}.%d{yyyy-MM-dd}"/>
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
  • 定义了一些全局属性:
    • appName:应用名称,这里值填写为 auth ,表示认证服务。
    • LOG_FILE:日志文件的路径和文件名模板, ./logs 表示输出到项目的同级目录下的 /logs 文件夹下。
    • LOG_PATTERN:日志输出格式。
  • 日志文件 Appender 配置
php-template 复制代码
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>${LOG_FILE}-%i.log</fileNamePattern>
        <maxHistory>30</maxHistory>
        <maxFileSize>10MB</maxFileSize>
        <totalSizeCap>0</totalSizeCap>
        <cleanHistoryOnStart>false</cleanHistoryOnStart>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${LOG_PATTERN}</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>
  • appender:用于将日志输出到文件,并且使用滚动策略来管理日志文件。
  • rollingPolicy:定义了日志滚动策略,使用 SizeAndTimeBasedRollingPolicy 以时间和大小为基准进行滚动。
  • fileNamePattern:定义了日志文件的命名模式。
  • maxHistory:保留 30 天的日志文件。
  • maxFileSize:每个日志文件最大 10MB。
  • totalSizeCap:总日志文件大小没有限制。
  • cleanHistoryOnStart:项目启动时不清理历史日志文件。
  • encoder:定义了日志的输出格式,以及文件编码格式。
  • Spring Profile 配置 :用于配置各环境的日志行为。这里主要定义了 devprod 两个环境:
php-template 复制代码
<springProfile name="dev">
   <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
       <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/> 
    </root>
</springProfile>

dev 本地开发环境中,包含控制台输出 CONSOLE 和文件输出 FILECONSOLE 配置通过包含 Spring Boot 默认的 console-appender.xml 实现。

php-template 复制代码
<springProfile name="prod">
   <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
       <appender-ref ref="FILE"/> 
    </root>
</springProfile>

prod 生产环境中,仅包含文件输出 FILE,不输出到控制台。这是为了生产环境中减少控制台日志输出,避免影响性能。

拓展小知识 : 如果你想同时设置多个环境,假设咱们除了本地开发环境、生产环境外,还有个 test 测试环境, 也仅需要输出日志到文件。则可以配置如下,通过逗号 , 分隔开来就行:

php-template 复制代码
<springProfile name="test,prod">
 // 省略...
</springProfile>

2. 异步日志

异步打印日志(Asynchronous Logging)是一种日志记录方式,它将日志写入操作放在一个单独的线程中执行,而不是在主线程中进行。这意味着日志写入的过程不会阻塞主线程的执行,主线程可以继续执行其余的业务逻辑,增强了应用的性能和响应速度。

2.1 为什么需要异步打印日志

  • 性能提升:同步日志记录在高并发情况下会显著影响应用性能,因为每一次日志写入操作都可能导致磁盘 I/O 操作,主线程必须等待这些操作完成才能继续执行。异步日志记录将这些操作放在单独的线程中进行,避免了主线程的阻塞,提高了整体性能。
  • 响应时间:异步日志记录可以减少应用的响应时间,尤其是在需要记录大量日志信息的时候。用户请求得到快速响应,而日志记录在后台处理。
  • 资源利用:通过异步日志记录,应用可以更有效地利用 CPU 资源。同步日志记录可能导致线程频繁等待 I/O 操作完成,而异步记录可以让这些线程去执行其他任务,提高资源利用率。
  • 系统稳定性:在极端情况下(例如,日志量非常大时),同步日志记录可能会导致应用出现性能瓶颈甚至崩溃。异步日志记录通过缓冲和队列机制,能够更好地应对突发的大量日志请求,增强系统稳定性。

2.2 Logback 配置异步日志

Logback 提供了 AsyncAppender 来支持异步日志记录。通过 AsyncAppender 可以将日志事件发送到一个队列中,并由一个独立的线程池来处理这些日志事件。编辑 logback-spring.xml 文件,添加配置如下:

php-template 复制代码
	// 省略...

	<!-- 文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		// 省略...
    </appender>

    <!-- 异步写入日志,提升性能 -->
    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 是否丢弃日志, 0 表示不丢弃。默认情况下,如果队列满 80%, 会丢弃 TRACE、DEBUG、INFO 级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 队列大小。默认值为 256 -->
        <queueSize>256</queueSize>
        <appender-ref ref="FILE"/>
    </appender>
    
    <!-- 本地 dev 开发环境 -->
    <springProfile name="dev">
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
        <root level="INFO">
            <appender-ref ref="CONSOLE"/> <!-- 输出控制台日志 -->
            <appender-ref ref="ASYNC_FILE"/> <!-- 打印日志到文件中。PS: 本地环境下,如果不想打印日志到文件,可注释掉此行 -->
        </root>
    </springProfile>

    <!-- 其它环境 -->
    <springProfile name="prod">
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
        <root level="INFO">
            <appender-ref ref="ASYNC_FILE"/> <!-- 生产环境下,仅打印日志到文件中 -->
        </root>
    </springProfile>
    
    // 省略...

解释一下修改的地方,主要添加了一个名称为 ASYNC_FILE 异步输出日志的 Appender

  • AsyncAppender 使用内部队列来异步处理日志事件。
  • queueSize:队列的大小。
  • discardingThreshold:是否丢弃日志, 0 表示不丢弃。

最后,将各个环境中的 FILE 更改为 ASYNC_FILE 异步写入日志。别忘了,再次重启一下项目,自测一波日志功能是否好使~

相关推荐
梦想歌2 分钟前
Dockerfile 构建 Java 应用瘦身优化
spring boot·docker
kikyo哎哟喂1 小时前
Spring&SpringBoot常用注解总结
java·spring boot·spring
S-X-S2 小时前
自定义异常模块
java·开发语言·spring boot
ss2732 小时前
基于Springboot + vue实现的文档管理系统
vue.js·spring boot·后端
烟波人长安吖~3 小时前
【安全帽头盔检测】基于YOLOV11+pytorch+Flask+SpringBoot+Vue+MySQL的安全帽头盔检测识别系统
pytorch·spring boot·深度学习·yolo·vue·计算机毕业设计·头盔安全帽检测
周盛欢3 小时前
Spring Boot 应用开发入门
java·spring boot·后端
customer085 小时前
【开源免费】基于SpringBoot+Vue.JS公司日常考勤系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud
小蒜学长5 小时前
二手车交易系统的设计与实现(代码+数据库+LW)
数据库·spring boot·后端·spring·旅游
马剑威(威哥爱编程)5 小时前
如何使用 Java 的 Spring Boot 创建一个 RESTful API?
java·开发语言·spring boot