go-auditGo Audit
API Reference

Data Audit API

Record and query data change events.

Auditor.RecordDataChange(ctx, entry) → error

Records a single data change. Normally called by ORM adapters, but you can invoke it directly from code paths that bypass the adapter (raw SQL, external imports, maintenance jobs).

_ = auditor.RecordDataChange(ctx, audit.DataEntry{
    EntityType: "ledger_entries",
    EntityID:   "le-42",
    Action:     audit.ActionCreate,
    NewValues:  map[string]any{"amount": 500},
})

Behavior:

  • Skips writing when DataAudit.Enabled == false.
  • Skips writing when EntityType is in DataAudit.ExcludeEntities.
  • Applies diff and field exclusion before persistence.
  • Suppresses UPDATE rows where nothing changed after exclusion.
  • For DELETEs without captured OldValues, uses NewValues as the old state.
  • Reads UserFunc for user_id / user_type.
  • Uses entry.TransactionID if set; otherwise reads it from the context via audit.TransactionIDFromContext(ctx).

audit.DataEntry

type DataEntry struct {
    EntityType    string
    EntityID      string
    Action        string
    OldValues     map[string]any
    NewValues     map[string]any
    Metadata      map[string]any
    TransactionID string
}
FieldRequiredNotes
EntityTypeYesTable / model name.
EntityIDYesPrimary key value. Compound PKs are JSON-encoded arrays.
ActionYesOne of the Action* constants.
OldValuesNoRequired for meaningful UPDATE / DELETE audit entries.
NewValuesNoRequired for CREATE / UPDATE entries.
MetadataNoApplication-specific context (IP, reason, request id, …).
TransactionIDNoOverrides context-derived transaction ID when set.

Auditor.Query(ctx, filter) → ([]AuditLog, error)

Fetches data audit records matching a filter. Default order is created_at DESC.

logs, err := auditor.Query(ctx, audit.DataFilter{
    EntityType: "users",
    Limit:      50,
})

audit.DataFilter

type DataFilter struct {
    EntityType    string
    EntityID      string
    Action        string
    UserID        string
    TransactionID string
    DateFrom      time.Time
    DateTo        time.Time
    Limit         int
    Offset        int
}

All fields are optional. Zero values are ignored by the query builder.

audit.AuditLog

type AuditLog struct {
    ID            uint64          `json:"id"`
    EntityType    string          `json:"entity_type"`
    EntityID      string          `json:"entity_id"`
    Action        string          `json:"action"`
    OldValues     json.RawMessage `json:"old_values,omitempty"`
    NewValues     json.RawMessage `json:"new_values,omitempty"`
    UserID        string          `json:"user_id"`
    UserType      string          `json:"user_type,omitempty"`
    Metadata      json.RawMessage `json:"metadata,omitempty"`
    TransactionID string          `json:"transaction_id,omitempty"`
    CreatedAt     time.Time       `json:"created_at"`
}

On this page