Files
RenewCMS/internal/infrastructure/auditing/recorder.go
T

58 lines
1.4 KiB
Go

package auditing
import (
"RenewCMS/internal/domain/audit"
"context"
"log"
"time"
)
type Recorder struct {
repository audit.Repository
now func() time.Time
logger *log.Logger
}
var _ audit.Recorder = &Recorder{}
func NewRecorder(repository audit.Repository, now func() time.Time, logger *log.Logger) *Recorder {
return &Recorder{repository, now, logger}
}
func (r *Recorder) Record(ctx context.Context, event audit.Event) {
defer func() {
if recovered := recover(); recovered != nil {
r.logger.Printf("audit: writing the %s event panicked: %v", event.Action, recovered)
}
}()
event = r.complete(ctx, event).Truncated()
if err := event.Validate(); err != nil {
r.logger.Printf("audit: dropped the %s event: %v", event.Action, err)
return
}
if _, err := r.repository.Append(event); err != nil {
r.logger.Printf("audit: failed to write the %s event: %v", event.Action, err)
}
}
func (r *Recorder) complete(ctx context.Context, event audit.Event) audit.Event {
origin, _ := audit.OriginFrom(ctx)
if event.Actor.Type == "" {
event.Actor = origin.Actor
}
if event.Source == "" {
event.Source = origin.Source
}
if event.IP == nil && origin.IP != "" {
ip := origin.IP
event.IP = &ip
}
if event.UserAgent == nil && origin.UserAgent != "" {
userAgent := origin.UserAgent
event.UserAgent = &userAgent
}
event.CreatedAt = r.now().UTC()
return event
}