BitzOrcas provides a 7-category audit system with sharded storage tables, an async channel-based pipeline, entity-level change tracking, and configurable retention policies.
Architecture
Request → RequestAuditMiddleware → IAuditLogger │ ▼ ChannelAuditQueue (unbounded Channel<T>) │ ▼ Background AuditWriter │ ┌──────────────────┼──────────────────┐ ▼ ▼ ▼ SysAuditLog SysActivityLog SysExternalRequestLogRecord SysSpecialLog SysCommunicationLog SysEntityPropertyChangesLog + SysSpecialLog7 audit categories
| Category | Table | Purpose |
|---|---|---|
| General | SysAuditLog | General audit trail entries |
| Activity | SysActivityLog | User activity tracking |
| Entity Property Changes | SysEntityPropertyChangesLog | Field-level change tracking |
| Communication | SysCommunicationLog | Inbound/outbound API calls |
| External Request | SysExternalRequestLogRecord | Outbound HTTP calls with details |
| Special | SysSpecialLog | Special/sensitive events |
Entity change tracking
SqlSugarEntityChangeAuditor tracks field-level changes to any entity:
{ "entityType": "NoteEntity", "entityId": "abc123", "changes": [ { "property": "Title", "oldValue": "Old", "newValue": "New" }, { "property": "Content", "oldValue": "...", "newValue": "..." } ]}Audit pipeline components
| Component | Location | Purpose |
|---|---|---|
IAuditLogger | BitzOrcas.Infrastructure | Enqueue audit entries |
ChannelAuditQueue | BitzOrcas.Infrastructure | Background queue processor |
AuditEntryNormalizer | BitzOrcas.Infrastructure | Normalize/validate entries |
IAuditLogStore | BitzOrcas.Infrastructure | Persistence port |
SqlSugarAuditLogStore | Infra.SqlSugar.Auditing | SqlSugar implementation |
IAuditQueryPort | BitzOrcas.Infrastructure | Read-only query port |
IAuditRetentionPort | BitzOrcas.Infrastructure | Retention cleanup port |
IAuditTableInitializer | BitzOrcas.Infrastructure | Schema init port |
Sharded entity hierarchy
Audit tables use a separate entity hierarchy with built-in sharding:
AuditEntityBase (snowflake Id)├── AuditTenantEntityBase (+ TenantId)│ └── AuditTenantSoftDeleteEntityBase (+ IsDeleted)│ ├── SysAuditLogEntity│ ├── SysActivityLogEntity│ ├── SysCommunicationLogEntity│ ├── SysExternalRequestLogRecordEntity│ ├── SysEntityPropertyChangesLogEntity│ └── SysSpecialLogEntityRetention policy
Configured via Quartz.NET in the JobHost:
{ "Audit": { "Retention": { "Enabled": true, "CronExpression": "0 0 2 * * ?", "MaxAgeDays": 90 } }}AuditRetentionQuartzJob runs on the Cron schedule, calling IAuditRetentionPort.CleanupAsync() to purge records older than the retention period.
Audit exclusions
Use [AuditIgnore] attribute to exclude specific request handlers or properties from audit:
[AuditIgnore]public class PingQueryHandler : IRequestHandler<PingQuery, Pong> { }Audit endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/audit/logs | GET | Paginated audit log query |
/api/audit/activity | GET | Activity log query |
/api/audit/entity-changes | GET | Entity change history |
/api/audit/external-requests | GET | External request audit |