Migrating from Manual Audit
Move from hand-written audit code to Go Audit's ORM hooks.
Many Go projects end up with hand-rolled audit code — a helper like
recordAudit(...) called after every write. It works, but:
- Easy to forget on new code paths.
- Scattered logic, hard to audit itself.
- Manual diff computation is error-prone.
Go Audit replaces all of that with ORM-level hooks and a single entry point for code paths that bypass the ORM.
Step 1 — Install and Register
go get github.com/gopackx/go-audit
go get github.com/gopackx/go-audit/adapters/gormsqlDB, _ := gormDB.DB()
auditor, _ := audit.New(sqlDB, audit.Config{
Dialect: audit.PostgreSQL,
UserFunc: yourExistingUserExtractor,
DataAudit: audit.DataAuditConfig{Enabled: true},
})
_ = gormDB.Use(auditgorm.Plugin(auditor))
_ = auditor.AutoMigrate(ctx)Step 2 — Map Existing Config
If you had a config like this:
var auditConfig = struct {
ExcludedFields []string
ExcludedEntities []string
}{
ExcludedFields: []string{"password", "token"},
ExcludedEntities: []string{"sessions"},
}Port it straight into DataAuditConfig:
DataAudit: audit.DataAuditConfig{
Enabled: true,
ExcludeFields: auditConfig.ExcludedFields,
ExcludeEntities: auditConfig.ExcludedEntities,
}Step 3 — Remove Manual Calls
Delete your recordAudit(...) calls from code paths that go through
the ORM. The plugin now captures them automatically.
For code paths that don't go through the ORM (raw SQL, external
imports, background workers writing via database/sql), switch to
auditor.RecordDataChange:
_ = auditor.RecordDataChange(ctx, audit.DataEntry{
EntityType: "ledger_entries",
EntityID: fmt.Sprint(entry.ID),
Action: audit.ActionCreate,
NewValues: map[string]any{"amount": entry.Amount, "account": entry.Account},
})Step 4 — Migrate the Table
If your existing audit table shape doesn't match Go Audit's, the easiest path is side-by-side:
- Run
auditor.AutoMigrate(ctx)— creates a freshaudit_logstable (defaults to the nameaudit_logs; override viaDataAudit.Tableif you need to coexist). - Write a one-off migration that copies legacy rows into the new shape (or leave them in place as read-only historical data).
- Update your read UI to query the new table.
Verifying the Cut-Over
Run both systems side-by-side for a day:
- Keep the old
recordAudit(...)calls. - Enable Go Audit's plugin.
- Spot-check that rows agree on entity, action, and diff shape.
- Remove the old calls once you're confident.
Payoff
- Every code path is audited automatically, including future ones.
- Diff computation is handled, including the "nothing changed" case.
- Transaction correlation gives you cross-system traces for free.
Snapshot/Restore/Purgecome along for free.