全局数据审计

如何使用数据审计功能 支持版本:2.4.1,2.5.1

全局数据生命周期审计功能

应用场景

需要记录数据什么时候被修改,什么人修改的,修改后的数据是什么,当数据有变更后,响应变更事件。

功能使用前提

  1. 确保微服务连接到了redis,rabbitmq,并且已经正确配置spring相关参数
  2. 日志服务升级到1.8.1版本以上

场景1. 开启产品已有的审计功能

开启方式:添加启动配置参数即可,修改审计配置,

h-visions:
  data-audit:
    #服务名称,作为数据的区分字段,默认是spring.application.name
    serviceName: ${h-visions.service-name}
    #是否开启数据历史审计总开关,如果设置为false,则功能不启用,默认false
    enable: false
    #是否审计所有实体,如果设置为true,所有实体都会审计,如果想要单独审计,需要设置为false,默认false
    audit-all-entity: false
    #是否审计实体的所有操作。如果不想记录所有的操作,需要设置为false,默认false
    audit-all-operation: false
    #审计实体的操作类型,当audit-all-operation设置为false的时候生效。只能设置如下三种操作,默认为空数组
    operation: INSERT,UPDATE,DELETE
    #按照实体来进行分别的设置,需要audit-all-entity设置为false
    audit-config: 
        # 实体类名
      - entity: SysUser
        # 是否记录所有的操作
        all-option: true
        # 记录的操作,必须all-option设置为false的时候生效
        option: INSERT,DELETE
      - entity: HvSysRole
        option: DELETE
        all-option: true
    

对象列表的对应properties的配置方法请参考:下面是监控SysUser的

h-visions.data-audit.audit-config[0].entity=SysUser
h-visions.data-audit.audit-config[0].all-option=false
h-visions.data-audit.audit-config[0].option=INSERT,DELETE
h-visions.data-audit.audit-config[1].entity=SysRole
h-visions.data-audit.audit-config[1].all-option=true

日志服务启动后会自动记录到数据审计表中,审计信息可以定期删除,(修改日志服务的配置可以调整过期日志时间,默认30天)

h-visions:
  logCapture:
    #定时清除日志的参数配置
    log-clear-day: 30
  dataAudit:
    #定时清除审计信息的参数配置
    audit-clear-day: 30

场景2. 微服务中添加数据审计功能

只能影响jpa操作的数据。没办法记录Mybatis,MybatisPlus或者JdbcTemplate语句操作的数据。需要自己调用日志相关的接口自己实现审计功能。

  1. 增加依赖

之前的log-client依赖可以删除,新的starter集成了之前的接口日志配置功能。Config.class 中的日志Aop可以去掉了。

<dependency>
    <groupId>com.hvisions</groupId>
    <artifactId>log-spring-boot-starter</artifactId>
    <version>1.8.1</version>
</dependency>
  1. SysBase.class 增加监听类DataAuditEntityListener
@EntityListeners({AuditingEntityListener.class, DataAuditEntityListener.class})
public class SysBase {
// 其余代码
}

场景3. 作为应用的事件源头,通过事件驱动的编程模式,解耦各个应用。

应用场景示例:当工单创建的时候。需要同步创建一个出库单,出库工单需要的物料。但是这块业务和工单无关不应该写到工单服务中
日志服务记录审计信息,就是通过监听全部的数据来实现的。

监听rabbitmq topic设置为自己想要监听的对象,解析消息体后编写自己的业务逻辑

首先升级pom依赖,使用最新的日志依赖,如果只是需要监听。可以依赖log-common

<dependency>
    <groupId>com.hvisions</groupId>
    <artifactId>log-spring-boot-starter</artifactId>
    <version>1.8.1</version>
</dependency>

服务中添加消息队列

@Configuration
public class DataAuditRabbitConfig {
    /**
     * 消息队列Queue名称
     */
    final static String LOG_QUEUE = "h-visions.{your service name}.{your queue name}";
    private final static String LOG_EXCHANGE = "h-visions.log.data.audit";

    @Bean
    public Queue dataAuditQueue() {
        return new Queue(DataAuditRabbitConfig.LOG_QUEUE);
    }

    @Bean
    TopicExchange dataAuditExchange() {
        return new TopicExchange(LOG_EXCHANGE);
    }

    /**
     * 绑定队列和关注的消息
     *
     * @param dataAuditQueue    队列
     * @param dataAuditExchange 分发器
     * @return 绑定
     */
    @Bean
    Binding bindingExchangeMessage1(Queue dataAuditQueue, TopicExchange dataAuditExchange) {
        // 绑定关系,例如你要监听工单服务{workOrder}中,工单实体{HvWorkOrder}的创建信息,routingKey应该为:workOrder.HvWorkOrder.INSERT,
        return BindingBuilder.bind(dataAuditQueue).to(dataAuditExchange).with("{servicename}.{entityName}.{operationName}");
    }
}

监听队列消息并对接自己的业务代码

@Component
@Slf4j
public class DataAuditReceiver {
    //注入你的服务Bean
    private final Service service;
    private final ObjectMapper objectMapper;

    @Autowired
    public DataAuditReceiver(DataAuditService dataAuditService, ObjectMapper objectMapper) {
        this.dataAuditService = dataAuditService;
        this.objectMapper = objectMapper;
    }


    @Bean
    public RabbitListenerErrorHandler auditErrorHandler() {
        return new RabbitListenerErrorHandler() {
            @Override
            public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) throws Exception {
                log.error("log insert error:" + message.toString(), e);
                return null;
            }
        };
    }

    /**
     * 监听队列
     *
     * @param json 接受数据并处理
     */
    @RabbitListener(queues = DataAuditRabbitConfig.LOG_QUEUE, errorHandler = "auditErrorHandler")
    public void process(String json) throws IOException {
        DataAuditDTO dto = objectMapper.readValue(json, DataAuditDTO.class);
        //处理消息,消息中有数据变更后的信息
        service.handle(dto);
    }

}
审计数据内容
2023-07-17
0