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

目录

​编辑

[自定义注解 + AOP 记录用户的使用日志](#自定义注解 + AOP 记录用户的使用日志)

使用背景

落地实践

一:自定义注解

二:切面配置

三:Api层使用

使用效果


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

使用背景

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

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

落地实践

一:自定义注解

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

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

二:切面配置

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

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

java 复制代码
    
    /**
     * @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层使用

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

java 复制代码
/**
 * @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、响应结果、耗时,都完整的打印出来,一旦出现外聘人员误操作或者三方数据不匹配,通过这些信息,定位起问题来都非常方便。

相关推荐
wanhengidc几秒前
巨 椰 云手机离线多开
运维·服务器·科技·智能手机·云计算
代码游侠几秒前
应用——管道与文件描述符
linux·服务器·c语言·学习·算法
Coder_Boy_1 分钟前
前端和后端软件系统联调经典问题汇总
java·前端·驱动开发·微服务·状态模式
GoWjw4 分钟前
C语言高级特性
c语言·开发语言·算法
自己的九又四分之三站台4 分钟前
基于Python获取SonarQube的检查报告信息
开发语言·python
wefg15 分钟前
【Linux】环境变量
linux·运维·服务器
扫地生大鹏6 分钟前
Linux登录用户名密码正确,报错Linux 登录报module is unknow
linux·运维·服务器
PieroPC8 分钟前
NiceGUI .classes() 完整列表教程
前端
月巴月巴白勺合鸟月半8 分钟前
一个医学编码的服务
服务器·前端·javascript
雨中飘荡的记忆12 分钟前
Retrofit:优雅的JAVA网络请求框架实战
java