zoukankan      html  css  js  c++  java
  • AOP+注解实现通用日志记录

    0,前言

    在项目开发中,日志记录是一件很重要的事情,下面介绍使用AOP,自定义注解来实现记录项目日志。

    最终要实现的效果是,在Controller方法上,加上自定义注解,就在数据库自动记录当前操作。

    示例:在UserController 的addUser方法加自定义注解@AutoLog

     

     数据库系统日志表记录此次操作:

     

    下面开始实现该功能

    1,表

     SQL:

    CREATE TABLE `sys_log`  (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `log_type` tinyint(4) NULL DEFAULT NULL COMMENT '日志类型(1登录日志,2操作日志)',
      `log_content` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '日志内容',
      `operate_type` tinyint(2) NULL DEFAULT NULL COMMENT '操作类型(1-查询;2-添加;3-更新;4-删除;5-导入;6-导出)',
      `userid` int(32) NULL DEFAULT NULL COMMENT '操作用户账号',
      `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作用户名称',
      `ip` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'IP',
      `method` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求java方法',
      `request_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求路径',
      `request_param` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '请求参数json',
      `request_type` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求类型',
      `cost_time` bigint(20) NULL DEFAULT NULL COMMENT '耗时',
      `create_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
      `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
      `update_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新人',
      `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
      PRIMARY KEY (`id`) USING BTREE,
      INDEX `index_table_userid`(`userid`) USING BTREE
    ) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系统日志表' ROW_FORMAT = Dynamic;

    2,代码

    用mybatis plus生成Entity、Mapper、Service

    自定义注解

    /**
     * 系统日志
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface AutoLog {
        /**
         *日志内容
         * @return
         */
        String value() default "";
    
        /**
         * 日志类型
         *
         * @return ;1:登录日志;2:操作日志
         */
        int logType() default CrcConstants.LOG_TYPE_2;
    
    
        /**
         * 操作日志类型
         *
         * @return (1查询,2添加,3修改,4删除)
         */
        int operateType() default 0;
    }

    常量类:

    /**
     * Created by: lhy on 2019-06-18
     * 常量
     **/
    public class CrcConstants {
    
    
        /**
         * 系统日志类型: 登录
         */
        public static final int LOG_TYPE_1 = 1;
    
        /**
         * 系统日志类型: 操作
         */
        public static final int LOG_TYPE_2 = 2;
    
    
    
        /**
         * 操作日志类型: 查询
         */
        public static final int OPERATE_TYPE_1 = 1;
    
        /**
         * 操作日志类型: 添加
         */
        public static final int OPERATE_TYPE_2 = 2;
    
        /**
         * 操作日志类型: 更新
         */
        public static final int OPERATE_TYPE_3 = 3;
    
        /**
         * 操作日志类型: 删除
         */
        public static final int OPERATE_TYPE_4 = 4;
    
        /**
         * 操作日志类型: 倒入
         */
        public static final int OPERATE_TYPE_5 = 5;
    
        /**
         * 操作日志类型: 导出
         */
        public static final int OPERATE_TYPE_6 = 6;
    }

     切面类:

    import com.alibaba.fastjson.JSONObject;
    import com.farinfo.common.utils.IpUtils;
    import com.farinfo.crc.config.AutoLog;
    import com.farinfo.crc.domain.CrcUser;
    import com.farinfo.crc.domain.SysLog;
    import com.farinfo.crc.service.CrcUserService;
    import com.farinfo.crc.service.SysLogService;
    import com.farinfo.crc.utils.CrcConstants;
    import com.farinfo.crc.utils.SpringContextUtil;
    import org.apache.commons.lang3.StringUtils;
    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.lang.reflect.Method;
    import java.util.Date;
    
    /**
     * Created by: lhy on 2020-03-27
     **/
    @Aspect
    @Component
    public class AutoLogAspect {
    
        @Autowired
        private SysLogService logService;
    
        @Autowired
        private CrcUserService userService;
    
    
        //切点
        @Pointcut("@annotation(com.farinfo.crc.config.AutoLog)")
        public void logPointCut() {
    
        }
    
        /**
         * 环绕增强
         * @param point
         * @return
         * @throws Throwable
         */
        @Around("logPointCut()")
        public Object around(ProceedingJoinPoint point) throws Throwable {
            long beginTime = System.currentTimeMillis();
            //执行方法
            Object result = point.proceed();
            //执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
            //保存日志
            saveSmsLog(point, time);
            return result;
        }
    
    
    
    
        private void saveSmsLog(ProceedingJoinPoint joinPoint, long time) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
    
            SysLog sysLog = new SysLog();
            AutoLog syslog = method.getAnnotation(AutoLog.class);
            if(syslog != null){
                //注解上的描述,操作日志内容
                sysLog.setLogContent(syslog.value());
                sysLog.setLogType(syslog.logType());
            }
    
            //请求的方法名
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = signature.getName();
            sysLog.setMethod(className + "." + methodName + "()");
    
    
            //设置操作类型
            if (sysLog.getLogType() == CrcConstants.LOG_TYPE_2) {
                sysLog.setOperateType(getOperateType(methodName, syslog.operateType()));
            }
    
            //请求的参数
            Object[] args = joinPoint.getArgs();
            try{
                String params = JSONObject.toJSONString(args);
                sysLog.setRequestParam(params);
            }catch (Exception e){
    
            }
    
            //获取request
            HttpServletRequest request = SpringContextUtil.getHttpServletRequest();
            //设置IP地址
            sysLog.setIp(IpUtils.getIpAddr(request));
    
            //获取登录用户信息,看你用的什么安全框架了,可以从安全上下文获取
            int userId = 35;
            CrcUser user = userService.selectById(userId);
            if(user != null){
                sysLog.setUsername(user.getLoginName());
                sysLog.setUserid(userId);
            }
    
            //耗时
            sysLog.setCostTime(time);
            sysLog.setCreateTime(new Date());
            //保存系统日志
            logService.insert(sysLog);
        }
        /**
         * 获取操作类型
         */
        private int getOperateType(String methodName,int operateType) {
            if (operateType > 0) {
                return operateType;
            }
            if (methodName.startsWith("list")) {
                return CrcConstants.OPERATE_TYPE_1;
            }
            if (methodName.startsWith("add")) {
                return CrcConstants.OPERATE_TYPE_2;
            }
            if (methodName.startsWith("edit")) {
                return CrcConstants.OPERATE_TYPE_3;
            }
            if (methodName.startsWith("delete")) {
                return CrcConstants.OPERATE_TYPE_4;
            }
            if (methodName.startsWith("import")) {
                return CrcConstants.OPERATE_TYPE_5;
            }
            if (methodName.startsWith("export")) {
                return CrcConstants.OPERATE_TYPE_6;
            }
            return CrcConstants.OPERATE_TYPE_1;
        }
    }

    实验:

    @RequestMapping("/testIdem")
    @RestController
    public class TestIdemController {
    
        @Autowired
        private CrcUserService userService;
    
        @AutoLog(value = "添加用户", operateType = CrcConstants.OPERATE_TYPE_2)
        @PostMapping("addUser")
        public String addUser(@RequestBody CrcUser user){
            userService.insert(user);
            return "OK";
        }
    
    }

     User表:

     sys_log表:

    如果想记录详细的日志信息,可以调用logSrvice.addLog() 进行自行添加。

  • 相关阅读:
    Tom和Jerry来了,Tom和Jerry走了——北漂18年(38)
    查找(一)史上最简单清晰的红黑树解说
    HDU4763-Theme Section(KMP+二分)
    Loadrunner得到server參数
    hdu 4002
    javascript——从「最被误解的语言」到「最流行的语言」
    【云快讯】之四十八《IBM和Cisco最新收购,加强Openstack易用能力》
    2013级学生两学期编程量统计
    Hadoop高速入门
    HDOJ 3339 In Action
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/12581847.html
Copyright © 2011-2022 走看看