从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现

本章结束后对应的节选代码文件:Gangbb-Vue-05-Log
项目地址:https://github.com/Gang-bb/Gangbb-Vue

历史遗留TODO:

  • 第三章
  1. mybatis缓存暂时没用到,后面整合redis后用redis做缓存(整合Redis完成)。
  2. 重写mybatis配置文件扫描mapper(日志整合章节完成)
  3. 整合暂时没有用到druid数据源,后续会用到

本章将留下TODO:

  • 第四章
  1. 登录日志还未实现。(到登录和权限模块完成)
  2. LogAspect从缓存获取当前的用户信息使用模拟的数据(到登录和权限模块完成)

本章将解决TODO:

  • 第三章
  1. 重写mybatis配置文件扫描mapper(日志整合章节完成)

本章只是简单的对日志工具进行引入和配置

整体思路:SLF4j+log4j2+Aop(若依的日志实现使用的是logback)

具体详细选型介绍可以查看我的文章:SpringBoot系列-- SpringBoot整合SLF4j+log4j2+aop记录web请求

原来文章的切点是设置在监听controller目录下,即所有请求。按照若依的做法是创建一个自定义@Log注解,切点设为该注解,如此设计更加灵活和扩展,决定采用它的方案!

1. 添加依赖

1.1 Gangbb-Vue的pom.xml

<properties>
	<fastjson.version>1.2.74fastjson.version>
properties>

<dependencyManagement>
    <dependencies>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>fastjsonartifactId>
            <version>${fastjson.version}version>
        dependency>
        
    dependencies>
dependencyManagement>

1.2 Gangbb-core的pom.xml

<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
        
        <exclusions>
            
            <exclusion>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-loggingartifactId>
            exclusion>
        exclusions>
    dependency>
    

    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-aopartifactId>
    dependency>
    

    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-log4j2artifactId>
    dependency>
    
    
    
    <dependency>
        <groupId>com.gangbbgroupId>
        <artifactId>Gangbb-commonartifactId>
    dependency>
    
dependencies>

1.2 Gangbb-common的pom.xml

<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-configuration-processorartifactId>
        <optional>trueoptional>
    dependency>
    
    
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
    dependency>
    
    
    
    <dependency>
        <groupId>org.apache.commonsgroupId>
        <artifactId>commons-lang3artifactId>
    dependency>
    
    
	
    <dependency>
        <groupId>javax.servletgroupId>
        <artifactId>javax.servlet-apiartifactId>
    dependency>
    
    
	
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-context-supportartifactId>
    dependency>
    

    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webartifactId>
    dependency>
    
dependencies>

1.3 Gangbb-admin的pom.xml

<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
        
        <exclusions>
            
            <exclusion>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-loggingartifactId>
            exclusion>
        exclusions>
    dependency>
    
    
    
    <dependency>
        <groupId>com.gangbbgroupId>
        <artifactId>Gangbb-coreartifactId>
    dependency>
    
dependencies>

注解要删除上节使用的:


<dependency>
    <groupId>com.gangbbgroupId>
    <artifactId>Gangbb-commonartifactId>
dependency>

因为导入的Gangbb-core中已经有Gangbb-common,不删除会导致循环依赖。

2. 创建数据库表

表名和其中一些字段名和若依的不一样

CREATE TABLE `sys_operation_log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '日志主键id',
  `title` varchar(255) DEFAULT '' COMMENT '操作模块',
  `business_type` tinyint(4) unsigned DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)',
  `class_method` varchar(255) DEFAULT '' COMMENT '请求处理方法',
  `request_method` varchar(255) DEFAULT '' COMMENT '请求方式',
  `operator_type` tinyint(4) unsigned DEFAULT '0' COMMENT '操作类别(0其它 1后台用户 2手机端用户)',
  `operation_name` varchar(50) DEFAULT '' COMMENT '操作人员',
  `operation_url` varchar(150) DEFAULT '' COMMENT '请求url',
  `operation_ip` varchar(20) DEFAULT '' COMMENT '操作ip',
  `operation_location` varchar(255) DEFAULT '' COMMENT '操作地点',
  `operation_param` varchar(255) DEFAULT '' COMMENT '请求参数',
  `json_result` varchar(255) DEFAULT '' COMMENT '返回参数',
  `operation_status` tinyint(4) unsigned DEFAULT '0' COMMENT '操作状态(0正常 1异常)',
  `error_msg` varchar(255) DEFAULT '' COMMENT '错误消息',
  `operation_time` datetime DEFAULT NULL COMMENT '操作时间',
  `creator` varchar(100) DEFAULT '' COMMENT '创建者',
  `createTime` datetime DEFAULT NULL COMMENT '创建时间',
  `reviser` varchar(100) DEFAULT '' COMMENT '更新者',
  `updateTime` datetime DEFAULT NULL COMMENT '更新时间',
  `isDel` tinyint(4) unsigned DEFAULT '0' COMMENT '是否删除 0-未删除  1-已删除',
  `remark` varchar(255) DEFAULT '' COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

3. 自定义注解@Log及相关枚举

在 common通用工具模块 中定义:

从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第1张图片

一、Log

@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /**
     * 模块
     */
    public String title() default "";

    /**
     * 功能
     */
    public BusinessType businessType() default BusinessType.OTHER;

    /**
     * 操作人类别
     */
    public OperatorType operatorType() default OperatorType.MANAGE;

    /**
     * 是否保存请求的参数
     */
    public boolean isSaveRequestData() default true;
}

二、BusinessType

public enum BusinessType
{
    /**
     * 其它
     */
    OTHER,

    /**
     * 新增
     */
    INSERT,

    /**
     * 修改
     */
    UPDATE,

    /**
     * 删除
     */
    DELETE,

    /**
     * 授权
     */
    GRANT,

    /**
     * 导出
     */
    EXPORT,

    /**
     * 导入
     */
    IMPORT,

    /**
     * 强退
     */
    FORCE,

    /**
     * 生成代码
     */
    GENCODE,

    /**
     * 清空数据
     */
    CLEAN,
}

三、OperatorType

public enum OperatorType
{
    /**
     * 其它
     */
    OTHER,

    /**
     * 后台用户
     */
    MANAGE,

    /**
     * 手机端用户
     */
    MOBILE
}

3. AOP切面处理请求操作日志

本节代码涉及过长不再贴出

整体思路:切入带有@Log的Controller,记录相应的请求信息。

需要先定义本节需要的一些实体类、枚举和工具类:

(其中有互相引用的,全部引入项目就不会错)

  • BaseEntity所有entity实体类都要继承的基类,

  • SysOperationLog操作日志记录表 对应数据库(sys_operation_log)表

  • BusinessStatus 操作状态枚举

  • BusinessType业务操作类型 枚举

  • OperatorType操作人类别 枚举

  • StringUtils字符串工具类

  • CharsetKit字符集工具类

  • Convert类型转换器

  • StrFormatter字符串格式化工具

  • IpUtils获取IP工具类

  • EscapeUtil转义和反转义工具类

  • HTMLFilterHTML过滤器,用于去除XSS漏洞隐患

  • ServletUtils客户端工具类

  • AddressUtils获取地址类

  • HttpUtils通用http发送方法

  • Constants通用常量信息

  • GangbbConfig读取项目相关配置

  • AsyncManager异步任务管理器

  • Threads线程相关工具类

  • SpringUtilsspring工具类 方便在非spring管理环境中获取bean

  • ThreadPoolConfig线程池配置

  • AsyncFactory异步工厂,产生任务用(目前只定义了 记录操作日志信息recordOperation方法,记录登录信息recordLogininfor方法后面到登录再涉及)

核心的LogAspect切面处理类中的保存Log具体处理方法handleLog主要逻辑:

  1. 获得注解
  2. 从缓存获取当前的用户信息(暂缺,先模拟一个)
  3. 获取请求各项需要记录的基本信息
  4. 判断请求是否有异常
  5. 保存到数据库
  6. 打印到控制台

既然最后一步要操数据库当然需要各层的文件:

从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第2张图片

5. log4j2的配置文件




<Configuration status="fatal">
  <Properties>
    <Property name="baseDir" value="${sys:user.home}/logs/Gangbb_Vue"/>
  Properties>

  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      
      <ThresholdFilter level="debug" onMatch="ACCEPT"
        onMismatch="DENY"/>
      <PatternLayout
        pattern="[%d{MM:dd HH:mm:ss.SSS}] [%level] [%logger{36}] - %msg%n"/>
    Console>

    
    <RollingFile name="debug_appender" fileName="${baseDir}/debug.log"
      filePattern="${baseDir}/debug_%i.log.%d{yyyy-MM-dd}">
      
      <Filters>
        
        <ThresholdFilter level="debug"/>
        <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
      Filters>
      
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      
      <Policies>
        
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        
        <SizeBasedTriggeringPolicy size="100 MB"/>
      Policies>
      
      <DefaultRolloverStrategy max="15"/>
    RollingFile>

    
    <RollingFile name="info_appender" fileName="${baseDir}/info.log"
      filePattern="${baseDir}/info_%i.log.%d{yyyy-MM-dd}">
      
      <Filters>
        
        <ThresholdFilter level="info"/>
        <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
      Filters>
      
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      
      <Policies>
        
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        
        <SizeBasedTriggeringPolicy size="100 MB"/>
      Policies>
      
      <DefaultRolloverStrategy max="15"/>
    RollingFile>

    
    <RollingFile name="error_appender" fileName="${baseDir}/error.log"
      filePattern="${baseDir}/error_%i.log.%d{yyyy-MM-dd}">
      
      <Filters>
        
        <ThresholdFilter level="error"/>
      Filters>
      
      <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
      <Policies>
        
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        
        <SizeBasedTriggeringPolicy size="100 MB"/>
      Policies>
      
      <DefaultRolloverStrategy max="15"/>
    RollingFile>
  Appenders>
  
  
  
  
  <Loggers>
    
    <logger name="org.mybatis" level="info" additivity="false">
      <AppenderRef ref="Console"/>
    logger>

    <Logger name="org.springframework" level="WARN" additivity="false">
      <AppenderRef ref="Console"/>
    Logger>

    
    <logger name="com.zaxxer.hikari" level="WARN" additivity="false">
      <appender-ref ref="Console"/>
    logger>

    
    <logger name="org.hibernate.validator" level="WARN" additivity="false">
      <appender-ref ref="Console"/>
    logger>

    




    <Root level="debug">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="debug_appender"/>
      <AppenderRef ref="info_appender"/>
      <AppenderRef ref="error_appender"/>
    Root>

  Loggers>
Configuration>

看到控制台有什么不爽的打印信息,在 标签对内再写一个过滤就行了!

6. 修改Mybatis配置

  • 添加:MyBatisConfig使 Mybatis支持*匹配扫描包

  • Gangbb-admin的application.yml:

mybatis:
  configuration:
    # 实体类驼峰命名转成数据库中的下划线命名
    map-underscore-to-camel-case: true
    # 指定 MyBatis 所用日志的具体实现
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
    # 全局映射器启用缓存
    cache-enabled: true
    # 允许 JDBC 支持自动生成主键
    use-generated-keys: true
    # 配置默认的执行器
    default-executor-type: reuse
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  # 扫描实体类路径(搜索指定包别名)
  type-aliases-package: com.gangbb.**.entity
  • ApplicationConfig配置对dao层mapper的扫描。
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.gangbb.**.dao")
public class ApplicationConfig
{
    /**
     * 时区配置
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
    {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
    }
}

6. 测试日志记录

新建测试TestLogAnnotationController

从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第3张图片

@RestController
@RequestMapping("log")
public class TestLogAnnotationController {

    @Log(title = "测试@Log注解", businessType = BusinessType.OTHER)
    @GetMapping("/hello")
    public String HelloLog(){
        return "测试@Log注解,记录操作日志";
    }
}

发送请求:

从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第4张图片

日志控制台打印信息:

从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第5张图片

(是不是十分清晰明了,i了i了!)

数据库中也有相应的数据:
从零搭建若依(Ruoyi-Vue)管理系统(5)--整合日志实现_第6张图片

你可能感兴趣的:(#,从零搭建若依管理系统,java实战开发,spring,boot,spring,若依)