diff --git a/pkg/server/service/event-ingester/config.go b/pkg/server/service/event-ingester/config.go index 68514cb63..05d266172 100644 --- a/pkg/server/service/event-ingester/config.go +++ b/pkg/server/service/event-ingester/config.go @@ -15,6 +15,8 @@ type Config struct { Authorization auth.AuthorizationConfig `yaml:"authorization"` // ClientNameSalt is the salt to use for computing client names ClientNameSalt string `yaml:"clientNameSalt"` + // DebugUsers is a list of usernames for which to enable debug logging. + DebugUsers []string `yaml:"debugUsers"` } func (c *Config) Validate() error { diff --git a/pkg/server/service/event-ingester/handler.go b/pkg/server/service/event-ingester/handler.go index 816699322..c2e8e29aa 100644 --- a/pkg/server/service/event-ingester/handler.go +++ b/pkg/server/service/event-ingester/handler.go @@ -2,6 +2,8 @@ package eventingester import ( "context" + "crypto/sha256" + "encoding/hex" "errors" "fmt" "net" @@ -30,12 +32,18 @@ type Handler struct { geoipProvider geoip.Provider cache store.Cache clientNameSalt string + debugUsers map[string]struct{} metrics *Metrics eventRouter *eventHandler.EventRouter } -func NewHandler(log logrus.FieldLogger, clockDrift *time.Duration, geoipProvider geoip.Provider, cache store.Cache, clientNameSalt string) *Handler { +func NewHandler(log logrus.FieldLogger, clockDrift *time.Duration, geoipProvider geoip.Provider, cache store.Cache, clientNameSalt string, debugUsers []string) *Handler { + debugUsersMap := make(map[string]struct{}, len(debugUsers)) + for _, u := range debugUsers { + debugUsersMap[u] = struct{}{} + } + return &Handler{ log: log, clockDrift: clockDrift, @@ -44,6 +52,7 @@ func NewHandler(log logrus.FieldLogger, clockDrift *time.Duration, geoipProvider metrics: NewMetrics("xatu_server_event_ingester"), eventRouter: eventHandler.NewEventRouter(log, cache, geoipProvider), clientNameSalt: clientNameSalt, + debugUsers: debugUsersMap, } } @@ -224,6 +233,21 @@ func (h *Handler) Events(ctx context.Context, events []*xatu.DecoratedEvent, use if user != nil { event.Meta.Client.Name = group.ComputeClientName(username, h.clientNameSalt, event.GetMeta().GetClient().GetName()) } + + // Debug log for configured debug users + if _, isDebugUser := h.debugUsers[username]; isDebugUser { + fields := logrus.Fields{ + "client_id": event.GetMeta().GetClient().GetId(), + "client_name": event.GetMeta().GetClient().GetName(), + "group": group.Name(), + "user": username, + } + if ipAddress != "" { + fields["hashed_ip"] = hashIP(ipAddress, h.clientNameSalt) + } + + h.log.WithFields(fields).Debug("Debug user request") + } } if user != nil { @@ -253,6 +277,15 @@ func (h *Handler) Events(ctx context.Context, events []*xatu.DecoratedEvent, use return filteredEvents, nil } +// hashIP computes a SHA256 hash of the IP address and returns the first 16 hex characters. +func hashIP(ip, salt string) string { + hash := sha256.New() + hash.Write([]byte(ip)) + hash.Write([]byte(salt)) + + return hex.EncodeToString(hash.Sum(nil))[:16] +} + func (h *Handler) filterEvents(ctx context.Context, events []*xatu.DecoratedEvent, user *auth.User, group *auth.Group) ([]*xatu.DecoratedEvent, error) { _, span := observability.Tracer().Start(ctx, "EventIngester.filterEvents", diff --git a/pkg/server/service/event-ingester/ingester.go b/pkg/server/service/event-ingester/ingester.go index 7e268efd1..320943b2f 100644 --- a/pkg/server/service/event-ingester/ingester.go +++ b/pkg/server/service/event-ingester/ingester.go @@ -54,7 +54,7 @@ func NewIngester(ctx context.Context, log logrus.FieldLogger, conf *Config, cloc log: log, config: conf, auth: a, - handler: NewHandler(log, clockDrift, geoipProvider, cache, conf.ClientNameSalt), + handler: NewHandler(log, clockDrift, geoipProvider, cache, conf.ClientNameSalt, conf.DebugUsers), healthServer: healthServer, }