在面向大型企业客户与上市公司的技术审计中,操作审计(Auditing & Compliance)是接受合规审查的第一道防线:
- 事后追责无据(Missing Audit Logs):发生了特权账号越权修改合同,但由于开发人员漏写了审计日志,导致无法追溯操作人与修改前的值;
- 审计日志被恶意篡改(Tampering Risk):黑客获取了普通数据库权限后,直接
UPDATE / DELETE审计表销毁入侵证据; - 海量日志压垮数据库(Storage Bloat):日均百万次写操作产生海量审计记录,导致关系型数据库磁盘空间耗尽、查询变慢。
BitzOrcas.Modern Auditing 模块构建了“10 级管道自动采集 + 只追加写(Append-Only)+ SQL/Mongo 冷热分层”企业级审计底座。
合规审计数据流转与冷热分层拓扑
第一步:结构化审计实体 SysAuditRecord
审计记录采用只追加写(Append-Only)模型,严禁任何 Update 操作:
using BitzOrcas.Domain.Entities;using BitzOrcas.Persistence.Metadata;
namespace BitzOrcas.Auditing.Domain;
// 审计主表按月分表存储(如 SysAuditLog_202608),杜绝单表过大[BitzTable("SysAuditLog", IsTenant = true, IsSoftDelete = false, Description = "平台不可篡改审计主表")][BitzIndex("IX_SysAuditLog_TraceId", nameof(TraceId))][BitzIndex("IX_SysAuditLog_Tenant_Time", nameof(TenantId), nameof(OccurredAt))]public sealed class SysAuditRecord : Entity<string>{ [BitzColumn(Length = 64, IsRequired = true)] public string TraceId { get; set; } = string.Empty;
[BitzColumn(Length = 64, IsRequired = true)] public string ActionName { get; set; } = string.Empty;
[BitzColumn(Length = 64, IsRequired = true)] public string OperatorId { get; set; } = string.Empty;
[BitzColumn(Length = 120)] public string OperatorName { get; set; } = string.Empty;
[BitzColumn(Length = 50)] public string ClientIp { get; set; } = string.Empty;
[BitzColumn(IsRequired = true)] public DateTimeOffset OccurredAt { get; set; }
[BitzColumn(IsRequired = true)] public long DurationMs { get; set; }
// JSON 差异快照(记录变更前与变更后字段对比) [BitzColumn(IsJson = true)] public string? DiffSnapshot { get; set; }}第二步:只读查询切片与基于 Cursor 的极速游标分页
由于审计日志体量巨大,深分页(OFFSET 1000000)会导致数据库 CPU 瞬间 100%。框架统一采用基于时间戳与主键的 Cursor 游标分页:
using BitzOrcas.Application.Abstractions.Queries;using BitzOrcas.Domain.Results;using BitzOrcas.Endpoint.Attributes;using Mediator;
namespace BitzOrcas.Auditing.Application.Queries;
// 1. 声明式查询端点:编译期生成 Minimal API 路由映射[GenerateEndpoint(HttpRoute.Query, "/api/auditing/logs", Tag = "Auditing")]// 2. 游标分页契约:基于 CursorTime 与 CursorId 实现深分页零性能抖动public sealed record QueryAuditLogsQuery( DateTimeOffset? StartTime, DateTimeOffset? EndTime, string? CursorTime, string? CursorId, int PageSize = 50) : IQuery<Result<PagedList<AuditLogDto>>>;总结
Auditing 模块满足最严苛的企业级安全审查:
- 全自动零漏记:10 级管道自动横切捕获,无需在 Handler 手写审计代码;
- Append-Only 绝对防篡改:只支持插入,禁止物理更新;
- 冷热分层高性能:分表分库 + 游标分页保障百万级审计毫秒响应。