Getting Started
Quickstart
Get go-audit running in under 5 minutes. This guide walks through installation, configuration and recording your first audit log entry.
This example wires Go Audit into a GORM + PostgreSQL app and shows audit logs appearing automatically after CRUD operations.
The Full Program
Go
package main
import (
"context"
"fmt"
"log"
"github.com/gopackx/go-audit"
auditgorm "github.com/gopackx/go-audit/adapters/gorm"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string
}
type ctxKey string
const userIDKey ctxKey = "user_id"
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=demo port=5432 sslmode=disable"
gormDB, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
sqlDB, err := gormDB.DB()
if err != nil {
log.Fatal(err)
}
// 1. Configure the auditor. Note: takes *sql.DB, not *gorm.DB.
auditor, err := audit.New(sqlDB, audit.Config{
Dialect: audit.PostgreSQL,
UserFunc: func(ctx context.Context) (string, string) {
if uid, ok := ctx.Value(userIDKey).(string); ok {
return uid, "user"
}
return "system", "system"
},
DataAudit: audit.DataAuditConfig{
Enabled: true,
ExcludeFields: []string{"password", "token"},
},
})
if err != nil {
log.Fatal(err)
}
// 2. Register the GORM plugin.
if err := gormDB.Use(auditgorm.Plugin(auditor)); err != nil {
log.Fatal(err)
}
// 3. Create audit tables (idempotent).
ctx := context.Background()
if err := auditor.AutoMigrate(ctx); err != nil {
log.Fatal(err)
}
if err := gormDB.AutoMigrate(&User{}); err != nil {
log.Fatal(err)
}
// 4. Attach a user to the context so UserFunc can resolve it.
ctx = context.WithValue(ctx, userIDKey, "admin-1")
tx := gormDB.WithContext(ctx)
// 5. Perform CRUD — audit logs appear automatically.
user := User{Name: "Ada Lovelace", Email: "ada@example.com"}
tx.Create(&user)
tx.Model(&user).Update("Email", "ada.l@example.com")
tx.Delete(&user)
// 6. Query the audit trail.
logs, _ := auditor.Query(ctx, audit.DataFilter{EntityType: "users"})
for _, l := range logs {
fmt.Printf("%s %s by %s\n", l.Action, l.EntityID, l.UserID)
}
}Go snippet
Step-by-Step Walkthrough
- Extract the
*sql.DB. Go Audit writes throughdatabase/sql, so callgormDB.DB()and pass the underlying*sql.DBtoaudit.New. - Configure the auditor. Set the dialect explicitly, provide a
UserFuncthat reads user identity from the context, and turn onDataAudit.Enabled. - Register the GORM plugin.
gormDB.Use(auditgorm.Plugin(auditor))installs all lifecycle callbacks on the GORM connection. - Run auto-migration.
auditor.AutoMigrate(ctx)creates theaudit_logs(and optionallyaudit_api_logs) tables. Safe to call repeatedly — all DDL usesIF NOT EXISTS. - Perform CRUD normally. Every
Create,Save,Updates, andDeleteis captured automatically. UsegormDB.WithContext(ctx)so theUserFuncreceives the caller's context.
Expected Output
create 1 by admin-1
update 1 by admin-1
soft_delete 1 by admin-1The third line appears as soft_delete instead of delete only if
User has a gorm.DeletedAt field. Without soft delete, you'll see
delete instead.
Next Steps
- Add API call logging
- Explore other adapters
- Browse more examples
- Want Claude to do this setup for you? See AI Integration.