diff --git a/ddtrace/tracer/option.go b/ddtrace/tracer/option.go index 2dc38796ad..c1499e190f 100644 --- a/ddtrace/tracer/option.go +++ b/ddtrace/tracer/option.go @@ -829,3 +829,42 @@ func StackFrames(n, skip uint) FinishOption { cfg.SkipStackFrames = skip } } + +// UserTagOption represents a function that can be provided as a parameter to SetUser. +// This is used to normalize user tags key/value pairs. +type UserTagOption func() (key string, val interface{}) + +// WithUserEmailTag emits the normalized key/value UserTagOption holding user email information. +func WithUserEmailTag(email string) UserTagOption { + return func() (key string, val interface{}) { + return "usr.email", email + } +} + +// WithUserNameTag emits the normalized key/value UserTagOption holding user name information. +func WithUserNameTag(name string) UserTagOption { + return func() (key string, val interface{}) { + return "usr.name", name + } +} + +// WithUserSessionIDTag emits the normalized key/value UserTagOption holding user session id information. +func WithUserSessionIDTag(sessionID string) UserTagOption { + return func() (key string, val interface{}) { + return "usr.session_id", sessionID + } +} + +// WithUserRoleTag emits the normalized key/value UserTagOption holding user role information. +func WithUserRoleTag(role string) UserTagOption { + return func() (key string, val interface{}) { + return "usr.role", role + } +} + +// WithUserScopeTag emits the normalized key/value UserTagOption holding user scope information. +func WithUserScopeTag(scope string) UserTagOption { + return func() (key string, val interface{}) { + return "usr.scope", scope + } +} diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 8532f5cbcd..efd6f51a14 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -153,6 +153,24 @@ func Inject(ctx ddtrace.SpanContext, carrier interface{}) error { return internal.GetGlobalTracer().Inject(ctx, carrier) } +// SetUser tags the root span of s with the provided user id as well as the +// optional tags provided as userTagOption parameters. This allows user identification +// across all spans of a trace. +func SetUser(s Span, id string, opts ...UserTagOption) { + if s == nil { + return + } + if span, ok := s.(*span); ok { + if span.context != nil { + span = span.context.trace.root + } + span.SetTag("usr.id", id) + for _, fn := range opts { + span.SetTag(fn()) + } + } +} + // payloadQueueSize is the buffer size of the trace channel. const payloadQueueSize = 1000