You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-08-10 22:31:50 +02:00
Make SpanContext Immutable (#1573)
* Make SpanContext Immutable * Adds NewSpanContext() constructor and SpanContextConfig{} struct for constructing a new SpanContext when all fields are known * Adds With<field>() methods to SpanContext for deriving a SpanContext with a single field changed. * Updates all uses of SpanContext to use the new API Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com> * Update CHANGELOG.md Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com> * Add tests for new SpanContext constructor and derivation Signed-off-by: Anthony J Mirabella <a9@aneurysm9.com> * Address PR feedback * Fix new uses of SpanContext from main
This commit is contained in:
committed by
GitHub
parent
d75e268053
commit
e88a091a72
@@ -60,11 +60,11 @@ type outOfThinAirPropagator struct {
|
||||
var _ propagation.TextMapPropagator = outOfThinAirPropagator{}
|
||||
|
||||
func (p outOfThinAirPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
|
||||
sc := trace.SpanContext{
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: 0,
|
||||
}
|
||||
})
|
||||
require.True(p.t, sc.IsValid())
|
||||
return trace.ContextWithRemoteSpanContext(ctx, sc)
|
||||
}
|
||||
|
@@ -52,13 +52,13 @@ func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
|
||||
return
|
||||
}
|
||||
|
||||
carrier.Set(tracestateHeader, sc.TraceState.String())
|
||||
carrier.Set(tracestateHeader, sc.TraceState().String())
|
||||
|
||||
h := fmt.Sprintf("%.2x-%s-%s-%.2x",
|
||||
supportedVersion,
|
||||
sc.TraceID,
|
||||
sc.SpanID,
|
||||
sc.TraceFlags&trace.FlagsSampled)
|
||||
sc.TraceID(),
|
||||
sc.SpanID(),
|
||||
sc.TraceFlags()&trace.FlagsSampled)
|
||||
carrier.Set(traceparentHeader, h)
|
||||
}
|
||||
|
||||
@@ -107,9 +107,9 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
||||
var sc trace.SpanContext
|
||||
var scc trace.SpanContextConfig
|
||||
|
||||
sc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])
|
||||
scc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])
|
||||
if err != nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
|
||||
if len(matches[3]) != 16 {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
sc.SpanID, err = trace.SpanIDFromHex(matches[3])
|
||||
scc.SpanID, err = trace.SpanIDFromHex(matches[3])
|
||||
if err != nil {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
@@ -130,10 +130,11 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
// Clear all flags other than the trace-context supported sampling bit.
|
||||
sc.TraceFlags = opts[0] & trace.FlagsSampled
|
||||
scc.TraceFlags = opts[0] & trace.FlagsSampled
|
||||
|
||||
sc.TraceState = parseTraceState(carrier.Get(tracestateHeader))
|
||||
scc.TraceState = parseTraceState(carrier.Get(tracestateHeader))
|
||||
|
||||
sc := trace.NewSpanContext(scc)
|
||||
if !sc.IsValid() {
|
||||
return trace.SpanContext{}
|
||||
}
|
||||
|
@@ -43,11 +43,11 @@ func injectSubBenchmarks(b *testing.B, fn func(context.Context, *testing.B)) {
|
||||
|
||||
mockTracer := oteltest.DefaultTracer()
|
||||
b.ReportAllocs()
|
||||
sc := trace.SpanContext{
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc)
|
||||
ctx, _ = mockTracer.Start(ctx, "inject")
|
||||
fn(ctx, b)
|
||||
|
@@ -37,72 +37,72 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) {
|
||||
{
|
||||
name: "valid w3cHeader",
|
||||
header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "valid w3cHeader and sampled",
|
||||
header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "future version",
|
||||
header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "future options with sampled bit set",
|
||||
header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "future options with sampled bit cleared",
|
||||
header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-08",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "future additional data",
|
||||
header: "02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-XYZxsf09",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "valid b3Header ending in dash",
|
||||
header: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01-",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "future valid b3Header ending in dash",
|
||||
header: "01-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-",
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestExtractValidTraceContextFromHTTPReq(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx = prop.Extract(ctx, propagation.HeaderCarrier(req.Header))
|
||||
gotSc := trace.RemoteSpanContextFromContext(ctx)
|
||||
if diff := cmp.Diff(gotSc, tt.wantSc, cmp.AllowUnexported(trace.TraceState{})); diff != "" {
|
||||
if diff := cmp.Diff(gotSc, tt.wantSc, cmp.Comparer(func(sc, other trace.SpanContext) bool { return sc.Equal(other) })); diff != "" {
|
||||
t.Errorf("Extract Tracecontext: %s: -got +want %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
@@ -219,28 +219,28 @@ func TestInjectTraceContextToHTTPReq(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "valid spancontext, sampled",
|
||||
sc: trace.SpanContext{
|
||||
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
wantHeader: "00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000000002-01",
|
||||
},
|
||||
{
|
||||
name: "valid spancontext, not sampled",
|
||||
sc: trace.SpanContext{
|
||||
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
wantHeader: "00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000000003-00",
|
||||
},
|
||||
{
|
||||
name: "valid spancontext, with unsupported bit set in traceflags",
|
||||
sc: trace.SpanContext{
|
||||
sc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: 0xff,
|
||||
},
|
||||
}),
|
||||
wantHeader: "00-4bf92f3577b34da6a3ce929d0e0e4736-0000000000000004-01",
|
||||
},
|
||||
{
|
||||
@@ -298,11 +298,11 @@ func TestTraceStatePropagation(t *testing.T) {
|
||||
stateHeader: "key1=value1,key2=value2",
|
||||
},
|
||||
valid: true,
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceState: state,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "valid parent, invalid state",
|
||||
@@ -311,10 +311,10 @@ func TestTraceStatePropagation(t *testing.T) {
|
||||
stateHeader: "key1=value1,invalid$@#=invalid",
|
||||
},
|
||||
valid: false,
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "valid parent, malformed state",
|
||||
@@ -323,10 +323,10 @@ func TestTraceStatePropagation(t *testing.T) {
|
||||
stateHeader: "key1=value1,invalid",
|
||||
},
|
||||
valid: false,
|
||||
wantSc: trace.SpanContext{
|
||||
wantSc: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user