微服务操作日志拦截

拦截类UserLogAopAspect

@Slf4j
@Aspect
@Component
@Order(AopOrderConst.LOG_AOP_ORDER)
public class UserLogAopAspect {

    @Autowired
    private IUserOperateLogService userOperateLogService;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Around("@annotation(annotation)")
    public Object logSave(ProceedingJoinPoint joinPoint, UserOperateLogAnnotation annotation) throws Throwable {
        long start = System.currentTimeMillis();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        //调用原来的方法
        Object result = joinPoint.proceed();
        UserOperateLogAnnotation operateLogAnnotation = methodSignature.getMethod().getDeclaredAnnotation(UserOperateLogAnnotation.class);
        //如果需要记录数据库开启异步操作
        if (Objects.nonNull(operateLogAnnotation) && operateLogAnnotation.saveDb()) {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            // 请求流水号
            String traceId = StringUtils.defaultString(TraceUtils.getTrace(), MDC.get(TraceConstant.LOG_TRACE_ID));
            String httpMethod = request.getMethod();
            List httpReqArgs = new ArrayList();
            UserOperateLogEntity operateLogEntity = new UserOperateLogEntity();
            operateLogEntity.setCreateTime(new Date());
            String params = null;
            try {
                operateLogEntity.setSuccess(Boolean.TRUE);
                if (Objects.nonNull(result)) {
                    JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(result));
                    if (Objects.nonNull(jsonObject) && jsonObject.containsKey("message")) {
                        String msg = String.valueOf(jsonObject.get("message"));
                        if (msg.length() > 900) {
                            operateLogEntity.setRemark(msg.substring(0, 899));
                        } else {
                            operateLogEntity.setRemark(msg);
                        }
                    }
                }
                operateLogEntity.setModule(operateLogAnnotation.module());
                LoginAppUser loginAppUser = SysUserUtils.getLoginAppUser();
                if (loginAppUser != null) {
                    operateLogEntity.setUsername(loginAppUser.getUsername());
                }
                Method method = resolveMethod(joinPoint);
                //接口描述
                if (method.isAnnotationPresent(ApiOperation.class)) {
                    ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
                    operateLogEntity.setOperateType(apiOperation.value());
                } else {
                    operateLogEntity.setOperateType(methodSignature.getName());
                }
                // 获取方法参数
                operateLogEntity.setService(methodSignature.getDeclaringTypeName() + "/" + methodSignature.getName());
                Object[] args = joinPoint.getArgs();// 参数值
                for (Object object : args) {
                    httpReqArgs.add(object);
                }
                params = JSONObject.toJSONString(httpReqArgs);
                operateLogEntity.setParams(params);
            } catch (Exception e) {
                operateLogEntity.setSuccess(Boolean.FALSE);
                operateLogEntity.setRemark(e.getMessage());
                log.error("请求报错,traceId={},  url={} , httpMethod={}, reqData={} ,error ={} ", traceId, httpMethod, params, e.getMessage());
            } finally {
                //如果需要记录数据库开启异步操作
                if (Objects.nonNull(operateLogAnnotation) && operateLogAnnotation.saveDb()) {
                    CompletableFuture.runAsync(() -> {
                        try {
                            userOperateLogService.saveLog(operateLogEntity);
                        } catch (Exception e) {
                            log.error("落库失败:{}", e.getMessage());
                        }
                    }, threadPoolTaskExecutor);
                }
                // 获取回执报文及耗时
                log.info("请求完成, traceId={}, 耗时={}, resp={}:", traceId, (System.currentTimeMillis() - start));
            }
        }
        return result;
    }

    public Method resolveMethod(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Class targetClass = point.getTarget().getClass();

        Method method = getDeclaredMethod(targetClass, signature.getName(),
                signature.getMethod().getParameterTypes());
        if (method == null) {
            throw new IllegalStateException("无法解析目标方法: " + signature.getMethod().getName());
        }
        return method;
    }

    private Method getDeclaredMethod(Class clazz, String name, Class... parameterTypes) {
        try {
            return clazz.getDeclaredMethod(name, parameterTypes);
        } catch (NoSuchMethodException e) {
            Class superClass = clazz.getSuperclass();
            if (superClass != null) {
                return getDeclaredMethod(superClass, name, parameterTypes);
            }
        }
        return null;
    }

}

注解类 UserOperateLogAnnotation

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserOperateLogAnnotation {

	/**
	 * 模块
	 * @return
	 */
	String module() default "";

	/**
	 * 是否保存到数据库
	 * @return
	 */
	boolean saveDb() default false;
}

 controller调用

@PostMapping("/updateUser")
@ApiOperation(value = "修改用户", notes = "修改用户")
@UserOperateLogAnnotation(module = "admin", saveDb = true)
public ResponseMessage updateUser(@RequestBody UpdateCompanyDto updateCompanyDto) {
    return null;
}

 创建SQL脚本

CREATE TABLE `user_operate_log`  (
  `id` bigint NOT NULL COMMENT '主键ID',
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名',
  `module` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模块名',
  `service` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '服务',
  `operate_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作类型',
  `params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '入参参数值',
  `remark` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
  `success` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否成功',
  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

你可能感兴趣的:(springcloud,微服务操作日志,操作日志入库)