You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.2 KiB
130 lines
4.2 KiB
// Package subscribers provides domain event subscriber implementations. |
|
package subscribers |
|
|
|
import ( |
|
"encoding/hex" |
|
|
|
"lol.mleku.dev/log" |
|
|
|
"next.orly.dev/pkg/domain/events" |
|
) |
|
|
|
// LoggingSubscriber logs domain events for analytics and debugging. |
|
type LoggingSubscriber struct { |
|
logLevel string // "debug", "info", "trace" |
|
} |
|
|
|
// NewLoggingSubscriber creates a new logging subscriber. |
|
// logLevel controls verbosity: "trace" logs all events, "debug" logs important events, |
|
// "info" logs only significant events like membership changes. |
|
func NewLoggingSubscriber(logLevel string) *LoggingSubscriber { |
|
if logLevel == "" { |
|
logLevel = "debug" |
|
} |
|
return &LoggingSubscriber{logLevel: logLevel} |
|
} |
|
|
|
// Handle processes a domain event by logging it. |
|
func (s *LoggingSubscriber) Handle(event events.DomainEvent) { |
|
switch e := event.(type) { |
|
case *events.EventSaved: |
|
s.logEventSaved(e) |
|
case *events.EventDeleted: |
|
s.logEventDeleted(e) |
|
case *events.FollowListUpdated: |
|
s.logFollowListUpdated(e) |
|
case *events.ACLMembershipChanged: |
|
s.logACLMembershipChanged(e) |
|
case *events.PolicyConfigUpdated: |
|
s.logPolicyConfigUpdated(e) |
|
case *events.UserAuthenticated: |
|
s.logUserAuthenticated(e) |
|
case *events.MemberJoined: |
|
s.logMemberJoined(e) |
|
case *events.MemberLeft: |
|
s.logMemberLeft(e) |
|
case *events.ConnectionOpened: |
|
s.logConnectionOpened(e) |
|
case *events.ConnectionClosed: |
|
s.logConnectionClosed(e) |
|
default: |
|
if s.logLevel == "trace" { |
|
log.T.F("domain event: %s", event.EventType()) |
|
} |
|
} |
|
} |
|
|
|
// Supports returns true for all event types. |
|
func (s *LoggingSubscriber) Supports(eventType string) bool { |
|
return true |
|
} |
|
|
|
func (s *LoggingSubscriber) logEventSaved(e *events.EventSaved) { |
|
if s.logLevel == "trace" { |
|
pubkeyHex := hex.EncodeToString(e.Event.Pubkey) |
|
log.T.F("event saved: kind=%d pubkey=%s admin=%v owner=%v", |
|
e.Event.Kind, pubkeyHex[:16], e.IsAdmin, e.IsOwner) |
|
} |
|
} |
|
|
|
func (s *LoggingSubscriber) logEventDeleted(e *events.EventDeleted) { |
|
if s.logLevel == "trace" || s.logLevel == "debug" { |
|
eventIDHex := hex.EncodeToString(e.EventID) |
|
deletedByHex := hex.EncodeToString(e.DeletedBy) |
|
log.D.F("event deleted: id=%s by=%s", eventIDHex[:16], deletedByHex[:16]) |
|
} |
|
} |
|
|
|
func (s *LoggingSubscriber) logFollowListUpdated(e *events.FollowListUpdated) { |
|
if s.logLevel == "trace" || s.logLevel == "debug" { |
|
adminHex := hex.EncodeToString(e.AdminPubkey) |
|
log.D.F("follow list updated: admin=%s added=%d removed=%d", |
|
adminHex[:16], len(e.AddedFollows), len(e.RemovedFollows)) |
|
} |
|
} |
|
|
|
func (s *LoggingSubscriber) logACLMembershipChanged(e *events.ACLMembershipChanged) { |
|
// Always log ACL changes at info level - they're significant |
|
pubkeyHex := hex.EncodeToString(e.Pubkey) |
|
log.I.F("ACL membership changed: pubkey=%s %s->%s reason=%s", |
|
pubkeyHex[:16], e.PrevLevel, e.NewLevel, e.Reason) |
|
} |
|
|
|
func (s *LoggingSubscriber) logPolicyConfigUpdated(e *events.PolicyConfigUpdated) { |
|
// Always log policy changes at info level |
|
updatedByHex := hex.EncodeToString(e.UpdatedBy) |
|
log.I.F("policy config updated by %s: %d changes", updatedByHex[:16], len(e.Changes)) |
|
} |
|
|
|
func (s *LoggingSubscriber) logUserAuthenticated(e *events.UserAuthenticated) { |
|
if s.logLevel == "trace" || s.logLevel == "debug" { |
|
pubkeyHex := hex.EncodeToString(e.Pubkey) |
|
log.D.F("user authenticated: pubkey=%s level=%s firstTime=%v", |
|
pubkeyHex[:16], e.AccessLevel, e.IsFirstTime) |
|
} |
|
} |
|
|
|
func (s *LoggingSubscriber) logMemberJoined(e *events.MemberJoined) { |
|
// Always log member joins at info level |
|
pubkeyHex := hex.EncodeToString(e.Pubkey) |
|
log.I.F("member joined: pubkey=%s invite=%s", pubkeyHex[:16], e.InviteCode) |
|
} |
|
|
|
func (s *LoggingSubscriber) logMemberLeft(e *events.MemberLeft) { |
|
// Always log member departures at info level |
|
pubkeyHex := hex.EncodeToString(e.Pubkey) |
|
log.I.F("member left: pubkey=%s", pubkeyHex[:16]) |
|
} |
|
|
|
func (s *LoggingSubscriber) logConnectionOpened(e *events.ConnectionOpened) { |
|
if s.logLevel == "trace" { |
|
log.T.F("connection opened: id=%s remote=%s", e.ConnectionID, e.RemoteAddr) |
|
} |
|
} |
|
|
|
func (s *LoggingSubscriber) logConnectionClosed(e *events.ConnectionClosed) { |
|
if s.logLevel == "trace" || s.logLevel == "debug" { |
|
log.D.F("connection closed: id=%s duration=%v events_rx=%d events_tx=%d", |
|
e.ConnectionID, e.Duration, e.EventsReceived, e.EventsPublished) |
|
} |
|
}
|
|
|