一、需求
接到公司产品的需求,需要在系统中做埋点日志,记录用户调用每一个接口的的功能日志,简而言之就是这个用户每天对系统的操作需要做日志保存。后续可以让用户或者用户上级查看。
二、技术实现
需使用技能点:Springboot+AOP+Mysql+Mybatis-plus实现
实现详细:利用Spring的AOP特性配合自定义注解对方法做一个增强,在增强中通过解析token来记录每一个用户的操作记录;
日志表(user_operate_log)设计:
user_id int 用户ID
operate varchar 操作功能
create_time datetime 创建时间
对应实体对象:
此处使用mybatis-plus实现需要读者自己整合进springboot中
/**
* @Author: whr
* @TODO: 用户操作记录对象
* @Date: create in 2021/3/11 17:37
*/
@Data
@TableName("user_operate_log")
@AllArgsConstructor
@NoArgsConstructor
public class UserLog {
/**
* 用户ID
*/
@TableId(value = "user_id",type = IdType.AUTO)
private int userId;
/**
* 接口功能
*/
private String operate;
/**
* 操作时间
*/
private LocalDateTime createTime;
}
编写日志对象对应Mapepr
/**
* @Author: whr
* @TODO: 用户操作日志记录接口
* @Date: create in 2021/3/11 19:02
*/
@Mapper
public interface UserOperateLogMaper extends BaseMapper<UserLog> {
}
编写自定义注解以及方法增强:
/**
* @Author: whr
* @TODO: 用户操作实现日志
* @Date: create in 2021/3/11 17:22
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserOperateLog {
/**
* 用户ID(由于此处是测试,解析token就省了,直接打注解传入)
* @return int
*/
int userId();
/**
* 接口功能
* @return string
*/
String operate();
}
AOP增强实现:
/**
* @Author: whr
* @TODO: 用户操作日志增强
* @Date: create in 2021/3/11 17:28
*/
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class UserOperateLogAspect {
/**
* 操作新增mapper
*/
private final UserOperateLogMaper userOperateLogMaper;
@Pointcut("@annotation(UserOperateLog)")
public void pointCut() {
}
/**
* 用户操作记录db
*
* @param joinPoint 方法信息
* @param userOperateLog 注解参数
*/
@Before("pointCut()&&@annotation(userOperateLog)")
public void saveUserOperate(JoinPoint joinPoint, UserOperateLog userOperateLog) {
save(userOperateLog);
}
@Async
public void save(UserOperateLog userOperateLog) {
userOperateLogMaper.insert(new UserLog(userOperateLog.userId(), userOperateLog.operate(), LocalDateTime.now()));
}
}
测试接口:
/**
* @Author: whr
* @TODO: 用户操作接口
* @Date: create in 2021/3/11 19:08
*/
@Slf4j
@RestController
@AllArgsConstructor
public class UserOperateController {
@UserOperateLog(userId = 1, operate = "查看操作日志")
@GetMapping("/user")
public R getList() {
log.info("用户埋点日志测试");
return R.ok();
}
}
三、测试
调用接口,查看数据库
功能实现;此处只是测试,过于简单,只是把原理和设计呈现给大家,不喜勿喷