easyAudit 提供一套可插拔的操作审计能力:通过 AOP 切面拦截关键修改方法,异步采集用户、时间、操作类型、HTTP 信息、数据前后状态,并通过可配置通道(本地直达 / Kafka)分发,最终由可插拔的处理器(Handler)完成持久化、查询、报表导出等。
本仓库包含:
audit/:审计框架(可作为 Maven 依赖引入)audit-core:注解、模型、SPI 扩展点(无业务依赖)audit-spring-boot-starter:Spring Boot 自动装配(AOP、通道、默认 Provider)
demo/:Spring Boot 示例应用(MyBatis-Plus + MySQL 8),演示修改→审计→落库→查询/导出
在业务工程 pom.xml 引入:
<dependency>
<groupId>com.yqz</groupId>
<artifactId>audit-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>并确保你的业务工程具备 AOP 运行时依赖(因为审计通过 AOP 工作):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>在业务应用的 application.yml 中配置(示例):
audit:
enabled: true
async: true
channel: local # local / kafka
# kafka 可选(只有当 channel=kafka 且引入 spring-kafka 时才生效)
audit:
kafka:
topic: audit-record
consumer-enabled: falseaudit.enabled:审计开关audit.async:是否异步分发(建议开启)audit.channel:local:本地直达(将AuditRecord直接交给AuditRecordHandler处理)kafka:发送到 Kafka(需引入spring-kafka并配置 KafkaTemplate;consumer 可选启用)
对“关键修改方法”(例如:项目名称修改、状态变更、金额变更)加注解即可触发审计。
@AuditLog(
action = "PROJECT_UPDATE",
entityType = "ResearchProject",
entityId = "#id",
recordArgs = true
)
public ResearchProjectEntity updateName(Long id, String name) {
// 更新 DB...
}字段含义:
action:操作类型(用于查询/报表维度)entityType:实体类型(可选,但推荐填写,便于检索)entityId:实体 ID(SpEL 表达式,如#id、#req.id)recordArgs/recordResult:是否记录入参/返回值(默认关闭,避免敏感信息与大对象)
审计的入库模型是统一结构(如 traceId/action/entityType/entityId/occurredAt/...),而业务对象差异体现在:
beforeJson:方法执行前的快照(JSON 字符串)afterJson:方法执行后的快照(JSON 字符串)
也就是说:表结构固定,快照内容可变,从而适配不同公司/不同业务线对审计内容的差异化需求。
默认返回匿名用户;业务方可在应用里提供同类型 Bean 覆盖(示例:从请求头或安全框架读取):
@Component
public class HeaderAuditUserProvider implements AuditUserProvider {
@Override
public AuditUser currentUser() {
return new AuditUser("u001", "张三");
}
}决定 beforeJson/afterJson 记录什么。
常见策略:
- 查 DB 得到 before/after(更准确,适合合规追溯)
- 只记录关键信息(如金额字段),返回一个小 DTO(减少敏感与存储开销)
demo 中提供了 DbAuditSnapshotProvider:通过 id 查询 DB 得到 before/after。
注意:如果你希望用
#id获取实体 id,请确保编译开启了参数名保留(maven-compiler-plugin的<parameters>true</parameters>)。本仓库根pom.xml已默认开启。
本框架把审计记录标准化为 AuditRecord,具体“写到哪里”交由 AuditRecordHandler 决定:
- 写 MySQL(demo 示例)
- 写 ES / ClickHouse / 日志系统
- 写文件归档、对接科研合规平台等
demo 使用 MySQL 8;你需要自行建库/建表/插入数据(或按需执行 demo/src/main/resources/schema.sql)。
并在 demo/src/main/resources/application.yml 填写正确的:
spring.datasource.urlspring.datasource.usernamespring.datasource.password
(当前 demo 默认关闭 SQL 自动初始化:spring.sql.init.mode: never)
mvn -pl demo -DskipTests spring-boot:run- 创建项目:
POST /projects- Body:
{"name":"项目A"}
- 修改项目名称(触发审计):
PUT /projects/{id}/name- Body:
{"name":"项目A(改名)"} - 可选请求头模拟用户:
X-User-Id: u001X-User-Name: 张三
- 查询审计记录:
GET /audit/records - 导出 CSV:
GET /audit/export.csv
通常是 “before 快照取不到实体 id(无法查 DB)” 导致:
- 没开启参数名保留时,
#id解析不到 - 业务方法第一个参数不是 id,且快照提取器只按 id 查询
本仓库已做了两层兜底:
- 根
pom.xml已开启编译参数名保留:<parameters>true</parameters> - AOP 同时提供
p0/a0/args[0]等变量用于兜底取参
如果你的业务方法签名更复杂(例如 update(req)),建议:
- 在
@AuditLog(entityId="#req.id")指明实体 id - 或在自定义
AuditSnapshotProvider中按你的入参结构取 id
内部演示项目,可按需扩展与二次开发。