Java实战:Spring Boot 实现异步记录复杂日志
日志记录是软件开发中非常重要的一环,它可以帮助我们快速定位问题、监控程序运行状态等。在 Spring Boot 应用中,异步记录日志是一种常见的需求。本文将详细介绍如何在 Spring Boot 中实现异步记录复杂日志,包括异步日志的基本原理、实现方式、以及具体代码示例。
一、异步日志的基本原理
在传统的同步日志记录方式中,当程序执行到日志输出语句时,会立即将日志信息写入到日志文件中。这种方式在某些情况下可能会影响程序的性能,尤其是在高并发场景下。为了解决这个问题,我们可以采用异步日志记录方式。
异步日志记录的基本原理是:当程序执行到日志输出语句时,并不是立即将日志信息写入到日志文件中,而是将日志信息放入一个缓冲区(如队列)中,然后程序继续执行。另外有一个专门的线程负责从缓冲区中取出日志信息,并写入到日志文件中。这种方式可以大大减少日志输出对程序性能的影响。
二、Spring Boot 中实现异步日志的方法
在 Spring Boot 中,我们可以通过以下几种方式实现异步日志记录:
1. 使用 Logback 的异步日志功能
Logback 是 Spring Boot 默认的日志框架。Logback 提供了异步日志的功能,可以通过配置文件来开启。
首先,在项目的 resources 目录下创建 logback-spring.xml 文件,然后添加以下内容:
<configuration><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><queueSize>1024</queueSize><appender-ref ref="STDOUT"/></appender><root level="info"><appender-ref ref="ASYNC"/></root>
</configuration>
在上面的配置中,我们创建了一个名为 ASYNC 的异步日志记录器,并将其输出目标设置为标准输出(STDOUT)。此外,我们还将队列大小设置为 1024,这意味着缓冲区可以存储 1024 条日志信息。
2. 使用 Spring AOP 和异步注解
除了使用 Logback 的异步日志功能外,我们还可以通过 Spring AOP 和异步注解来实现异步日志记录。
首先,我们需要在项目中添加 Spring AOP 的依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后,我们可以创建一个切面类,用于拦截需要记录日志的方法:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {@Pointcut("execution(* com.example.service.*.*(..))")public void serviceLog() {}@Before("serviceLog()")public void beforeServiceLog() {System.out.println("Before service method");}
}
在上面的代码中,我们定义了一个名为 LoggingAspect 的切面类,该类包含一个名为 serviceLog 的切点,该切点用于拦截 com.example.service 包下所有类的所有方法。我们还定义了一个名为 beforeServiceLog 的前置通知,该通知会在方法执行前输出一条日志信息。
最后,我们可以在需要记录日志的方法上添加 @Async 注解,以实现异步日志记录:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class UserService {@Asyncpublic void addUser(User user) {// 业务逻辑}
}
三、代码示例
下面是一个完整的示例,展示了如何在 Spring Boot 中实现异步记录复杂日志。
1. 添加依赖
首先,在项目的 pom.xml 文件中添加以下依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
</dependencies>
2. 配置 Logback
在项目的 resources 目录下创建 logback-spring.xml 文件,并添加以下内容:
<configuration><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><queueSize>1024</queueSize><appender-ref ref="STDOUT"/></appender><root level="info"><appender-ref ref="ASYNC"/></root>
</configuration>
3. 创建切面类
创建一个名为 LoggingAspect 的切面类,用于拦截需要记录日志的方法:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {@Pointcut("execution(* com.example.service.*.*(..))")public void serviceLog() {}@Before("serviceLog()")public void beforeServiceLog() {System.out.println("Before service method");}
}
4. 创建服务类
创建一个名为 UserService 的服务类,并在其中一个方法上添加 @Async 注解:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class UserService {@Asyncpublic void addUser(User user) {// 业务逻辑}
}
5. 创建控制器类
创建一个名为 UserController 的控制器类,用于测试异步日志记录:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/addUser")public String addUser() {userService.addUser(new User());return "User added";}
}
6. 运行项目
启动 Spring Boot 应用,并访问以下 URL:http://localhost:8080/addUser。在浏览器中,我们将看到“User added”的响应。同时,在控制台输出中,我们将看到“Before service method”的日志信息。这表明我们已经成功实现了异步记录复杂日志的功能。
四、总结
本文详细介绍了在 Spring Boot 中实现异步记录复杂日志的方法,包括异步日志的基本原理、实现方式以及具体代码示例。通过使用 Logback 的异步日志功能和 Spring AOP,我们可以轻松地实现异步日志记录,从而提高应用程序的性能。希望本文对您有所帮助。
相关文章:
Java实战:Spring Boot 实现异步记录复杂日志
日志记录是软件开发中非常重要的一环,它可以帮助我们快速定位问题、监控程序运行状态等。在 Spring Boot 应用中,异步记录日志是一种常见的需求。本文将详细介绍如何在 Spring Boot 中实现异步记录复杂日志,包括异步日志的基本原理、实现方式…...
“色狼”用英语怎么说?柯桥日常英语,成人英语口语学习
最近有粉丝问我"色狼"英文翻译是啥 首先声明不是"colour wolf"哈 关于“色狼”的英文表达有很多 快和C姐一起来看看吧! 1.pervert 这个单词的意思是变态、色狼 是对性变态者最直观的描述 He is such a pervert! I saw him lo…...
Docker前后端项目部署
目录 一、搭建项目部署的局域网 二、redis安装 三、MySQL安装 四、若依后端项目搭建 4.1 使用Dockerfile自定义镜像 五、若依前端项目搭建 一、介绍前后端项目 一张图带你看懂ruoyi的前后端项目部署 得出结论:需要4台服务器,都处于同一个局域网中…...
如何快速的搭建一个小程序
要快速搭建一个小程序,你可以按照以下步骤进行: 明确目标和需求:在开始搭建小程序之前,首先明确你的小程序的主要功能、目标用户以及希望实现的业务需求。这将帮助你更好地规划和设计小程序。选择小程序平台:根据你的…...
STM32自学☞AD多通道
涉及到的硬件有:光敏传感器,热敏传感器,红外对射传感器,电位器 通过adc将他们采集的模拟信号转换为数值 ad.c文件 #include "stm32f10x.h" #include "stm32f10x_adc.h" #include "ad.h" #inc…...
微服务之商城系统
一、商城系统建立之前的一些配置 1、nacos Nacos是一个功能丰富的开源平台,用于配置管理、服务发现和注册、健康检查等,帮助构建和管理分布式系统。 在linux上安装nacos容器的命令: docker run --name nacos-standalone -e MODEstandalone …...
安卓玩机工具推荐----高通芯片9008端口读写分区 备份分区 恢复分区 制作线刷包 工具操作解析
上期解析了下adb端口备份分区的有关操作 安卓玩机工具推荐----ADB状态读写分区 备份分区 恢复分区 查看分区号 工具操作解析 在以往的博文中对于高通芯片机型的分区读写已经分享了很多。相关类似博文 安卓备份分区----手动查询安卓系统分区信息 导出系统分区的一些基本操作 …...
全量知识系统问题及SmartChat给出的答复 之16 币圈生态链和行为模式
Q.42 币圈生态链和行为模式 我认为,上面和“币”有关的一系列概念和技术,按设计模式的划分 ,整体应该都属于行为模式,而且应该囊括行为模式的所有各个方面。 而行为又可以按照三种不同的导向(以目的或用途为导向、过…...
【MOMO_Tips】批量将word转换为PDF格式
批量将word转换为PDF格式 1.打开文件–>选项–>自定义功能区–>开发工具–>确定 2.点开开发工具,选择第一个visual basic 3.进入页面后找到插入–>模块,就可以看到这样的画面之后将下列vba代码复制粘贴到模块中 Sub ConvertWordsToPd…...
【JSON2WEB】08 Amis的事件和校验
【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…...
抖店类目报白什么意思?什么类目需要报白?这次给你讲明白!
我是电商珠珠 不少新手在选择类目的时候,有些类目却无法选择,系统显示需要报白才可以。那什么是报白?怎么报白?今天我就一次性给你们讲清楚。 抖店类目报白什么意思? 根据官方的说法,报白就是针对一些比…...
<C++>【继承篇】
✨前言✨ 🎓作者:【 教主 】 📜文章推荐: ☕博主水平有限,如有错误,恳请斧正。 📌机会总是留给有准备的人,越努力,越幸运! 💦导航助手…...
size_t 和double相乘怎么转换size_t
在C中,size_t和double可以直接相乘,结果会自动转换为double类型。如果你想要得到的结果是size_t类型,你需要进行显式类型转换。但是要注意,double转size_t可能会丢失小数部分,只保留整数部分。 以下是一个例子&#x…...
C# 的一些好用的语法糖介绍
C# 中有很多语法糖(Syntactic sugar),它们是一些语言特性,使得编写代码更加简洁、易读、更具表现力。 Lambda 表达式: Lambda 表达式允许你编写简洁的匿名函数。例如: Func<int, int, int> add (a…...
驱动开发面试复习
创建字符设备 1 创建设备号 alloc_chrdev_region 2.创建cdev cdev_init 3.添加一个 cdev,完成字符设备注册到内核 cdev_add 4.创建类 class_create 5.创建设备 device_create 1.内核空间与用户空间数据 copy_from_user 和copy_to_user 俩个函数来完成。 copy_from_user 函数…...
监测数据计算与换算:确保工程安全的关键步骤
在工程项目中,监测数据的计算与换算是一项至关重要的工作,它直接关系到工程的安全与稳定。本文将从确定基准值、数据计算与换算、异常值处理以及数据存储等方面,探讨监测数据计算与换算的主要工作内容。 添加图片注释,不超过 140 …...
Vue项目实战--空间论坛(1)
环境准备 安装好node.js,Vue后 添加插件 router---路由,多页面的应用 vuex---在多个组件之间维护同一个数据 添加依赖 bootstrap---美工 popperjs/core vue项目介绍 views-----对应vue文件,页面 router-----路由,页面,c…...
linux内核驱动——字符设备实现两个终端单向收发
linux内核驱动——字符设备实现两个终端单向收发 参考 Ubuntu18.04添加内核模块(字符设备) 创建内核驱动文件chat_dev.c: #include <linux/init.h> //定义了module_init #include <linux/module.h> //最基本的头文件&a…...
读取CSV数据并写入MySQL
import pandas as pd #import tushare as ts from sqlalchemy import create_engineimport baostock as bs #### 登陆系统 #### lg bs.login() # 显示登陆返回信息 print(login respond error_code:lg.error_code) print(login respond error_msg:lg.error_msg) #### 获取沪深…...
centos7.4下升级最新的ssh
一 安装telnet服务器 安装telnet服务器目的,防止我们升级失败的时候,可以通过telnet登录,而不至于上机房。 由于我们是临时启动,所以只要简单的使用,不要通过xinetd来进行守护。 命令如下: yum -y install …...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
