全局数据生命周期审计功能
应用场景
需要记录数据什么时候被修改,什么人修改的,修改后的数据是什么,当数据有变更后,响应变更事件。
功能使用前提
- 确保微服务连接到了redis,rabbitmq,并且已经正确配置spring相关参数
- 日志服务升级到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语句操作的数据。需要自己调用日志相关的接口自己实现审计功能。
- 增加依赖
之前的log-client依赖可以删除,新的starter集成了之前的接口日志配置功能。Config.class 中的日志Aop可以去掉了。
<dependency>
<groupId>com.hvisions</groupId>
<artifactId>log-spring-boot-starter</artifactId>
<version>1.8.1</version>
</dependency>
- 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);
}
}