Skip to content

Commit

Permalink
contrib/99designs/gqlgen: add WithCustomTag option (#2598)
Browse files Browse the repository at this point in the history
  • Loading branch information
samsullivan authored Mar 13, 2024
1 parent 1e168dd commit 8f46a7a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
28 changes: 20 additions & 8 deletions contrib/99designs/gqlgen/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ const defaultServiceName = "graphql"
type config struct {
serviceName string
analyticsRate float64
tags map[string]interface{}
}

// An Option configures the gqlgen integration.
type Option func(t *config)
type Option func(cfg *config)

func defaults(t *config) {
t.serviceName = namingschema.ServiceNameOverrideV0(defaultServiceName, defaultServiceName)
t.analyticsRate = globalconfig.AnalyticsRate()
func defaults(cfg *config) {
cfg.serviceName = namingschema.ServiceNameOverrideV0(defaultServiceName, defaultServiceName)
cfg.analyticsRate = globalconfig.AnalyticsRate()
cfg.tags = make(map[string]interface{})
}

// WithAnalytics enables or disables Trace Analytics for all started spans.
Expand All @@ -37,14 +39,24 @@ func WithAnalytics(on bool) Option {

// WithAnalyticsRate sets the sampling rate for Trace Analytics events correlated to started spans.
func WithAnalyticsRate(rate float64) Option {
return func(t *config) {
t.analyticsRate = rate
return func(cfg *config) {
cfg.analyticsRate = rate
}
}

// WithServiceName sets the given service name for the gqlgen server.
func WithServiceName(name string) Option {
return func(t *config) {
t.serviceName = name
return func(cfg *config) {
cfg.serviceName = name
}
}

// WithCustomTag will attach the value to the span tagged by the key.
func WithCustomTag(key string, value interface{}) Option {
return func(cfg *config) {
if cfg.tags == nil {
cfg.tags = make(map[string]interface{})
}
cfg.tags[key] = value
}
}
16 changes: 12 additions & 4 deletions contrib/99designs/gqlgen/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,17 @@ func (t *gqlTracer) InterceptOperation(ctx context.Context, next graphql.Operati
func (t *gqlTracer) InterceptField(ctx context.Context, next graphql.Resolver) (res any, err error) {
opCtx := graphql.GetOperationContext(ctx)
fieldCtx := graphql.GetFieldContext(ctx)
opts := []tracer.StartSpanOption{
opts := make([]tracer.StartSpanOption, 0, 6+len(t.cfg.tags))
for k, v := range t.cfg.tags {
opts = append(opts, tracer.Tag(k, v))
}
opts = append(opts,
tracer.Tag(tagGraphqlField, fieldCtx.Field.Name),
tracer.Tag(tagGraphqlOperationType, opCtx.Operation.Operation),
tracer.Tag(ext.Component, componentName),
tracer.ResourceName(fmt.Sprintf("%s.%s", fieldCtx.Object, fieldCtx.Field.Name)),
tracer.Measured(),
}
)
if !math.IsNaN(t.cfg.analyticsRate) {
opts = append(opts, tracer.Tag(ext.EventSampleRate, t.cfg.analyticsRate))
}
Expand All @@ -172,14 +176,18 @@ func (*gqlTracer) InterceptResponse(ctx context.Context, next graphql.ResponseHa
// also creates child spans (orphans in the case of a subscription) for the
// read, parsing and validation phases of the operation.
func (t *gqlTracer) createRootSpan(ctx context.Context, opCtx *graphql.OperationContext) (ddtrace.Span, context.Context) {
opts := []tracer.StartSpanOption{
opts := make([]tracer.StartSpanOption, 0, 7+len(t.cfg.tags))
for k, v := range t.cfg.tags {
opts = append(opts, tracer.Tag(k, v))
}
opts = append(opts,
tracer.SpanType(ext.SpanTypeGraphQL),
tracer.Tag(ext.SpanKind, ext.SpanKindServer),
tracer.ServiceName(t.cfg.serviceName),
tracer.Tag(ext.Component, componentName),
tracer.ResourceName(opCtx.RawQuery),
tracer.StartTime(opCtx.Stats.OperationStart),
}
)
if !math.IsNaN(t.cfg.analyticsRate) {
opts = append(opts, tracer.Tag(ext.EventSampleRate, t.cfg.analyticsRate))
}
Expand Down
10 changes: 10 additions & 0 deletions contrib/99designs/gqlgen/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ func TestOptions(t *testing.T) {
assert.Equal(0.5, root.Tag(ext.EventSampleRate))
},
},
"WithCustomTag": {
tracerOpts: []Option{
WithCustomTag("customTag1", "customValue1"),
WithCustomTag("customTag2", "customValue2"),
},
test: func(assert *assert.Assertions, root mocktracer.Span) {
assert.Equal("customValue1", root.Tag("customTag1"))
assert.Equal("customValue2", root.Tag("customTag2"))
},
},
} {
t.Run(name, func(t *testing.T) {
assert := assert.New(t)
Expand Down

0 comments on commit 8f46a7a

Please sign in to comment.