diff --git a/ddtrace/tracer/textmap.go b/ddtrace/tracer/textmap.go index 3224016fa0..5e0302df1f 100644 --- a/ddtrace/tracer/textmap.go +++ b/ddtrace/tracer/textmap.go @@ -110,11 +110,15 @@ type PropagatorConfig struct { ParentHeader string // PriorityHeader specifies the map key that will be used to store the sampling priority. - // It deafults to DefaultPriorityHeader. + // It defaults to DefaultPriorityHeader. PriorityHeader string // MaxTagsHeaderLen specifies the maximum length of trace tags header value. MaxTagsHeaderLen int + + // B3 specifies if B3 headers should be added for trace propagation. + // See https://github.com/openzipkin/b3-propagation + B3 bool } // NewPropagator returns a new propagator which uses TextMap to inject @@ -151,28 +155,39 @@ type chainedPropagator struct { } // getPropagators returns a list of propagators based on the list found in the -// given environment variable. If the list doesn't contain a value or has invalid -// values, the default propagator will be returned. +// given environment variable. If the list doesn't contain any valid values the +// default propagator will be returned. Any invalid values in the list will log +// a warning and be ignored. func getPropagators(cfg *PropagatorConfig, env string) []Propagator { dd := &propagator{cfg} ps := os.Getenv(env) + defaultPs := []Propagator{dd} + if cfg.B3 { + defaultPs = append(defaultPs, &propagatorB3{}) + } if ps == "" { - return []Propagator{dd} + return defaultPs } var list []Propagator + if cfg.B3 { + list = append(list, &propagatorB3{}) + } for _, v := range strings.Split(ps, ",") { switch strings.ToLower(v) { case "datadog": list = append(list, dd) case "b3": - list = append(list, &propagatorB3{}) + if !cfg.B3 { + // propagatorB3 hasn't already been added, add a new one. + list = append(list, &propagatorB3{}) + } default: log.Warn("unrecognized propagator: %s\n", v) } } if len(list) == 0 { // return the default - return []Propagator{dd} + return defaultPs } return list } diff --git a/ddtrace/tracer/textmap_test.go b/ddtrace/tracer/textmap_test.go index 1fb0fbd818..41f4608b66 100644 --- a/ddtrace/tracer/textmap_test.go +++ b/ddtrace/tracer/textmap_test.go @@ -458,6 +458,58 @@ func TestB3(t *testing.T) { assert.True(ok) assert.Equal(2, p) }) + + t.Run("config", func(t *testing.T) { + os.Setenv("DD_PROPAGATION_STYLE_INJECT", "datadog") + defer os.Unsetenv("DD_PROPAGATION_STYLE_INJECT") + + var tests = []struct { + in []uint64 + out map[string]string + }{ + { + []uint64{1412508178991881, 1842642739201064}, + map[string]string{ + b3TraceIDHeader: "000504ab30404b09", + b3SpanIDHeader: "00068bdfb1eb0428", + }, + }, + { + []uint64{9530669991610245, 9455715668862222}, + map[string]string{ + b3TraceIDHeader: "0021dc1807524785", + b3SpanIDHeader: "002197ec5d8a250e", + }, + }, + { + []uint64{1, 1}, + map[string]string{ + b3TraceIDHeader: "0000000000000001", + b3SpanIDHeader: "0000000000000001", + }, + }, + } + + for _, test := range tests { + t.Run("", func(t *testing.T) { + tracer := newTracer(WithPropagator(NewPropagator(&PropagatorConfig{B3: true}))) + root := tracer.StartSpan("web.request").(*span) + root.SetTag(ext.SamplingPriority, -1) + root.SetBaggageItem("item", "x") + ctx, ok := root.Context().(*spanContext) + ctx.traceID = test.in[0] + ctx.spanID = test.in[1] + headers := TextMapCarrier(map[string]string{}) + err := tracer.Inject(ctx, headers) + + assert := assert.New(t) + assert.True(ok) + assert.Nil(err) + assert.Equal(test.out[b3TraceIDHeader], headers[b3TraceIDHeader]) + assert.Equal(test.out[b3SpanIDHeader], headers[b3SpanIDHeader]) + }) + } + }) } func assertTraceTags(t *testing.T, expected, actual string) {