【Spring】自定义注解 + AOP 记录用户的使用日志

news2024/12/23 9:06:31

目录

​编辑

自定义注解 + AOP 记录用户的使用日志

使用背景

落地实践

一:自定义注解

二:切面配置

三:Api层使用

使用效果


自定义注解 + AOP 记录用户的使用日志

使用背景

(1)在学校项目中,安防平台实际的使用人员大多都是外聘人员,用户的一些关键操作最好记录清楚,像是青岛工程职业学院网络及监控系统项目中,有个功能是对全校学生权限的一键冻结和解冻。

(2)对接非常强势的第三方数据时,例如腾讯的腾讯微卡产品,虽然是他们将数据接入到海康平台,但仍然不接受定制,我们必须按照腾讯的接口协议,提供给他们接口。注意:此时没有办法走OpenApi,而请假数据是每天有推送的,为了一旦出现问题可回溯,需要记录完整的数据日志。

落地实践

一:自定义注解

配置自定义注解“LogPoint”,之后会用在关键的接口上,作为切入点来记录该接口的访问信息。


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface LogPoint {
    /***
    * @Description 日志描述
    * @return java.lang.String
    */
    String description() default "";
}

 

二:切面配置

1.在切面里,我们可以配置请求参数的详细信息逐条打印,和响应结果与它的耗时记录,这些打印信息足以应对现场的大多数问题。

2.不用担心info日志打印过多的问题,只需要把注解标注在关键的接口,与多占的那些硬盘空间相比,这些信息能帮助技术和研发节省更多的时间,更具性价比。

    
    /**
     * @ClassName AspectLogConfig
     * @Description 出入参日志配置类
     * @Version 1.0
     **/
    @Aspect
    @Component
    @Slf4j
    public class LogConfig {
        private final static Logger logger = LoggerFactory.getLogger(LogConfig.class);
    
        @Pointcut("@annotation(com.hikvision.pea.common.annotation.LogPoint)")
        public void logPoint() {
        }
    
        /***
         * @Description 切入点之前织入
         * @Param []
         * @return void
         */
        @Before("logPoint()")
        public void doBefore(JoinPoint joinPoint) throws Throwable {
            //开始打印请求日志
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
    
            //打印请求相关参数
            logger.info("================== start ==================");
    
            //打印请求 url
            logger.info("URL              : {}", request.getRequestURL().toString());
            //打印描述信息
    
            //打印HTTP method
            logger.info("HTTP Method      : {}", request.getMethod());
            //打印调用 controller 的全路径以及执行方法
            logger.info("Class Method     : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
            //打印请求的ip
            logger.info("IP               : {}", request.getRemoteAddr());
            //打印请求入参
            logger.info("Request Args     : {}", joinPoint.getArgs());
        }
    
        @After("logPoint()")
        public void doAfter() throws Throwable {
    
        }
    
        /***
         * @Description 环绕
         * @Date 14:35 2022/6/23
         * @Param [proceedingJoinPoint]
         * @return java.lang.Object
         */
        @Around("logPoint()")
        public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            long startTime = System.currentTimeMillis();
            //执行切点
            Object result = proceedingJoinPoint.proceed();
            logger.info("打印出参 : {}", result);
            logger.info("执行耗时 : {} ms", System.currentTimeMillis() - startTime);
            logger.info("================== end ===================" + System.lineSeparator());
            return result;
        }
    }

 

三:Api层使用

只需要将注解加在对应的接口上,无需其它编码。

/**
 * @ClassName ResourceController
 * @Description 门禁点控制器
 * @Version 1.0
 **/

@Api(tags = "门禁点控制器")
@RestController
@RequestMapping("/resource")
@Slf4j
public class ResourceController {
    @Autowired
    IResourceService iResourceService;

    @ApiOperation("获取门禁点资源")
    @PostMapping("/doorSources")
    @LogPoint(description = "获取门禁点资源")
    public ResponseData getDoorSources(@ApiParam("入参") @RequestBody ResourceReqVo resourceReqVo) {
        Page<Resource> resources = iResourceService.getResources(resourceReqVo);
        return ResponseData.success(resources);
    }
}

 

使用效果

将调用方的请求参数、IP、响应结果、耗时,都完整的打印出来,一旦出现外聘人员误操作或者三方数据不匹配,通过这些信息,定位起问题来都非常方便。

在这里插入图片描述

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里计算巢:开启数据集市场的宝库,助力AI研究和应用

阿里计算巢 阿里数据巢提供了一个丰富的数据集市场&#xff0c;官方地址&#xff1a; https://computenest.console.aliyun.com/dataset/service/cn-hangzhou 可以看到数据集内容涵盖了多个领域&#xff0c;且还在不断增加中。关键是免费&#xff01;且支持下载到本地。 以下…

oracle 根据身份证号码与指定日期计算年龄

自定义函数&#xff1a; CREATE OR REPLACE FUNCTION 获取年龄(身份证号 varchar2, 指定时间 date) RETURN varchar2 AS 年龄 varchar2(16); BEGINif length(身份证号) >18 thenSELECT TRUNC( MONTHS_BETWEEN(指定时间, TO_DATE(SUBSTR(身份证号, 7, 8), YYYYMMDD) …

Django学习记录01

1.项目结构 djangoProject02 ├── manage.py 【项目的管理&#xff0c;启动项目、创建app、数据管理】【不要动】【常常用】 └── jangoProject02 ├── __init__.py ├── settings.py 【项目配置】 【常常修改】 ├── urls.py …

Linux 查看系统信息 + 服务信息命令(简记)

概述 作用&#xff1a;Linux 运维工作中常用的命令速查 小步教程 (xiaobuteach.com) Linux 命令大全 | 菜鸟教程 (runoob.com) 文本编辑器vim 本章大纲 | 小步教程 vim 多文件编辑 | 小步教程 常用 ps 查看服务启动命令 Linux ps 命令 | 菜鸟教程 (runoob.com) # 查找…

Linux进程信号处理:深入理解与应用(2​​)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;its 6pm but I miss u already.—bbbluelee 0:01━━━━━━️&#x1f49f;──────── 3:18 &#x1f504; ◀️…

32ADC模数转换器&AD单通道&多通道

目录 一.简介 二.逐次逼近法​编辑 三.结构框图 四.小tips (1)转换模式 &#xff08;2&#xff09;触发控制 &#xff08;3&#xff09;数据对齐 &#xff08;4&#xff09;转换时间 &#xff08;5&#xff09;校准 &#xff08;6&#xff09;硬件电路 五.相关函数 …

Java语法学习IO流

Java语法学习IO流 大纲 文件IO流 具体案例 1. 文件 基本介绍 创建文件 第一种&#xff1a; public static void main(String[] args) {String filePathName "d:\\news1.txt";File file new File(filePathName);try {file.createNewFile();} catch (IOExceptio…

vulhub中Apache Druid 代码执行漏洞复现(CVE-2021-25646)

Apache Druid是一个开源的分布式数据存储。 Apache Druid包括执行嵌入在各种类型请求中的用户提供的JavaScript代码的能力。这个功能是为了在可信环境下使用&#xff0c;并且默认是禁用的。然而&#xff0c;在Druid 0.20.0及以前的版本中&#xff0c;攻击者可以通过发送一个恶…

2018 年全国职业院校技能大赛高职组“信息安全管理与评估”赛项任务书(笔记解析)

1. 网络拓扑图 2. IP 地址规划表 3. 设备初始化信息 阶段一 任务 1:网络平台搭建 1、根据网络拓扑图所示,按照 IP 地址参数表,对 WAF 的名称、各接口 IP 地址 进行配置。 2、根据网络拓扑图所示,按照 IP 地址参数表,对 DCRS 的名称、各接口 IP 地址 进行配置。 3、根据网…

C++项目 -- 高并发内存池(二)Thread Cache

C项目 – 高并发内存池&#xff08;二&#xff09;Thread Cache 文章目录 C项目 -- 高并发内存池&#xff08;二&#xff09;Thread Cache一、高并发内存池整体框架设计二、thread cache设计1.整体设计2.thread cache哈希桶映射规则3.TLS无锁访问4.thread cache代码 一、高并发…

CCF迎来新风采:揭晓2024-2026年度执行机构负责人名单!

会议之眼 快讯 中国计算机学会&#xff08;CCF&#xff09;成立于1962年&#xff0c;是一家全国性学会&#xff0c;拥有独立社团法人地位&#xff0c;同时是中国科学技术协会的会员单位。作为中国计算机及相关领域的学术团体&#xff0c;CCF的宗旨在于为该领域专业人士的学术和…

C

extern int a; //同一个项目声明 int r a > b ? a : b; 错误 scanf 不输入‘\n’,getchar()输入\n; printf()返回值 0次 system("cls"); 可以调用命令行函数 time(NULL)时间戳 srand((unsigned)time(NULL)); //随机数种子 int rev rand()%1001; //随…

Linux---yum命令详解

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 目录 1.概念2.yum的配置信…

Open CASCADE学习|拓扑变换

目录 平移变换 旋转变换 组合变换 通用变换 平移变换 TopoDS_Shape out;gp_Trsf theTransformation;gp_Vec theVectorOfTranslation(0., 0.125 / 2, 0.);theTransformation.SetTranslation(theVectorOfTranslation);BRepBuilderAPI_Transform myBRepTransformation(out, th…

一篇文章了解区分指针数组,数组指针,函数指针,链表。

最近在学习指针&#xff0c;发现指针有这许多的知识&#xff0c;其中的奥妙还很多&#xff0c;需要学习的也很多&#xff0c;今天那我就将标题中的有关指针知识&#xff0c;即指针数组&#xff0c;数组指针&#xff0c;函数指针&#xff0c;给捋清楚这些知识点&#xff0c;区分…

【Linux取经路】进程控制——程序替换

文章目录 一、单进程版程序替换看现象二、程序替换的基本原理三、程序替换接口学习3.1 替换自己写的可执行程序3.2 第三个参数 envp 验证四、结语一、单进程版程序替换看现象 #include <stdio.h> #

【Funny guys】龙年专属测试鼠标寿命小游戏...... 用Python给大家半年了......

目录 【Funny guys】龙年专属测试鼠标寿命小游戏...... 用Python给大家半年了...... 龙年专属测试鼠标寿命小游戏用Python给大家半年了贪吃龙游戏 文章所属专区 码农新闻 欢迎各位编程大佬&#xff0c;技术达人&#xff0c;以及对编程充满热情的朋友们&#xff0c;来到我们的程…

Spring Boot + flowable 快速实现工作流

背景 使用flowable自带的flowable-ui制作流程图 使用springboot开发流程使用的接口完成流程的业务功能 文章来源&#xff1a;https://blog.csdn.net/zhan107876/article/details/120815560 一、flowable-ui部署运行 flowable-6.6.0 运行 官方demo 参考文档&#xff1a; htt…

SpringBoot整合Flowable最新教程(二)启动流程

介绍 文章主要从SpringBoot整合Flowable讲起&#xff0c;关于Flowable是什么&#xff1f;数据库表解读以及操作的Service请查看SpringBoot整合Flowable最新教程&#xff08;一&#xff09;&#xff1b;   其他说明&#xff1a;Springboot版本是2.6.13&#xff0c;java版本是1…

4. 树(二叉树、二叉查找树/二叉排序树/二叉搜索树、平衡二叉树、平衡二叉B树/红黑树)

树 1. 二叉树1.1 概述1.2 特点1.3 二叉树遍历方式1.3.1 前序遍历(先序遍历)1.3.2 中序遍历1.3.3 后序遍历1.3.4 层序遍历 2. 二叉查找树&#xff08;二叉排序树、二叉搜索树&#xff09;2.1 概述2.2 特点 3. 平衡二叉树3.1 概述3.2 特点3.3 旋转3.3.1 左旋3.3.2 右旋 3.4 平衡二…