当前位置: 首页 > news >正文

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

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

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

1. 添加日志配置文件

/resources 资源目录下,创建名为 logback-spring.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>

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

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

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

<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 配置
<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 两个环境:
<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 实现。

<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 测试环境, 也仅需要输出日志到文件。则可以配置如下,通过逗号 , 分隔开来就行:

<springProfile name="test,prod">// 省略...
</springProfile>

2. 异步日志

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

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

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

2.2 Logback 配置异步日志

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

	// 省略...<!-- 文件输出 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">// 省略...</appender><!-- 异步写入日志,提升性能 --><appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"><!-- 是否丢弃日志, 0 表示不丢弃。默认情况下,如果队列满 80%, 会丢弃 TRACEDEBUGINFO 级别的日志 --><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 异步写入日志。别忘了,再次重启一下项目,自测一波日志功能是否好使~

相关文章:

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

Spring Boot 3.x 整合 Logback 日志框架&#xff08;支持异步写入&#xff09; 在构建任何应用程序时&#xff0c;良好的日志管理都是必不可少的。日志可以帮助我们监控、调试和跟踪代码的运行情况。 1. 添加日志配置文件 在 /resources 资源目录下&#xff0c;创建名为 log…...

从0开始学习搭网站第二天

前言&#xff1a;今天比较惭愧&#xff0c;中午打铲吃了一把&#xff0c;看着也到钻二了&#xff0c;干脆顺手把这个赛季的大师上了&#xff0c;于是乎一直到网上才开始工作&#xff0c;同样&#xff0c;今天的学习内容大多来自mdn社区mdn 目录 怎么把文件上传到web服务器采用S…...

【Unity-Animator】通过 StateMachineBehaviour 实现回调

StateMachineBehaviour 简介 StateMachineBehaviour是一个基类&#xff0c;所有状态脚本都派生自该类。它可以在状态机进入、退出或更新状态时执行代码&#xff0c;而无需编写自己的逻辑来测试和检测状态的变化。这使得开发者可以更方便地处理状态转换时的逻辑&#xff0c;例…...

鸿蒙中自定义slider实现字体大小变化

ui&#xff1a; import { display, mediaquery, router } from kit.ArkUI import CommonConstants from ./CommonConstants; import PreferencesUtil from ./PreferencesUtil; import StyleConstants from ./StyleConstants;// 字体大小 Entry Component struct FontSize {Sta…...

数据结构与算法之栈: LeetCode 71. 简化路径 (Ts版)

简化路径 https://leetcode.cn/problems/simplify-path/description/ 描述 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 ‘/’ 开头&#xff09;&#xff0c;请你将其转化为 更加简洁的规范路径 在 Unix 风格的文件系统中…...

STM32-笔记40-BKP(备份寄存器)

一、什么是BKP&#xff08;备份寄存器&#xff09;&#xff1f; 备份寄存器是42个16位的寄存器&#xff0c;可用来存储84个字节的用户应用程序数据。他们处在备份域里&#xff0c;当VDD电源被切断&#xff0c;他们仍然由VBAT维持供电。当系统在待机模式下被唤醒&#xff0c;或…...

NAS中不同RAID级别特点与适用场景

1. RAID 0&#xff08;条带化&#xff09; 硬盘数量&#xff1a;至少2块。硬盘要求&#xff1a;硬盘容量可以不同&#xff0c;但总容量以最小硬盘为准&#xff08;例如&#xff1a;1TB 2TB 2TB&#xff0c;其中1TB会被浪费&#xff09;。优点&#xff1a; 读写性能显著提升&…...

node.js的进程保活

nodejs的进程保活其实用PM2应该更好用些&#xff0c;不过由于原理其实并不复杂&#xff0c;我们可以自己手写一个服务来干这个工作。 假设我们有一个服务&#xff0c;可以这样来定义下它的相关信息&#xff1a; const svcs[ {"sid":"apl","name"…...

meta name=“viewport“ content=“width=device-width, initial-scale=1.0“

meta name“viewport” content“widthdevice-width, initial-scale1.0” 这段代码在网页设计中扮演着非常重要的角色&#xff0c;尤其是在响应式设计中。下面是对这段代码的详细解释及其在响应式设计中的作用&#xff1a; 1. 代码含义 html Copy Code meta 标签是 HTML 中用…...

【vue3】 defineExpose 的使用

以下是 Vue3 中defineExpose的使用方法&#xff1a; 基本概念 defineExpose是 Vue3 中的一个工具函数&#xff0c;是仅能在<script setup>中使用的函数&#xff0c;用于显式暴露组件内部的属性或方法给父组件使用2。在 Vue3 的<script setup>中&#xff0c;组件的…...

思维转换:突破思维桎梏,创造更高效的工作与生活

在现代职场和生活中&#xff0c;我们经常面临着各种挑战和问题&#xff0c;有时候虽然付出了很多努力&#xff0c;但依然难以找到更有效的解决方案。这时&#xff0c;或许我们需要的不是更多的努力&#xff0c;而是一次“思维转换”。这一概念看似简单&#xff0c;但它背后却蕴…...

OpenCV相机标定与3D重建(55)通用解决 PnP 问题函数solvePnPGeneric()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 根据3D-2D点对应关系找到物体的姿态。 cv::solvePnPGeneric 是 OpenCV 中一个更为通用的函数&#xff0c;用于解决 PnP 问题。它能够返回多个可能…...

vue3学习日记5 - 项目起步

最近发现职场前端用的框架大多为vue&#xff0c;所以最近也跟着黑马程序员vue3的课程进行学习&#xff0c;以下是我的学习记录 视频网址&#xff1a; Day2-11.项目起步-静态资源引入和ErrorLen安装_哔哩哔哩_bilibili 学习日记&#xff1a; vue3学习日记1 - 环境搭建-CSDN博…...

java导出pdf文件

java导出pdf&#xff0c;前端下载 1、制作pdf模板2、获取pdf导出中文需要的文件3、实现4、前端发起请求并生成下载链接 使用注意点 因为原来制作的pdf表单内容过于复杂&#xff0c;下面代码只包含前两行的操作。 本次操作需要前端向后端发起请求&#xff0c;后端返回数据给前端…...

【MySQL学习笔记】MySQL视图View

视图View 1、视图的基础语法2、检查选项3、视图的更新4、视图的作用 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&…...

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》&#xff0c;让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识&#xff0c;顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话&#xff0c;可以看看博主的C语言专栏哟&#xff…...

【Redis】初识Redis

目录 Redis简介 Redis在内存中存储数据 Redis数据库中的应用 Redis缓存中的应用 Redis消息中间件 尾言 Redis简介 如下是Redis官网中&#xff0c;对Redis的一段描述 在这段描述中&#xff0c;我们提取如下关键要点&#xff1a; Redis主要用于在内存中存储数据Redis可…...

docker虚拟机平台未启用问题

在终端中输入如下代码&#xff0c;重启电脑即可 Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform 对于Docker Desktop - Unexpected WSL error问题 参考链接 解决WSL2与docker冲突问题...

《零基础Go语言算法实战》【题目 2-22】Go 调度器优先调度问题

《零基础Go语言算法实战》 【题目 2-22】Go 调度器优先调度问题 下面代码的输出是什么&#xff1f;请说明原因。 package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(1) wg : sync.WaitGroup{} wg.Add(10)…...

关于使用FastGPT 摸索的QA

近期在通过fastGPT&#xff0c;创建一些基于特定业务场景的、相对复杂的Agent智能体应用。 工作流在AI模型的基础上&#xff0c;可以定义业务逻辑&#xff0c;满足输出对话之外的需求。 在最近3个月来的摸索和实践中&#xff0c;一些基于经验的小问题点&#xff08;自己也常常…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...