Documentation
¶
Overview ¶
Package audit records an append-only actor/action/target trail through a pluggable Sink, with a Bun-backed sink and a Fiber helper that prefills request context.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Entry ¶
type Entry struct {
bun.BaseModel `bun:"table:audit_log,alias:al"`
ID int64 `bun:"id,pk,autoincrement"`
Actor string `bun:"actor"`
Action string `bun:"action,notnull"`
Target string `bun:"target"`
TargetID string `bun:"target_id"`
Metadata map[string]any `bun:"metadata"`
IP string `bun:"ip"`
RequestID string `bun:"request_id"`
CreatedAt time.Time `bun:"created_at,notnull"`
}
Entry is one audit record.
type Recorder ¶
type Recorder struct {
// contains filtered or unexported fields
}
Recorder records entries through a Sink.
func (*Recorder) FromRequest ¶
FromRequest returns an Entry prefilled with Actor (via the configured extractor, if any), IP, and RequestID. The caller fills Action/Target/etc and passes it to Record.
func (*Recorder) Record ¶
Record sets CreatedAt (when zero) and writes the entry to the sink.
Example ¶
Record an audit entry and read it back.
package main
import (
"context"
"database/sql"
"fmt"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/sqlitedialect"
"github.com/uptrace/bun/driver/sqliteshim"
"github.com/rahmadafandi/fibr/audit"
)
func main() {
sqldb, _ := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
db := bun.NewDB(sqldb, sqlitedialect.New())
defer db.Close()
ctx := context.Background()
_ = audit.Migrate(ctx, db)
rec := audit.New(audit.NewBunSink(db))
_ = rec.Record(ctx, audit.Entry{
Actor: "admin",
Action: "user.suspend",
Target: "user",
TargetID: "99",
})
entries, _ := audit.List(ctx, db, audit.Filter{Actor: "admin"})
fmt.Println(entries[0].Action, entries[0].TargetID)
}
Output: user.suspend 99
Click to show internal directories.
Click to hide internal directories.