我用注解实现接口的操作流水日志

IT实战联盟 2020-12-08 09:54:26 ⋅ 85 阅读

作者:Lvshen的技术小屋 
原文:https://www.toutiao.com/i689551231529549876

在项目中,我们会需要获取接口的操作日志。比如获取接口的接口名、操作人,接口运行时间、所属的服务、接口的类型(增删改查)等等。初级的做法是在接口方法执行完后将这些操作记录存入库中,这段代码写在接口中,但是这样违反了设计原则中的单一职责原则。常用的做法是使用AOP来做,在运行时动态的插入日志记录的代码。这里我是用注解来做。

创建日志记录表

首先我们来创建日志记录表:

我用注解实现接口的操作流水日志

 

operation表

当然后编写实体类:

我用注解实现接口的操作流水日志

 

编写日志记录注解

我们先定义一个注解OperationLog

我用注解实现接口的操作流水日志

 

这个注解里面定义了几个参数:

opType:业务类型

opBusinessName:业务名称,例如会员服务、订单服务等等

opBusinessId:业务来源ID,一般为主键ID

定义业务类型类OperationType

我用注解实现接口的操作流水日志

 

这个业务类型类定义了接口的类型:增删改查。

接下来我们编写切面类OperationLogAspect

获取方法上面的注解:

Method method = ((MethodSignature) pjp.getSignature()).getMethod();
//获取目标方法上面的注解
OperationLog opLog = method.getAnnotation(OperationLog.class);

执行目标方法:

try {
    // 执行目标方法
    result = pjp.proceed();
} catch (Throwable throwable) {
    throw new Exception(throwable);
}

在执行目标方法前后记录执行时间:

TimeInterval timer = DateUtil.timer();
...
 // 执行目标方法
...
long executeTime = timer.intervalRestart(); 

解析注解上的表达式,就是获取业务id:

// 解析表达式,获取结果
String itemId = String.valueOf(expression.getValue(context));

将数据封装到对象中:

Operation operation = Operation.builder()
                    //.id(snowflake.nextId())
                    .opType(opLog.opType().name())
                    .opBusinessName(opLog.opBusinessName())
                    .opBusinessId(itemId)
                    .opTime(String.valueOf(executeTime))
                    //这里可以添加操作人
                    .build();

记录日志并入库:

private void handle(Operation operation) {
    // 通过日志打印输出
    log.info("opType = " + operation.getOpType() + ",opItem = " + operation.getOpBusinessName() + ",opItemId = " + operation.getOpBusinessId() + ",opTime = " + operation.getOpTime());
    // 持久化入库
    operationService.save(operation);
}

整体代码如下:

我用注解实现接口的操作流水日志

 

测试注解

测试注解代码如下:

@RequestMapping("/getById")
@ResponseBody
@OperationLog(opType = OperationType.QUERY,opBusinessName = "会员服务",opBusinessId = "#id")
public Member getById(@RequestParam String id) {
    return memberService.getById(id);
}

我们在这个接口getById上添加了注解@OperationLog,表明我们想记录这个接口的操作记录。opType为查询类型,所属的业务为会员服务,业务id为接口的参数id。

启动代码运行接口:

我用注解实现接口的操作流水日志

 

控制台打印了日志:

我用注解实现接口的操作流水日志

 

并且数据库也有了记录:

我用注解实现接口的操作流水日志

 

代码到这里就结束了,当然我们还可以在日志记录表中添加接口名的路径、以及接口的调用链等信息。


全部评论: 0

    我有话说:

    采集Nginx几种方式

    来源 | https://dwz.cn/ofiCxRK0 由于nginx功能强大,性能突出,越来越多web应用采用nginx作为http和反向代理web服务器。而nginx访问日志不管是做

    「转载」微服务分布式架构中,如何实现日志链路跟踪?

    背景 开发排查系统问题得最多手段就是查看系统,在分布式环境中一般使用ELK来统一收集,但是在并发大时使用日志定位问题还是比较麻烦,我们来看下面图     上图

    京东技术:面对海量流量七步走保证用户体验(部分操作能够快速实战

    当促销活动正式开始时,不少用户开启了价格保护,在此高并发情况下,如何保证用户体验,如何保证系统稳定性、高可、快速计算结果,是本文重点。

    smart-doc 2.0.0 重磅发布,Java 零注解 API 文档生成工具

    smart-doc是一款同时支持java restful api和apache dubbo rpc接口文档生成工具,smart-doc颠覆了传统类似swagger这种大量采用注解侵入来生成文档

    老板要开发一个简单工作流引擎

    第1关 一天,老板找到,说要做个简单工作流引擎。 查了一天啥是工作流,然后做出了如下版本: 按顺序添加任意个审批人组成一个链表,最后加一个结束节点 记录当前审批人,当审批完后,审批人向后

    SQL判断是否"存在",还在 count 操作

    来源:http://toutiao.com/i6826511837840802315 根据某一条件从数据库表中查询 『有』与『没有』,只有两种状态,那为什么在写SQL时候,还要SELECT

    【收藏】18 个 Java8 日期处理实践,太有了!

    实例来学习如何使用新API。 Java处理日期、...

    好文推荐:是如何redis做实时订阅推送

    目前项目已上前线,运行平稳~~~

    手把手教你Spring Cloud + Redis 是实现点赞功能,包教包会

    ; 这玩意是怎么实现呢?来手把手教你实现,其...

    MongoDB 数据库基本操作(二)

    MongoDB 是一个基于分布式文件存储数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展高性能数据存储解决方案。

    职场:面试过那些烂技术大哥

    马有千里之程,无骑不可自往。人有冲天之,无运不能自通。

    「强烈推荐」这是看过最接“地气”代码问题与重构实践

      写这个文章是因为前段时间确实因为公司业务开发太忙太紧,所有开发都处在于加班赶项目,并且加入新人较多造成了一系列代码不可控质量问题。 文章针对这段时间代码出现各种各样问题

    Martian-cloud 4.0,跟注册中心拜拜了,基于传染机制分布式组件诞生

    这次真要跟注册中心讲拜拜了,微服务不再需要占用一套注册中心集群了,大大节约了运维成本 更新点如下 丢弃了一开始【生产者->注册中心->消费者】模型 采用传染机制,实现服务发现与

    关于MySQL 通用查询日志和慢查询日志分析

    MySQL中日志包括:错误、二进制、通用查询、慢查询日志等等。这里主要介绍下比较常用两个功能:通用查询日志和慢查询

    Excelize -Go 开源项目中唯一支持复杂样式 XLSX 文件类库

    Go 语言编写一个操作 Office Excel 文档类库

    SpringBoot 整合SpringSecurity示例实现前后分离权限注解+JWT登录认证

    一.说明 SpringSecurity是一个用于Java 企业级应用程序安全框架,主要包含用户认证和用户授权两个方面.相比较Shiro而言,Security功能更加强大,它可以很容易地扩展以满足

    精品推荐:如何实现一个TCC分布式事务框架一点思考

    本文将以Spring容器为例,试图分析一下,实现一个通用TCC分布式事务框架需要注意一些问题。

    mongoHelper 0.3.9 发布,spring-data-mongodb 增强工具包,简化 CRUD 操作

    mongoHelper 是基于 spring-data-mongodb 增强工具包,简化 CRUD 操作,提供类 jpa 数据库操作。 传统关系型数据库及围绕它们构建 orm 在项目开发中有很

    生产技巧:如何不停机修改Zookeeper日志路径?

    咪咕Kafka及Zookeeper是分离部署(即:未使用Kafka本身自带Zkper),故而要想修改Zookeeper,需如下操作...