springboot 切面编程记录请求日志

本文介绍了如何在SpringBoot中使用AOP切面编程来记录非查询操作的请求日志,包括创建日志表结构、定义注解、实现切面处理类以及在接口上使用注解的例子。通过这种方法,可以方便地记录用户的操作、响应时间、请求方法、参数、IP地址等信息。
摘要由CSDN通过智能技术生成

springboot 切面编程记录请求日志

开发过程中,对于非查询操作,需要做对应的日志记录,因此使用切面在接口上定义@SysLogService注解,方便日志记录。

数据库表创建:

/*==============================================================*/
/* Table: sys_log  系统日志表                              */
/*==============================================================*/
CREATE TABLE public.sys_log (
  id SERIAL NOT NULL PRIMARY KEY,
  user_id VARCHAR ( 50 ) NULL,
  user_name VARCHAR ( 50 ) NULL,
  operation VARCHAR ( 100 ) NULL,
  response_time INT4 NULL,
  method VARCHAR ( 200 ) NULL,
  params TEXT  NULL,
  ip VARCHAR ( 50 ) NULL,
  gmt_create TIMESTAMP NULL 
);
COMMENT ON TABLE public.sys_log IS '系统日志';
COMMENT ON COLUMN public.sys_log.id IS '主键id';
COMMENT ON COLUMN public.sys_log.user_id IS '用户id';
COMMENT ON COLUMN public.sys_log.user_name IS '用户名称';
COMMENT ON COLUMN public.sys_log.operation IS '用户操作';
COMMENT ON COLUMN public.sys_log.response_time IS '响应时间';
COMMENT ON COLUMN public.sys_log.method IS '请求方法';
COMMENT ON COLUMN public.sys_log.params IS '请求参数';
COMMENT ON COLUMN public.sys_log.ip IS 'IP地址';
COMMENT ON COLUMN public.sys_log.gmt_create IS '创建时间';

注解接口定义:

/**
 * 系统日志注解
 * @author xx
 * @Date 2021-4-14 18:01:05
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLogService {

	String value() default "";

}

参数解释:
@Target 定义该注解可以用于何处,包含:ElementType.PARAMETER;ElementType.METHOD;ElementType.TYPE等;
@Retention 是定义被它所注解的注解保留多久;有SOURCE(保留在源文件);CLASS(保留到class文件);RUNTIME(JVM加载后仍存在)三种;
@Documented 注解只是用来做标识,没什么实际作用

具体实现:

/**
 * 系统日志,切面处理类
 * @author xx
 * @Date 2021-4-14 19:30:02
 */
@Aspect
@Component
@Slf4j
public class SysLogAspect {

    @Autowired
    private SysLogMapper sysLogMapper;
    @Autowired
    SysUserApplicationService sysUserApplicationService;

    @Pointcut("@annotation(com.yoi.core.domain.repository.SysLogService)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        saveSysLog(point, time);
        return result;
    }

    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        SysLogService syslog = method.getAnnotation(SysLogService.class);
        if(syslog != null){
            //注解上的描述
            sysLog.setOperation(syslog.value());
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        //请求的参数
        Object[] args = joinPoint.getArgs();
        try{
            String params = JSONUtils.beanToJson(args[0]);
            sysLog.setParams(params);
        }catch (Exception e){

        }
        //设置IP地址
        sysLog.setIp(WebUtils.getIpAddr());
        //用户名
        String userId = WebUtils.getUserId();
        sysLog.setUserId(userId);
        if(ObjectUtils.isNotEmpty(userId)){
            SysUserDto sysUserDto = sysUserApplicationService.getUserByUserId(userId);
            sysLog.setUserName(sysUserDto.getUserName());
        }
        sysLog.setResponseTime(time);
        sysLog.setGmtCreate(DateUtils.getCurrentDate());
        if(ObjectUtils.isNotEmpty(syslog.value())){
            //保存系统日志
            int num = sysLogMapper.insert(sysLog);
            if(num>0){
                log.info("save log{} success!",sysLog.toString());
            }else{
                log.info("save log{} faild!",sysLog.toString());
            }
        }else{
            log.debug(className + "." + methodName + "() :request log{}!",sysLog.toString());
        }
    }

}

接口定义的注解使用:

    @ApiOperation(value = "保存测试接口", notes = "保存测试接口")
    @SysLogService("保存测试接口")
    @PostMapping("/test")
    public boolean test(@ApiParam(value = "传入json格式", required = true) @RequestBody Test test) {
        return faultApplicationService.save(test);
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值