Skip to main content

数据变更审计(DataChangeInfo / 数据操作日志)

通过 IChameleonDbContext 执行的每次写操作(新增 / 更新 / 删除)都会自动产生一条数据变更审计日志(又称"数据操作日志 / 变更记录 / 修改前后值"),记录变更前后的完整数据。使用方无需编写任何审计代码。

概述​

审计机制分两层:

  • 组件层:Chameleon.Database 内部维护"变更日志管道",每次写操作成功后生成 DataChangeInfo(含变更前后快照),通过 ChameleonDbContextOptions 的回调交给宿主
  • 平台层:宿主(ChameleonSDK 注册)将变更日志写入待处理表 system_logdataoperationpending,由平台后续消费为完整的数据操作日志

与相邻概念的边界:对象审计日志是对象配置中可视化的审计开关与查询界面;本文档描述的是 DbContext 写操作自动产生的底层变更记录,两者面向同一份数据变更事实。

记录内容​

每条变更日志包含:

项说明
对象编码metaobjectcode,数据所属对象
动作action:Add / Update / Delete
变更前before(JSON),更新/删除时的原数据快照
变更后after(JSON),新增/更新后的数据
数据 IDdataid,被操作记录的 _id
操作时间actiontime / createdtime(UTC)
组织organization,来自当前上下文

更新操作执行前,组件会先查出原数据作为 before 快照,因此更新是有开销的读后写。

监控范围​

平台默认只监控非 system_ 前缀的业务表;system_ 前缀的系统表中仅 system_userinformation 在白名单内。系统表自身的变更不产生此类审计日志。

与事务的关系​

  • 非事务写操作:变更日志立即写出
  • 事务中的写操作:日志先在内存中累积,提交前统一写出;事务回滚时日志被丢弃,因此不会出现"数据回滚了但日志还在"的错账

数据结构(AI 参考)​

public enum DataChangeActionEnum { Add, Update, Delete }

public class DataChangeItem
{
public ObjectData Before { get; set; } // 变更前快照(更新/删除时)
public ObjectData After { get; set; } // 变更后快照(新增/更新时)
}

public class DataChangeInfo
{
public DataChangeActionEnum Action { get; set; }
public DateTime ActionTime { get; set; } // 默认 DateTime.UtcNow
public string MetaObjectCode { get; set; }
public List<DataChangeItem> Items { get; set; }
}

ChameleonDbContextOptions 中与审计相关的扩展点(宿主/微服务自建 ChameleonDbContext 时可配置):

属性类型说明
OnDataChangedAction<IChameleonDbContext, DataChangeInfo>每次写操作成功后触发
OnWriteDataChangedLogAction<IChameleonDbContext, List<DataChangeInfo>>批量写出日志(事务提交时或非事务即时)

使用示例​

平台侧查询变更记录​

数据变更后的完整操作日志可在平台的对象审计日志中查看(含操作人、时间、前后值),或在 C# 脚本中查询待处理表:

var logs = await sdk.DbContext.GetListBySqlAsync(
@"SELECT * FROM ""system_logdataoperationpending""
WHERE ""metaobjectcode"" = @code
ORDER BY ""createdtime"" DESC
LIMIT 50",
new Dictionary<string, object> { { "code", "LeaveApplication" } }
);

注意事项​

  • 审计日志由平台异步消费,system_logdataoperationpending 是中间表,不要在其中长期保留或依赖它做实时查询;消费后的正式数据以平台数据操作日志为准
  • 更新操作因需要读取变更前快照,性能略高于纯写入;大批量高频更新时需评估
  • 通过 GetDatabase() 直接执行的 ORM 写操作不产生审计日志,需要审计时必须走 IChameleonDbContext 的方法

下一步​

相关实现​

  • 变更日志管道:chameleon-core/components/Chameleon.Database/DbContext/ChameleonDbContextAuditTrail.cs
  • 数据结构:chameleon-core/components/Chameleon.Database/DataChangeInfo.cs
  • 平台侧落地:chameleon/server/Components/Chameleon.SDK/ChameleonSdkInjectionExtensions.cs(写入 system_logdataoperationpending)