Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented logic for Opentracing baggage propagation #1880

Merged
75 changes: 67 additions & 8 deletions propagators/ot/ot_data_test.go
Expand Up @@ -15,6 +15,8 @@
package ot_test

import (
"strings"

"go.opentelemetry.io/otel/trace"
)

Expand All @@ -38,11 +40,13 @@ var (
traceID32 = trace.TraceID{0xa1, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36}
spanID = trace.SpanID{0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7}
emptyBaggage = map[string]string{}
// TODO: once baggage extraction is supported, re-enable this
// baggageSet = attribute.NewSet(
// attribute.String(baggageKey, baggageValue),
// attribute.String(baggageKey2, baggageValue2),
// )
baggageSet = map[string]string{
baggageKey: baggageValue,
}
baggageSet2 = map[string]string{
baggageKey: baggageValue,
baggageKey2: baggageValue2,
}
)

type extractTest struct {
Expand Down Expand Up @@ -85,9 +89,22 @@ var extractHeaders = []extractTest{
SpanID: spanID,
TraceFlags: trace.FlagsSampled,
},
emptyBaggage,
// TODO: once baggage extraction is supported, re-enable this
// &baggageSet,
baggageSet,
},
{
"baggage multiple values",
map[string]string{
traceIDHeader: traceID32Str,
spanIDHeader: spanIDStr,
sampledHeader: "0",
baggageHeader: baggageValue,
baggageHeader2: baggageValue2,
},
trace.SpanContextConfig{
TraceID: traceID32,
SpanID: spanID,
},
baggageSet2,
},
{
"left padding 64 bit trace ID",
Expand Down Expand Up @@ -168,6 +185,48 @@ var invalidExtractHeaders = []extractTest{
sampledHeader: "wired",
},
},
{
name: "invalid baggage key",
headers: map[string]string{
traceIDHeader: traceID32Str,
spanIDHeader: spanIDStr,
sampledHeader: "1",
"ot-baggage-d–76": "test",
},
expected: trace.SpanContextConfig{
TraceID: traceID32,
SpanID: spanID,
TraceFlags: trace.FlagsSampled,
},
},
{
name: "invalid baggage value",
headers: map[string]string{
traceIDHeader: traceID32Str,
spanIDHeader: spanIDStr,
sampledHeader: "1",
baggageHeader: "øtel",
},
expected: trace.SpanContextConfig{
TraceID: traceID32,
SpanID: spanID,
TraceFlags: trace.FlagsSampled,
},
},
{
name: "invalid baggage result (too large)",
headers: map[string]string{
traceIDHeader: traceID32Str,
spanIDHeader: spanIDStr,
sampledHeader: "1",
baggageHeader: strings.Repeat("s", 8188),
},
expected: trace.SpanContextConfig{
TraceID: traceID32,
SpanID: spanID,
TraceFlags: trace.FlagsSampled,
},
},
{
name: "missing headers",
headers: map[string]string{},
Expand Down
43 changes: 34 additions & 9 deletions propagators/ot/ot_propagator.go
Expand Up @@ -28,9 +28,10 @@ import (

const (
// Default OT Header names.
traceIDHeader = "ot-tracer-traceid"
spanIDHeader = "ot-tracer-spanid"
sampledHeader = "ot-tracer-sampled"
traceIDHeader = "ot-tracer-traceid"
spanIDHeader = "ot-tracer-spanid"
sampledHeader = "ot-tracer-sampled"
baggageHeaderPrefix = "ot-baggage-"

otTraceIDPadding = "0000000000000000"

Expand Down Expand Up @@ -72,7 +73,7 @@ func (o OT) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
}

for _, m := range baggage.FromContext(ctx).Members() {
carrier.Set(fmt.Sprintf("ot-baggage-%s", m.Key()), m.Value())
carrier.Set(fmt.Sprintf("%s%s", baggageHeaderPrefix, m.Key()), m.Value())
}

}
Expand All @@ -93,18 +94,42 @@ func (o OT) Extract(ctx context.Context, carrier propagation.TextMapCarrier) con
if err != nil || !sc.IsValid() {
return ctx
}
// TODO: implement extracting baggage
//
// this currently is not achievable without an implementation of `keys`
// on the carrier, see:
// https://github.com/open-telemetry/opentelemetry-go/issues/1493

bags, err := extractBags(carrier)
if err != nil {
return trace.ContextWithRemoteSpanContext(ctx, sc)
}
ctx = baggage.ContextWithBaggage(ctx, bags)
return trace.ContextWithRemoteSpanContext(ctx, sc)
}

func (o OT) Fields() []string {
return []string{traceIDHeader, spanIDHeader, sampledHeader}
}

// extractBags reconstructs the baggage information from opentracing
jaronoff97 marked this conversation as resolved.
Show resolved Hide resolved
func extractBags(carrier propagation.TextMapCarrier) (baggage.Baggage, error) {
emptyBags, _ := baggage.New()
var members []baggage.Member
for _, key := range carrier.Keys() {
lowerKey := strings.ToLower(key)
if !strings.HasPrefix(lowerKey, baggageHeaderPrefix) {
continue
}
strippedKey := strings.TrimPrefix(lowerKey, baggageHeaderPrefix)
member, err := baggage.NewMember(strippedKey, carrier.Get(key))
if err != nil {
return emptyBags, err
jaronoff97 marked this conversation as resolved.
Show resolved Hide resolved
}
members = append(members, member)
}
bags, err := baggage.New(members...)
if err != nil {
return emptyBags, err
}
return bags, nil
jaronoff97 marked this conversation as resolved.
Show resolved Hide resolved
}

// extract reconstructs a SpanContext from header values based on OT
// headers.
func extract(traceID, spanID, sampled string) (trace.SpanContext, error) {
Expand Down