Core
Auditor constructor, Config, and top-level types.
audit.New(db, config) → (Auditor, error)
Creates an Auditor backed by database/sql. The caller supplies an
open *sql.DB — Go Audit never opens its own connection.
auditor, err := audit.New(sqlDB, audit.Config{
Dialect: audit.PostgreSQL,
UserFunc: userFromContext,
DataAudit: audit.DataAuditConfig{Enabled: true},
})| Param | Type | Description |
|---|---|---|
db | *sql.DB | Open database handle used for audit writes. |
config | audit.Config | Dialect, user func, audit table configs. |
Returns (Auditor, error). The returned Auditor is an interface
value (see below). No DB I/O happens until you call AutoMigrate or
the first CRUD through an ORM adapter.
Validation errors returned by New:
DataAudit.Enabled && UserFunc == nil— UserFunc required when data audit is enabled.- Neither
DataAudit.EnablednorAPIAudit.Enabledis true. DataAudit.TableorAPIAudit.Tableis not a valid SQL identifier.
audit.NewWithStore(store, dialect, config) → (Auditor, error)
Alternative constructor that takes any Store implementation. Useful
for tests (with audit.NewMemoryStore()) or for routing audit writes
through a custom persistence layer.
audit.Config
type Config struct {
Dialect DialectType
UserFunc UserFunc
DataAudit DataAuditConfig
APIAudit APIAuditConfig
Logger func(format string, args ...any)
}| Field | Purpose |
|---|---|
Dialect | One of audit.PostgreSQL, audit.MySQL, audit.SQLite, or custom. |
UserFunc | Resolves (userID, userType) from context on every audit write. |
DataAudit | Data change auditing config. |
APIAudit | API call auditing config. |
Logger | Called when a storage error is swallowed under ErrorFailSilent, and by the Bun adapter's default error handler under ErrorFailLoud. Optional — defaults to log.Printf. |
audit.DataAuditConfig
type DataAuditConfig struct {
Table string
Enabled bool
ExcludeFields []string
ExcludeEntities []string
SkipOldValues bool
OnError ErrorMode
}| Field | Default | Notes |
|---|---|---|
Table | "audit_logs" | Must match ^[A-Za-z_][A-Za-z0-9_]{0,62}$. |
Enabled | false | Must be true (or APIAudit.Enabled must be). |
ExcludeFields | nil | Case-sensitive map keys; dropped before storage. |
ExcludeEntities | nil | Skip entire entity types. |
SkipOldValues | false | Skip pre-UPDATE/DELETE SELECT in adapters. |
OnError | ErrorFailLoud | See ErrorMode below. |
audit.APIAuditConfig
type APIAuditConfig struct {
Table string
Enabled bool
RedactHeaders []string
RedactBodyFields []string
MaxBodySize int
OnError ErrorMode
}| Field | Default | Notes |
|---|---|---|
Table | "audit_api_logs" | Must match ^[A-Za-z_][A-Za-z0-9_]{0,62}$. |
Enabled | false | Enables auditor.API(). |
RedactHeaders | nil | Case-insensitive header key match. |
RedactBodyFields | nil | Case-insensitive JSON key match at any depth. |
MaxBodySize | 4096 (bytes) | Oversized bodies get truncation marker. |
OnError | ErrorFailLoud | See ErrorMode below. |
audit.ErrorMode
const (
ErrorFailLoud ErrorMode = iota // auditor returns store errors; each adapter surfaces them as far as its ORM allows (default)
ErrorFailSilent // logs via Config.Logger and returns nil
)Under ErrorFailLoud the auditor returns the store error from
RecordDataChange / RecordAPICall. How far it travels depends on the
adapter:
| Adapter | What the caller sees |
|---|---|
| GORM | Attached to the *gorm.DB via db.AddError, visible in db.Error. |
| Ent | Returned from Mutate as go-audit: record <action>: <store error> together with the mutation result; bulk mutations join the per-row failures. |
| Bun | AfterQuery cannot change the error Bun returns, so the error goes to the auditbun.WithErrorHandler callback. The default handler logs via Config.Logger. |
Direct RecordDataChange / RecordAPICall | Returned as-is. |
In every adapter the ORM write has already been applied when the audit store fails — fail-loud reports, it does not roll back on its own. See the per-adapter pages for details: GORM, Bun, Ent.
Under ErrorFailSilent the auditor logs via Config.Logger and
returns nil in every adapter. Use it when the application write must
not be coupled to audit availability (e.g. the audit DB is allowed to
be briefly unavailable during maintenance).
audit.UserFunc
type UserFunc func(ctx context.Context) (userID string, userType string)Called on every audit write. Typical implementation pulls a user out of the request context set by middleware.
func userFromContext(ctx context.Context) (string, string) {
if u, ok := ctx.Value(userCtxKey).(*User); ok {
return u.ID, u.Role
}
return "system", "system"
}Required when DataAudit.Enabled == true.
Constants
const (
ActionCreate = "create"
ActionUpdate = "update"
ActionDelete = "delete"
ActionSoftDelete = "soft_delete"
ActionRestore = "restore"
)
const (
PostgreSQL DialectType = "postgres"
MySQL DialectType = "mysql"
SQLite DialectType = "sqlite"
)Auditor Interface
type Auditor interface {
RecordDataChange(ctx context.Context, entry DataEntry) error
API() APIAuditor
Query(ctx context.Context, filter DataFilter) ([]AuditLog, error)
QueryByTransaction(ctx context.Context, txID string) (*TransactionLog, error)
AutoMigrate(ctx context.Context) error
Purge(ctx context.Context, before time.Time) (PurgeResult, error)
Snapshot(ctx context.Context, entityType, entityID string, at time.Time) (map[string]any, error)
Restore(ctx context.Context, entityType, entityID string, at time.Time) (*RestoreResult, error)
Config() Config
}RecordDataChange— manual entry point used by ORM adapters and callers writing via raw SQL. Applies diff, exclusion, and context transaction ID resolution.API()— returns theAPIAuditorfor third-party call logging.Query/QueryByTransaction— read paths (see Query & Filters).AutoMigrate(ctx)— creates audit tables and indexes. Safe to call repeatedly; usesIF NOT EXISTSeverywhere.Purge(ctx, before)— deletes rows older thanbeforefrom both tables (if enabled). Returns per-table counts.Snapshot/Restore— reconstruct entity state at a past time by replaying audit history (see Query & Filters).Config()— returns the configuration the Auditor was created with.
Store Helpers
audit.NewSQLStore(db *sql.DB, d Dialect) Store
audit.NewMemoryStore() StoreNewSQLStore backs the default path. NewMemoryStore is intended
for tests.