springboot通过aop环形切的方式来实现日志记录

springboot通过aop环形切的方式来实现日志记录

添加依赖

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop'
implementation 'com.alibaba:fastjson:1.2.78'

自定义注解

package com.shop.annos;

import com.shop.codes.EnumOperationType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


//注解在哪个阶段执行
@Retention(RetentionPolicy.RUNTIME)
//注解放置的目标位置,METHOD是可注解在方法级别上
@Target({ElementType.METHOD})
public @interface OperLog {
    String message();  // 介绍
    EnumOperationType operation();  // 日志类型
}

日志实体类

package com.shop.entity;

import java.util.Date;
/*
*日志实体类 SysLog
 */
public class SysLog {

    private Long id;  //

    private String userId;  // 操作用户 ID

    private String message;  // 消息

    private String operation;  // 日志类型

    private String method;  // 请求方法

    private String params;  // 请求参数

    private String ip;  // 请求IP

    private Date createDate;// 请求时间

    private Long totalTime; //总耗时长(毫秒)

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getOperation() {
        return operation;
    }

    public void setOperation(String operation) {
        this.operation = operation;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getParams() {
        return params;
    }

    public void setParams(String params) {
        this.params = params;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Long getTotalTime() {
        return totalTime;
    }

    public void setTotalTime(Long totalTime) {
        this.totalTime = totalTime;
    }
}

操作类型类

package com.shop.codes;

/**
 * 操作类型类  OperationType
 */
public enum EnumOperationType {

    LOGIN("LOGIN"),
    LOGOUT("LOGOUT"),
    INSERT("INSERT"),
    QUERY ("QUERY"),
    UPDATE ("UPDATE "),
    DELETE ("DELETE ");

    private String desc;

    EnumOperationType(String desc) {
        this.desc = desc;
    }


    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "EnumStatusCode{" +
            " desc='" + desc + '\'' +
            '}';
    }
}

切面处理

package com.shop.config.LogAsceptConfig;

import com.alibaba.fastjson.JSON;
import com.shop.annos.OperLog;
import com.shop.entity.SysLog;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 系统日志:切面处理类
 */
@Aspect
@Component
public class SysLogAspect {

    private static Logger logger = LoggerFactory.getLogger(SysLogAspect.class);

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation( com.shop.annos.OperLog)")
    public void logPoinCut() {
    }

    //@Around:环绕通知
    @Around("logPoinCut()")
    public Object saveSysLog(ProceedingJoinPoint proceedingJoinPoint) {

        logger.info("环绕通知开始。。。。。");
        //保存日志
        SysLog sysLog = new SysLog();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作
        OperLog myLog = method.getAnnotation(OperLog.class);
        if (myLog != null) {
            String value = myLog.message();
            sysLog.setMessage(value);//保存获取的操作
        }
        //获取请求的类名
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        sysLog.setMethod(className + "." + methodName);

        //请求的参数
        Object[] args = proceedingJoinPoint.getArgs();
        //将参数所在的数组转换成json
        String params = JSON.toJSONString(args);
        sysLog.setParams(params);

        sysLog.setCreateDate(new Date());
        //获取用户名
        //获取用户ip地址
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        sysLog.setIp(request.getRemoteAddr());

        //开始调用时间
        // 计时并调用目标函数
        long start = System.currentTimeMillis();
        Long time = System.currentTimeMillis() - start;
        sysLog.setTotalTime(time);

        //调用service保存SysLog实体类到数据库
        //sysLogService.save(sysLog);
        try {
            Object result = proceedingJoinPoint.proceed();
            logger.info("    "+result.toString());
            logger.info("环绕通知结束。。。。。");
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            logger.info(""+throwable);
        }
        return "系统异常";
    }

}

将注解加到需要记录用户操作的方法体上

在Controller层上添加我们的自定义注解就可以了:
@OperLog(message = “日志描述”,operation = 日志类型)

    @PostMapping(value = "/loginIn")
    @OperLog(message = "用户登录",operation = EnumOperationType.LOGIN)
    @ApiOperation(value = "登录接口",notes = "登录接口",produces = "application/json")
    public String login(String name,String password){
        User user = tidDSUserService.loginIn(name,password);
//        String s = weatherController.QueryWeather();
        if(user !=null){
            return "success";
        }else {
            return "error";
        }
    }

爱意随风起,风停意难平
爱意随风起,却不随风散

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值