异步日志登录

发布时间 2023-06-05 20:53:35作者: 一只快乐的柠檬精J

异步日志登录

项目亮点 : 放在公司的通用组件库中: 日志记录组件库

  • 系统的用户操作日志记录【解耦合】
    自定义注解 + AOP + 异步多线程/MQ + 数据模型设计 + 设计模式【单例模式+工厂模式】

  • 效果:

    • 开发者只需要在业务方法上,添加一个注解 @Log 就可以实现执行这个方法时,自动记录日志。===> 输出【数据库、文件、ES索引库】
  • 设计数据模型:

    • 日志内容:
      操作人 + 操作时间 + 操作人IP地址 +
      什么操作【 哪个类 + 哪个方法 + 方法参数 + 结果 + 异常信息 】 +
      哪个系统 +
      操作类型【login/logout/ delete/insert ......】

    • 日志表模型

代码具体实现

  1. 自定义一个注解
/**
 *以下四个为springboot元注解,注解类都要有
 */
@Target({ElementType.TYPE,ElementType.METHOD})  //作用范围 :作用类上、方法上
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Inherited
public @interface Log {

}
  1. 编写AOP代码实现记录日志的功能:先定义一个通知类【@Aspect】,在通知类中实现记录日志的操作,完成代码增强 = 如下代码

    • 准备工作 :

      • 首先导入依赖 : springboot项目 + AOP

      • 通知类上加注解 :

        @Component
        @Aspect
        
    • 切点表达式 :对所有方法上添加了 @Log 注解的方法进行代码增强,增强的逻辑就是记录日志

          * 对注解方法进行增强
           */
          @Pointcut("@annotation(cn.itcast.common.log.anno.Log)")
          public void pointCut(){}
      
    • 编写通知方法,在通知方法中实现日志的记录

      • 第一步:先需要选择通知类型: @before @after @around @afterReturning @afterThrowing

        • 选择: @afterReturning @afterThrowing
      • 编写通知方法,并在通知方法中完成日志的记录

            /**
             * 记录方法正常返回日志
             * @param joinPoint  切点对象
             * @param result  方法返回结果
             */
            @AfterReturning(pointcut = "pointCut()",returning = "result")  //指定切点表达式 、 结果类型
            public void logSuccess(JoinPoint joinPoint,Object result){
                //TODO 记录日志
            }
        
            /**
             * 记录方法异常抛出异常日志
             * @param joinPoint 切点对象, 可以获取到和增强的目标方法的很多信息
             * @param ex  方法抛出的异常
             */
            @AfterThrowing(pointcut = "pointCut()" ,throwing = "ex")
            public void logException(JoinPoint joinPoint,Throwable ex){
                //TODO 记录日志
            }
        
      • 创建日志表

        CREATE TABLE sys_operate_log(
             id BIGINT PRIMARY KEY,
             operator VARCHAR(20) COMMENT '操作人',
             operate_time DATETIME COMMENT '操作时间',
             operate_ipaddr VARCHAR(15) COMMENT '操作人客户端ip地址',
             method_name VARCHAR(200) COMMENT '执行的类名+方法名',
             method_param LONGTEXT COMMENT '方法参数',
             method_result LONGTEXT COMMENT '返回结果',
             exception LONGTEXT COMMENT '执行异常信息',
        
             operate_type VARCHAR(10) COMMENT '操作类型:login、logout、add、update、query、delete'
        );
        
        
      • 创建实体类SysOperateLog

        package com.itcast.logself.pojo;
        import java.time.LocalDateTime;
        public class SysOperateLog {
            private Long id;
            /**
             * 操作人
             */
            private String operator;
            /**
             * 操作时间
             */
            private LocalDateTime operateTime;
            /**
             * 操作人客户端ip地址
             */
            private String operateIpaddr;
            /**
             * 执行的类名+方法名
             */
            private String methodName;
            /**
             * 方法参数
             */
            private String methodParam;
            /**
             * 返回结果
             */
            private String methodResult;
            /**
             * 执行异常信息
             */
            private String exception;
            /**
             * 操作类型:login、logout、add、update、query、delete
             */
            private String operateType;
        }
        
      • 创建mapper层