java切面做日志记录

Java项目 日志框架+切面,完美记录 Java Spring Boot项目搭建日志框架,创建日志切面,方便追溯 阅读详情

前言

     众说周知,aop是oop思想的延续,是为了我们更好的程序的开发, 更便于我们对技术及代码的维护。
 今天就利用aop来做一个日志的记 录。废话不多说,上代码。

实例

entity

import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name="tb_operate_record")
@Data
@NoArgsConstructor
public class TbOperateRecord implements Serializable {

    private static final long serialVersionUID = 4907931420975674126L;
    
    @Id
    @GeneratedValue(generator ="paymentableGenerator")
    @GenericGenerator(name ="paymentableGenerator", strategy = "uuid")
    @Column(name= "log_record_id")
    private String id;     // 主键 采用UUID 策略目的是为了适配数据库(具体项目可以选择合适的生成策略)
    
    @Column(name="input_Params")
    private String inputParams; //方法输入的参数
    
    @Column(name="user_name")
    private String userName; //操作人
    
    @Column(name="operate_description")
    private String operateDescription ; //用户操作记录描述
    
    @Column( name = "req_ip")
    private String reqIp;  //请求ip地址
    
    @Column(name="req_url")
    private String reqUrl; //请求reqURL
    
    @Column(name = "take_time")
    private String  takeTime; //耗时
    
    @Column(name="operate_time")
    private String  operateTime; //操作时间
    
    @Column(name= "method_description")
    private String methodDescription; //接口功能描述
    
    @Column(name="method_name")
    private String methodName; //方法名

切面类

@Component
@Aspect
public class LoggerRecord {

    private final  static Logger logger = LoggerFactory.getLogger(LoggerRecord.class);

    private final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 规定日期格式

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private TbOperateRecordRepository tbOperateRecordRepository;

    //定义切点
    @Pointcut(value = "execution(* com.*.controller.*.*(..))")
    public void  PointCutJcLog(){

    }
    @Around(value = "PointCutJcLog()")     //编写逻辑
    public Object saveJcRecordLogger(ProceedingJoinPoint joinPoint)throws Throwable{
        TbOperateRecord operateRecord = new TbOperateRecord();  //创建日志记录对象
        long startTime = System.currentTimeMillis();
        Object retVal = joinPoint.proceed();
        long entTime = System.currentTimeMillis();
        String consumeTime = formatDuring(entTime - startTime);
        operateRecord.setTakeTime(consumeTime);
        operateRecord.setOperateTime(df.format(new Date()));
        //从session中取出用户及部门信息
        getUserInfo(operateRecord); //获取用户信息方法
        //创建日志操作对象
        Class<?> target = joinPoint.getTarget().getClass();
        getJcLoggerSource(operateRecord, target); //获取日志目录
        MethodSignature signature =(MethodSignature)joinPoint.getSignature(); //从切面织入点处通过反射机制获取织入点处的方法
        Method method = signature.getMethod();
        operateRecord.setMethodName(method.getName());
        getUsingAndInterfaceFunction(operateRecord, method); //获取用途及接口功能描述
        Object[] args = joinPoint.getArgs();
        getRequestAgrs(operateRecord, args);
        String remoteAddr = request.getRemoteAddr();//获取请求地址
        operateRecord.setReqIp(remoteAddr);
        String url = request.getRequestURL().toString();
        operateRecord.setReqUrl(url);
        try {
            tbOperateRecordRepository.save(operateRecord);
            logger.info("操作日志记录成功");
        } catch (Exception e) {
            logger.error("操作日志记录新增失败",e.getMessage());
        }
        return  retVal;  // 使用 ProceedingJoinPoin 该类必须返回,即释放拦截的
    }
  
    //获取请求参数
    private void getRequestAgrs(TbOperateRecord operateRecord, Object[] args) {
        if(null!= args){
            List<Map<String, Object>> paramsMap = new ArrayList<Map<String, Object>>();
            HttpServletRequest request;
            for (int i = 0; i <args.length ; i++) {
                try{
                    request = (HttpServletRequest) args[i];  //过滤参数为接口类型的
                    //如果是HttpServletRequest则跳过
                    continue;
                }catch (Exception e){
                    ConcurrentHashMap<String, Object> eachParam = new ConcurrentHashMap<>();
                    eachParam.put("第"+(i+1)+"参数",args[i]);
                    paramsMap.add(eachParam);
                }
            }
            String content = JSON.toJSONString(paramsMap);
            operateRecord.setInputParams(content);

        }else{
            operateRecord.setInputParams("该方法没有请求参数");
        }
    }
    //记录信息的组装
    private void getOperateDescription(TbOperateRecord operateRecord, String name) {
        String description = "";
        StringBuffer buffer = new StringBuffer("用户【");
        description = buffer.append(operateRecord.getUserName() + "】,于【")
                .append(operateRecord.getOperateTime() + "】,执行【")
                .append(operateRecord.getMethodDescription()+ "】操作,请求接口【")
                .append(name + "】,请求ip【")
                .append(operateRecord.getReqIp() + "】,请求参数【")
                .append(operateRecord.getInputParams() + "】").toString();
        operateRecord.setOperateDescription(description);
    }

    //请求耗时计算
    public static String formatDuring(long time) {
        long minutes = (time % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (time % (1000 * 60)) / 1000;
        long subsec = time % 1000;
        return minutes + "分钟," + seconds + "秒," + subsec + "毫秒 ";
    }

// 用户信息的获取 (根据自己项目封装的工具类取值)
 private void getUserInfo(TbOperateRecord operateRecord) {
        String userName="";
        try {
            Session currentUser = Session.getCurrentUser(request.getSession());
            UserInfo userinfo = currentUser.getUserinfo();
            if(null !=userinfo){
                  userName = userinfo.getUserName();
            }
        } catch (Exception e) {
            logger.error("未获取当前登录人相关信息",e.getMessage());
        }
        operateRecord.setUserName(userName);

    }

Repository

import com.sanling.credit.wd.entity.TbOperateRecord;
import org.springframework.data.jpa.repository.JpaRepository;
public interface  TbOperateRecordRepository extends JpaRepository<TbOperateRecord,String> {
}

注意

提高篇:

https://blog.youkuaiyun.com/WindwirdBird/article/details/110129276

切点的选择及正则的写法很重要,必须写对

execution使用

https://blog.youkuaiyun.com/WindwirdBird/article/details/110201365

java使用AOP切面获取请求日志并记录 关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦[外链图片转存中…(img-ff2nhJh9-1714129089178)] 阅读详情

相关推荐

[Java实战]Spring Boot切面编程实现日志记录(三十六)

Spring Boot切面编程实现日志记录

曼岛_的博客 1971

【Java日志系列实践2】AOP切面实现业务日志

1 业务日志的标准 业务日志,也叫操作日志。主要功能: 记录用户行为,方便业务数据回溯与统计。 1.1 操作日志记录内容 操作日志记录主要内容:用户是谁,在什么时间,对什么数据,做了什么样的更改。 逻辑中必须增加业务日志的位置: (1)业务数据的变更处(新增、修改、删除) (2)特别分支条件、边界条件处。 1.2 业务常见的日志记录形式 ● 动态的文本记录,比如:2022-03-12 10:00 订单创建,创建用户“小新”,订单号:NO.123456 ”。 ● 修改类型的文本,包含修改前和修改后的

我的技术日常 6379

立创EDA开源足轮机器人:基于STM32F407与ESP32的LQR自平衡与FOC驱动设计全解析

本文详细解析了基于立创EDA平台的开源足轮机器人项目。该项目采用STM32F407作为主控,ESP32负责无线通信,并应用LQR自平衡算法与FOC驱动技术,实现了机器人的稳定站立、移动转向及复杂地形适应能力。文章深入剖析了其硬件架构、软件设计及调试经验,为机器人运动控制学习提供了宝贵参考。

weixin_42608299的博客 232

Java利用Aop切面记录操作日志(注解方式)

⾯向切⾯编程,它是⼀种思想,它是对某⼀类事情的 集中处理。⽽ AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,提供了⼀种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。@Mapping/*** 操作具体某个功能的描述* @return*//*** 操作类型* @return*/@Aspect@Component@Autowired@Autowired@Autowired@Autowired// 获取request对象。

“种一棵树最好的时间是十年前,其次就是现在。” 3304

6.5 构网型储能系统的协同控制策略

本文系统阐述了构网型储能系统的协同控制策略,重点分析了多机组群协同运行面临的功率分配不均、动态响应失配等挑战。研究提出了改进型下垂控制与虚拟阻抗法、基于一致性算法的分布式协同控制等解决方案,探讨了构网型储能与同步发电机在惯性响应、一次调频等方面的协同机制,以及与跟网型电源在电压支撑、阻抗重塑等方面的互补作用。文章构建了分层控制架构,为实现多类型电源的全局优化运行提供了技术路径,对提升高比例新能源电力系统的稳定性具有重要意义。

技术工作者 1005

2025年从零开始:构建你的首个ComfyUI工作流-ComfyUI入门教程

然而,由于它拥有众多的插件节点,以及较为复杂的操作流程,学习起来相对困难。以前面搭建的文生图工作流为例,首先点击功能区的【保存】,然后你的浏览器会出来一个弹窗,你可以进行文件命名,点击确定后浏览器会下载该文件,也就是带“json”后缀的文件,这样我们的工作流就打包成一份文件了。思考一下前面说的,节点是不是需要下载安装才能使用,而我们复用别人的工作流,他用的节点你不一定下载了,因为目前有600多个节点,你不可能全部下载了吧,所以我们日后使用别人的工作流,你会经常出现这样的问题。

weixin_59486588的博客 1456

java面向切面编程AOP案例,记录请求日志

aop的使用

w_iceh的博客 2475

PC微信逆向:破解聊天记录文件!_读取别人pc微信msg文件

本文详细介绍了PC版微信数据库的解密方法,总结了前人经验并补充了关键细节。通过OllyDbg调试工具从微信内存中获取32字节加密密钥,使用C++结合OpenSSL库实现解密程序。重点解决了开发环境配置问题,包括Visual Studio项目设置和OpenSSL库的版本适配,将原本固定的数据库路径改为参数化输入,提高了工具的通用性。该方案为电子取证中的微信数据提取提供了完整的技术路径,避免了研究者重复探索已解决的问题。

zz96405784848的博客 9769

java中日志切面_java切面做日志记录

前言众说周知,aop是oop思想的延续,是为了我们更好的程序的开发, 更便于我们对技术及代码的维护。今天就利用aop来做一个日志的记 录。废话不多说,上代码。实例entityimport lombok.Data;import lombok.NoArgsConstructor;import org.hibernate.annotations.GenericGenerator;import javax...

weixin_32584595的博客 1283

【Bluetooth蓝牙开发】一、开篇词 | 打造全网最详细的Bluetooth开发教程

1、开篇词 2、蓝牙开发入门 3、蓝牙协议栈总览 4、蓝牙协议栈——物理层 5、蓝牙协议栈——链路层 6、蓝牙协议栈——传输层 7、蓝牙协议栈——L2CAP协议 8、蓝牙协议栈——ATT协议 9、蓝牙协议栈——GATT协议 10、蓝牙通信流程分析 11、蓝牙协议栈——Bluez交叉编译 12、蓝牙调试工具汇总

Donge's Blog 1万+

【目录】专栏文章导航

从最强工具链Davinci Configurator模块学习出发掌握AUTOSAR

weixin_47571898的博客 3301

使用AOP切面实现日志记录功能

说到AOP大家都可以想到他是面向切面的编程,它通过将横切关注点(例如日志记录、事务管理、权限控制等)从主要业务逻辑中分离出来,以模块化的方式进行管理。在AOP中,通过定义切面(Aspect)来捕获和处理横切关注点,然后将其应用于特定的目标对象或方法。官方的解释有点抽象,我们举个例子说明:假设我们需要在多个方法中添加日志记录功能。传统的方式是在每个方法中都添加日志代码,但这样会导致代码重复,并且当我们需要修改日志记录逻辑时,需要逐个修改所有方法。

心态的博客 6217

Debezium系列之:使用指定值替代指定字段的值

Debezium系列之:使用指定值替代指定字段的值

zhengzaifeidelushang的博客 306

切面编程的优势与实践技巧

本阶段将重点讨论切片和切面的核心区别,并通过实际应用总结切面编程的优势与实践技巧。本文特别适合初学者,结合详细代码示例与注释帮助你深入理解 Java AOP 技术。

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 1万+

[AI] 嵌入模型选择:bge / text-embedding-3 / Jina Embeddings 对比与选型指南

摘要: 本文对比了BGE-M3、OpenAI和Jina三种主流嵌入模型在语言覆盖、性能、延迟、维度和成本等维度的差异。BGE-M3适合中文场景,本地部署成本低;OpenAI API多语能力强但依赖网络;Jina在多语表现突出但需关注商用许可。测试显示BGE-M3本地延迟3-6ms,OpenAI API延迟200-600ms。选型建议:隐私场景选BGE本地部署,多语低维护选OpenAI,高精度选Jina。部署时需注意批处理优化、向量库压缩和商用许可等问题,建议建立评测指标并监控关键指标。

每日出拳老爷子的博客 428

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spring+logBack+AOP 在切面上做日志记录

业务场景 基本上每个项目中都会有性能需求,但是性能优化又没有现成的模式可以套用。因为每个项目的业务特点以及结构特点,我们需要采集实际运行中的耗时数据来进行性能分析,采取具有针对性的优化方案。如何在Spring工程并且是代码低侵入性的条件下做耗时数据记录,将是本篇博客的重点。 环境 语言:java 框架:Spring(本文采用Spring族中的SpringBoot) 主要工具:Aspect,log...

NoNoEscape的博客 1271

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

切面实现对controller层进行统一日志记录

切面实现对controller层进行统一日志记录切面通用父类自定义注解需要的一些工具类业务模块使用 本文章项目开源地址 切面通用父类 这里实现通用父类,里面写好了对请求的信息(url、方法、请求头信息、参数)等信息,并对执行的controller的方法名、方法参数值进行记录,无论方法执行完成或者执行异常都会有相应的记录输出。各个业务模块需要继承这个父类,并重新切片的方法,以此实现自定义切入点。这里...

qq_33140565的博客 2244

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

springAOP面向切面编程之日志记录功能

关于AOP: 这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代

一只喜欢学习的猪仔 1万+

SpringBoot 使用 AOP 切面对请求进行日志记录

SpringBoot 使用 AOP 切面对请求进行日志记录

weixin_46619605的博客 1048

java:AOP面向切面编程

AOP是什么:一种将横切关注点(日志、事务等)与核心业务逻辑分离的技术。如何实现:Spring AOP通过动态代理在运行时将切面“织入”到目标方法中。核心注解@Aspect@Pointcut@Around@Before@After等。为何需要:实现解耦、提高代码的可复用性和可维护性,让开发者能更专注于核心业务逻辑。通过AOP,我们可以以一种非常优雅和非侵入式的方式,为应用程序添加强大的功能。

talenteddriver的博客 1771

java 对 openfeign 接口做切面

我整理的一些关于【Java】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/bLN8S1Java 对 OpenFeign 接口做切面 在现代微服务架构中,OpenFeign 是一个非常流行的声明式 HTTP 客户端工具,它的简洁性和易用性使得开发者在与 RESTful API...

weixin_29137599的博客 445

springboot中两种方式配置切面

在工作中做项目微服务化,需要把原来老的项目拆分成一个个小的接口对外提供服务。对拆分出来的接口,需要做权限控制与入参,出参,耗时等日志记录。于是做个了切面类,来通过切面对相应方法做记录。 1.首先我们需要引入相应的jar包 &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId...

zhuxingKevin的博客 1万+

Java aop切面

切面(Aspect)是面向切面编程(AOP)的核心概念,用于封装横切关注点(如日志记录、事务管理、安全控制等),在不修改主业务逻辑代码的情况下,动态插入到主业务流程中。通过切面,可以实现代码的模块化和复用,提升程序结构的清晰度和可维护性。在Spring框架中,使用@Aspect注解定义切面类,并通过切入点表达式指定切点。切面广泛应用于日志记录、事务管理、安全控制等场景,显著提高了代码的复用性和可维护性。

C_V_Better的博客 2107

Java AOP实践指南:切面编程详解

通过本文的讲解,我们深入了解了切面编程的核心概念、动态代理的实现原理,并通过一个实际的例子展示了使用Java AOP的完整过程。AOP可以帮助我们将横切关注点(例如日志记录、事务管理等)从核心业务逻辑中解耦出来,提高代码的可维护性和重用性。同时,AOP也是实现设计模式和架构思想的重要手段之一,我们在开发中可以灵活运用AOP来优化代码结构并提高系统的整体性能。

xuewenyu_的博客 7315

java用注解@annotation和切面@Aspect实现日志记录

1.日志切面定义 @Aspect @Component public class LogAspect { @Around(value = "@annotation(log)") public Object log(ProceedingJoinPoint joinPoint, Log log) throws Throwable { Object result =...

陈俊的马蹄印 4490

十:SpringBoot-配置AOP切面编程,解决日志记录业务

SpringBoot-配置AOP切面编程,解决日志记录业务1、AOP切面编程1.1 AOP编程特点1.2 AOP中术语和图解2、SpringBoot整合AOP2.1 核心依赖2.2 编写日志记录注解2.3 编写日志记录的切面代码2.4 请求日志测试2.5 异常日志测试 1、AOP切面编程 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热

爱是与世界平行 1377
上一篇: Oracle创建数据库及迁移命令
下一篇: 状态码415解决
WindwardBird
博客等级 码龄7年 19粉丝 94原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值