package audit import ( "context" "time" ) type contextKey int const ( keyRequestMeta contextKey = iota keyActor ) type RequestMeta struct { IP string RequestID string UserAgent string } type Actor struct { ID string Type string } func WithRequestMeta(ctx context.Context, meta RequestMeta) context.Context { return context.WithValue(ctx, keyRequestMeta, meta) } func WithActor(ctx context.Context, actor Actor) context.Context { return context.WithValue(ctx, keyActor, actor) } func RequestMetaFromContext(ctx context.Context) (RequestMeta, bool) { meta, ok := ctx.Value(keyRequestMeta).(RequestMeta) return meta, ok } func ActorFromContext(ctx context.Context) (Actor, bool) { actor, ok := ctx.Value(keyActor).(Actor) return actor, ok } func enrichEntry(ctx context.Context, entry Entry) Entry { if entry.At == 0 { entry.At = time.Now().Unix() } if meta, ok := RequestMetaFromContext(ctx); ok { if entry.IP == "" { entry.IP = meta.IP } if entry.RequestID == "" { entry.RequestID = meta.RequestID } if entry.UserAgent == "" { entry.UserAgent = meta.UserAgent } } if entry.ActorID == "" || entry.ActorType == "" { if actor, ok := ActorFromContext(ctx); ok { if entry.ActorID == "" { entry.ActorID = actor.ID } if entry.ActorType == "" { entry.ActorType = actor.Type } } } return entry }