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 异步写入日志。别忘了,再次重启一下项目,自测一波日志功能是否好使~

相关推荐
IT毕设实战小研1 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
一只爱撸猫的程序猿2 小时前
使用Spring AI配合MCP(Model Context Protocol)构建一个"智能代码审查助手"
spring boot·aigc·ai编程
甄超锋2 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
武昌库里写JAVA5 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
Pitayafruit6 小时前
Spring AI 进阶之路03:集成RAG构建高效知识库
spring boot·后端·llm
zru_96026 小时前
Spring Boot 单元测试:@SpyBean 使用教程
spring boot·单元测试·log4j
甄超锋6 小时前
Java Maven更换国内源
java·开发语言·spring boot·spring·spring cloud·tomcat·maven
还是鼠鼠7 小时前
tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
java·spring boot·后端·spring·maven
舒一笑12 小时前
Started TttttApplication in 0.257 seconds (没有 Web 依赖导致 JVM 正常退出)
jvm·spring boot·后端
javadaydayup13 小时前
Apollo 凭什么能 “干掉” 本地配置?
spring boot·后端·spring