通过AOP实现日志记录

这次要实现的功能是,要记录所有到controller中方法的运行日志保存到日志表中

日志信息包含:操作人、操作时间、执行方法的全类名、执行方法名、方法作用、方法运行时参数、返回值、方法执行时长。

准备工作

添加aop的启动器

<!--aop-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

创建数据表

-- 操作日志表
create table operate_log(
    id int unsigned primary key auto_increment comment 'ID',
    class_name varchar(100) comment '操作的类名',
    method_name varchar(100) comment '操作的方法名',
    method_desc varchar(100) comment '方法用途',
    method_params varchar(1000) comment '方法参数',
    return_value varchar(2000) comment '返回值',
    operate_user int unsigned comment '操作人ID',
    operate_time datetime comment '操作时间',
    cost_time bigint comment '方法执行耗时, 单位:ms'
) comment '操作日志表';

创建日志类

package com.itheima.pojo;
​
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
import java.time.LocalDateTime;
​
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {
    private Integer id; //ID
    private String className; //操作类名
    private String methodName; //操作方法名
    private String methodDesc; //方法用途
    private String methodParams; //操作方法参数
    private String returnValue; //操作方法返回值
    private Integer operateUser; //操作人ID
    private LocalDateTime operateTime; //操作时间
    private Long costTime; //操作耗时
}

创建日志的Mapper

package com.itheima.mapper;
​
import com.itheima.pojo.OperateLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
​
@Mapper
public interface OperateLogMapper {
​
    //插入日志数据
    @Insert("insert into operate_log (operate_user, operate_time, class_name, method_name,method_desc, method_params, return_value, cost_time) " +
            "values (#{operateUser}, #{operateTime}, #{className}, #{methodName},#{methodDesc}, #{methodParams}, #{returnValue}, #{costTime});")
    public void insert(OperateLog log);
​
}

制作切面

package com.itheima.aspect;
​
​
import com.itheima.anno.LogAnno;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.util.JwtUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
​
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
​
@Component
@Aspect//切面
public class LogAspect {
​
    @Autowired
    private HttpServletRequest request;
​
    @Autowired
    private OperateLogMapper operateLogMapper;
​
    //自定义注解
    @Pointcut("@annotation(com.itheima.anno.LogAnno)")
    public void pt() {
    }
​
    //环绕通知
    @Around("pt()")
    public Object logAround(ProceedingJoinPoint pjp) {
        OperateLog operateLog = new OperateLog();
​
        //日志信息包含:方法作用、、返回值、方法执行时长
        try {
            String token = request.getHeader("token");
            Integer id = JwtUtils.parseJWT(token).get("id", Integer.class);
            operateLog.setOperateUser(id);//操作人id
        }catch (Exception e){
           e.printStackTrace();
        }
​
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        operateLog.setMethodName(ms.getMethod().getName());//方法名
        operateLog.setMethodDesc(ms.getMethod().getAnnotation(LogAnno.class).methodDesc());//方法作用
​
        operateLog.setOperateTime(LocalDateTime.now());//操作时间
        operateLog.setClassName(pjp.getTarget().getClass().getName());//全类名
        operateLog.setMethodParams(Arrays.toString(pjp.getArgs()));//参数
​
        Object obj = null;
        long start = new Date().getTime();
        try {
            obj = pjp.proceed();
            operateLog.setReturnValue(obj.toString());
            return obj;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
            long end = new Date().getTime();
            operateLog.setCostTime(end-start);//方法执行时长
            operateLogMapper.insert(operateLog);//保存日志
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值