mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-03-21 21:17:35 +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:
parent
d75e268053
commit
e88a091a72
CHANGELOG.md
bridge
exporters
otlp
stdout
trace
oteltest
propagation
sdk/trace
batch_span_processor_test.gobenchmark_test.gosampling.gosampling_test.gosimple_span_processor_test.gospan.gospan_processor_test.gotrace_test.go
trace
@ -8,12 +8,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## Added
|
||||
### Added
|
||||
|
||||
- Added `Marshler` config option to `otlphttp` to enable otlp over json or protobufs. (#1586)
|
||||
- A `ForceFlush` method to the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` to flush all registered `SpanProcessor`s. (#1608)
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- Update the `ForceFlush` method signature to the `"go.opentelemetry.io/otel/sdk/trace".SpanProcessor` to accept a `context.Context` and return an error. (#1608)
|
||||
@ -22,6 +21,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
- `"go.opentelemetry.io/sdk/metric/controller.basic".WithPusher` is replaced with `WithExporter` to provide consistent naming across project. (#1656)
|
||||
- Added non-empty string check for trace `Attribute` keys. (#1659)
|
||||
- Add `description` to SpanStatus only when `StatusCode` is set to error. (#1662)
|
||||
- `trace.SpanContext` is now immutable and has no exported fields. (#1573)
|
||||
- `trace.NewSpanContext()` can be used in conjunction with the `trace.SpanContextConfig` struct to initialize a new `SpanContext` where all values are known.
|
||||
|
||||
### Removed
|
||||
|
||||
@ -29,7 +30,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
These are now returned as a SpanProcessor interface from their respective constructors. (#1638)
|
||||
- Removed setting status to `Error` while recording an error as a span event in `RecordError`. (#1663)
|
||||
|
||||
|
||||
### Fixed
|
||||
|
||||
- `SamplingResult.TraceState` is correctly propagated to a newly created
|
||||
|
@ -186,5 +186,5 @@ func (s *span) AddLink(l octrace.Link) {
|
||||
}
|
||||
|
||||
func (s *span) String() string {
|
||||
return fmt.Sprintf("span %s", s.otSpan.SpanContext().SpanID.String())
|
||||
return fmt.Sprintf("span %s", s.otSpan.SpanContext().SpanID().String())
|
||||
}
|
||||
|
@ -66,8 +66,8 @@ func TestMixedAPIs(t *testing.T) {
|
||||
// Reverse the order we look at the spans in, since they are listed in last-to-first order.
|
||||
i = len(spans) - i - 1
|
||||
// Verify that OpenCensus spans and opentelemetry spans have each other as parents.
|
||||
if spans[i].ParentSpanID() != parent.SpanContext().SpanID {
|
||||
t.Errorf("Span %v had parent %v. Expected %d", spans[i].Name(), spans[i].ParentSpanID(), parent.SpanContext().SpanID)
|
||||
if spans[i].ParentSpanID() != parent.SpanContext().SpanID() {
|
||||
t.Errorf("Span %v had parent %v. Expected %d", spans[i].Name(), spans[i].ParentSpanID(), parent.SpanContext().SpanID())
|
||||
}
|
||||
parent = spans[i]
|
||||
}
|
||||
@ -111,8 +111,8 @@ func TestStartSpanWithRemoteParent(t *testing.T) {
|
||||
t.Fatalf("Got %d spans, exepected %d", len(spans), 1)
|
||||
}
|
||||
|
||||
if spans[0].ParentSpanID() != parent.SpanContext().SpanID {
|
||||
t.Errorf("Span %v, had parent %v. Expected %d", spans[0].Name(), spans[0].ParentSpanID(), parent.SpanContext().SpanID)
|
||||
if spans[0].ParentSpanID() != parent.SpanContext().SpanID() {
|
||||
t.Errorf("Span %v, had parent %v. Expected %d", spans[0].Name(), spans[0].ParentSpanID(), parent.SpanContext().SpanID())
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,8 +150,8 @@ func TestToFromContext(t *testing.T) {
|
||||
// Reverse the order we look at the spans in, since they are listed in last-to-first order.
|
||||
i = len(spans) - i - 1
|
||||
// Verify that OpenCensus spans and opentelemetry spans have each other as parents.
|
||||
if spans[i].ParentSpanID() != parent.SpanContext().SpanID {
|
||||
t.Errorf("Span %v had parent %v. Expected %d", spans[i].Name(), spans[i].ParentSpanID(), parent.SpanContext().SpanID)
|
||||
if spans[i].ParentSpanID() != parent.SpanContext().SpanID() {
|
||||
t.Errorf("Span %v had parent %v. Expected %d", spans[i].Name(), spans[i].ParentSpanID(), parent.SpanContext().SpanID())
|
||||
}
|
||||
parent = spans[i]
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
// error handler.
|
||||
func OTelSpanContextToOC(sc trace.SpanContext) octrace.SpanContext {
|
||||
if sc.IsDebug() || sc.IsDeferred() {
|
||||
otel.Handle(fmt.Errorf("ignoring OpenTelemetry Debug or Deferred trace flags for span %q because they are not supported by OpenCensus", sc.SpanID))
|
||||
otel.Handle(fmt.Errorf("ignoring OpenTelemetry Debug or Deferred trace flags for span %q because they are not supported by OpenCensus", sc.SpanID()))
|
||||
}
|
||||
var to octrace.TraceOptions
|
||||
if sc.IsSampled() {
|
||||
@ -36,8 +36,8 @@ func OTelSpanContextToOC(sc trace.SpanContext) octrace.SpanContext {
|
||||
to = 0x1
|
||||
}
|
||||
return octrace.SpanContext{
|
||||
TraceID: octrace.TraceID(sc.TraceID),
|
||||
SpanID: octrace.SpanID(sc.SpanID),
|
||||
TraceID: octrace.TraceID(sc.TraceID()),
|
||||
SpanID: octrace.SpanID(sc.SpanID()),
|
||||
TraceOptions: to,
|
||||
}
|
||||
}
|
||||
@ -49,9 +49,9 @@ func OCSpanContextToOTel(sc octrace.SpanContext) trace.SpanContext {
|
||||
if sc.IsSampled() {
|
||||
traceFlags = trace.FlagsSampled
|
||||
}
|
||||
return trace.SpanContext{
|
||||
return trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID(sc.TraceID),
|
||||
SpanID: trace.SpanID(sc.SpanID),
|
||||
TraceFlags: traceFlags,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -35,11 +35,11 @@ func TestOTelSpanContextToOC(t *testing.T) {
|
||||
},
|
||||
{
|
||||
description: "sampled",
|
||||
input: trace.SpanContext{
|
||||
input: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
expected: octrace.SpanContext{
|
||||
TraceID: octrace.TraceID([16]byte{1}),
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
@ -48,10 +48,10 @@ func TestOTelSpanContextToOC(t *testing.T) {
|
||||
},
|
||||
{
|
||||
description: "not sampled",
|
||||
input: trace.SpanContext{
|
||||
input: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
},
|
||||
}),
|
||||
expected: octrace.SpanContext{
|
||||
TraceID: octrace.TraceID([16]byte{1}),
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
@ -60,11 +60,11 @@ func TestOTelSpanContextToOC(t *testing.T) {
|
||||
},
|
||||
{
|
||||
description: "debug flag",
|
||||
input: trace.SpanContext{
|
||||
input: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
TraceFlags: trace.FlagsDebug,
|
||||
},
|
||||
}),
|
||||
expected: octrace.SpanContext{
|
||||
TraceID: octrace.TraceID([16]byte{1}),
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
@ -97,11 +97,11 @@ func TestOCSpanContextToOTel(t *testing.T) {
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
TraceOptions: octrace.TraceOptions(0x1),
|
||||
},
|
||||
expected: trace.SpanContext{
|
||||
expected: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: "not sampled",
|
||||
@ -110,10 +110,10 @@ func TestOCSpanContextToOTel(t *testing.T) {
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
TraceOptions: octrace.TraceOptions(0),
|
||||
},
|
||||
expected: trace.SpanContext{
|
||||
expected: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: "trace state is ignored",
|
||||
@ -122,17 +122,15 @@ func TestOCSpanContextToOTel(t *testing.T) {
|
||||
SpanID: octrace.SpanID([8]byte{2}),
|
||||
Tracestate: &tracestate.Tracestate{},
|
||||
},
|
||||
expected: trace.SpanContext{
|
||||
expected: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{1}),
|
||||
SpanID: trace.SpanID([8]byte{2}),
|
||||
},
|
||||
}),
|
||||
},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
output := OCSpanContextToOTel(tc.input)
|
||||
if output.SpanID != tc.expected.SpanID ||
|
||||
output.TraceID != tc.expected.TraceID ||
|
||||
output.TraceFlags != tc.expected.TraceFlags {
|
||||
if !output.Equal(tc.expected) {
|
||||
t.Fatalf("Got %+v spancontext, exepected %+v.", output, tc.expected)
|
||||
}
|
||||
})
|
||||
|
@ -76,11 +76,11 @@ func (t *MockTracer) Start(ctx context.Context, name string, opts ...trace.SpanO
|
||||
if startTime.IsZero() {
|
||||
startTime = time.Now()
|
||||
}
|
||||
spanContext := trace.SpanContext{
|
||||
spanContext := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: t.getTraceID(ctx, config),
|
||||
SpanID: t.getSpanID(),
|
||||
TraceFlags: 0,
|
||||
}
|
||||
})
|
||||
span := &MockSpan{
|
||||
mockTracer: t,
|
||||
officialTracer: t,
|
||||
@ -117,7 +117,7 @@ func (t *MockTracer) addSpareContextValue(ctx context.Context) context.Context {
|
||||
|
||||
func (t *MockTracer) getTraceID(ctx context.Context, config *trace.SpanConfig) trace.TraceID {
|
||||
if parent := t.getParentSpanContext(ctx, config); parent.IsValid() {
|
||||
return parent.TraceID
|
||||
return parent.TraceID()
|
||||
}
|
||||
if len(t.SpareTraceIDs) > 0 {
|
||||
traceID := t.SpareTraceIDs[0]
|
||||
@ -132,7 +132,7 @@ func (t *MockTracer) getTraceID(ctx context.Context, config *trace.SpanConfig) t
|
||||
|
||||
func (t *MockTracer) getParentSpanID(ctx context.Context, config *trace.SpanConfig) trace.SpanID {
|
||||
if parent := t.getParentSpanContext(ctx, config); parent.IsValid() {
|
||||
return parent.SpanID
|
||||
return parent.SpanID()
|
||||
}
|
||||
return trace.SpanID{}
|
||||
}
|
||||
|
@ -229,12 +229,12 @@ func (cast *currentActiveSpanTest) runOTOtelOT(t *testing.T, ctx context.Context
|
||||
}
|
||||
|
||||
func (cast *currentActiveSpanTest) recordSpans(t *testing.T, ctx context.Context) context.Context {
|
||||
spanID := trace.SpanContextFromContext(ctx).SpanID
|
||||
spanID := trace.SpanContextFromContext(ctx).SpanID()
|
||||
cast.recordedCurrentOtelSpanIDs = append(cast.recordedCurrentOtelSpanIDs, spanID)
|
||||
|
||||
spanID = trace.SpanID{}
|
||||
if bridgeSpan, ok := ot.SpanFromContext(ctx).(*bridgeSpan); ok {
|
||||
spanID = bridgeSpan.otelSpan.SpanContext().SpanID
|
||||
spanID = bridgeSpan.otelSpan.SpanContext().SpanID()
|
||||
}
|
||||
cast.recordedActiveOTSpanIDs = append(cast.recordedActiveOTSpanIDs, spanID)
|
||||
return ctx
|
||||
@ -637,19 +637,19 @@ func checkTraceAndSpans(t *testing.T, tracer *internal.MockTracer, expectedTrace
|
||||
}
|
||||
for idx, span := range tracer.FinishedSpans {
|
||||
sctx := span.SpanContext()
|
||||
if sctx.TraceID != expectedTraceID {
|
||||
t.Errorf("Expected trace ID %v in span %d (%d), got %v", expectedTraceID, idx, sctx.SpanID, sctx.TraceID)
|
||||
if sctx.TraceID() != expectedTraceID {
|
||||
t.Errorf("Expected trace ID %v in span %d (%d), got %v", expectedTraceID, idx, sctx.SpanID(), sctx.TraceID())
|
||||
}
|
||||
expectedSpanID := spanIDs[idx]
|
||||
expectedParentSpanID := parentSpanIDs[idx]
|
||||
if sctx.SpanID != expectedSpanID {
|
||||
t.Errorf("Expected finished span %d to have span ID %d, but got %d", idx, expectedSpanID, sctx.SpanID)
|
||||
if sctx.SpanID() != expectedSpanID {
|
||||
t.Errorf("Expected finished span %d to have span ID %d, but got %d", idx, expectedSpanID, sctx.SpanID())
|
||||
}
|
||||
if span.ParentSpanID != expectedParentSpanID {
|
||||
t.Errorf("Expected finished span %d (span ID: %d) to have parent span ID %d, but got %d", idx, sctx.SpanID, expectedParentSpanID, span.ParentSpanID)
|
||||
t.Errorf("Expected finished span %d (span ID: %d) to have parent span ID %d, but got %d", idx, sctx.SpanID(), expectedParentSpanID, span.ParentSpanID)
|
||||
}
|
||||
if span.SpanKind != sks[span.SpanContext().SpanID] {
|
||||
t.Errorf("Expected finished span %d (span ID: %d) to have span.kind to be '%v' but was '%v'", idx, sctx.SpanID, sks[span.SpanContext().SpanID], span.SpanKind)
|
||||
if span.SpanKind != sks[span.SpanContext().SpanID()] {
|
||||
t.Errorf("Expected finished span %d (span ID: %d) to have span.kind to be '%v' but was '%v'", idx, sctx.SpanID(), sks[span.SpanContext().SpanID()], span.SpanKind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,11 +82,11 @@ func (OneRecordCheckpointSet) ForEach(kindSelector exportmetric.ExportKindSelect
|
||||
// may be useful for testing driver's trace export.
|
||||
func SingleSpanSnapshot() []*exporttrace.SpanSnapshot {
|
||||
sd := &exporttrace.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
SpanID: trace.SpanID{3, 4, 5, 6, 7, 8, 9, 0},
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
Name: "foo",
|
||||
|
@ -101,10 +101,13 @@ func span(sd *export.SpanSnapshot) *tracepb.Span {
|
||||
return nil
|
||||
}
|
||||
|
||||
tid := sd.SpanContext.TraceID()
|
||||
sid := sd.SpanContext.SpanID()
|
||||
|
||||
s := &tracepb.Span{
|
||||
TraceId: sd.SpanContext.TraceID[:],
|
||||
SpanId: sd.SpanContext.SpanID[:],
|
||||
TraceState: sd.SpanContext.TraceState.String(),
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
TraceState: sd.SpanContext.TraceState().String(),
|
||||
Status: status(sd.StatusCode, sd.StatusMessage),
|
||||
StartTimeUnixNano: uint64(sd.StartTime.UnixNano()),
|
||||
EndTimeUnixNano: uint64(sd.EndTime.UnixNano()),
|
||||
@ -152,9 +155,12 @@ func links(links []trace.Link) []*tracepb.Span_Link {
|
||||
// being reused -- in short we need a new otLink per iteration.
|
||||
otLink := otLink
|
||||
|
||||
tid := otLink.TraceID()
|
||||
sid := otLink.SpanID()
|
||||
|
||||
sl = append(sl, &tracepb.Span_Link{
|
||||
TraceId: otLink.TraceID[:],
|
||||
SpanId: otLink.SpanID[:],
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
Attributes: Attributes(otLink.Attributes),
|
||||
})
|
||||
}
|
||||
|
@ -148,8 +148,7 @@ func TestLinks(t *testing.T) {
|
||||
assert.Equal(t, expected, got[1])
|
||||
|
||||
// Changes to our links should not change the produced links.
|
||||
l[1].TraceID[0] = byte(0x1)
|
||||
l[1].SpanID[0] = byte(0x1)
|
||||
l[1].SpanContext = l[1].WithTraceID(trace.TraceID{})
|
||||
assert.Equal(t, expected, got[1])
|
||||
}
|
||||
|
||||
@ -201,11 +200,11 @@ func TestSpanData(t *testing.T) {
|
||||
endTime := startTime.Add(10 * time.Second)
|
||||
traceState, _ := trace.TraceStateFromKeyValues(attribute.String("key1", "val1"), attribute.String("key2", "val2"))
|
||||
spanData := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
TraceState: traceState,
|
||||
},
|
||||
}),
|
||||
SpanKind: trace.SpanKindServer,
|
||||
ParentSpanID: trace.SpanID{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8},
|
||||
Name: "span data to span data",
|
||||
@ -225,21 +224,21 @@ func TestSpanData(t *testing.T) {
|
||||
},
|
||||
Links: []trace.Link{
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF},
|
||||
SpanID: trace.SpanID{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
|
||||
TraceFlags: 0,
|
||||
},
|
||||
}),
|
||||
Attributes: []attribute.KeyValue{
|
||||
attribute.String("LinkType", "Parent"),
|
||||
},
|
||||
},
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF},
|
||||
SpanID: trace.SpanID{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7},
|
||||
TraceFlags: 0,
|
||||
},
|
||||
}),
|
||||
Attributes: []attribute.KeyValue{
|
||||
attribute.String("LinkType", "Child"),
|
||||
},
|
||||
|
@ -55,11 +55,11 @@ func TestExportSpans(t *testing.T) {
|
||||
{
|
||||
[]*tracesdk.SpanSnapshot{
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
SpanID: trace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
TraceFlags: byte(1),
|
||||
},
|
||||
}),
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "parent process",
|
||||
StartTime: startTime,
|
||||
@ -77,11 +77,11 @@ func TestExportSpans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}),
|
||||
SpanID: trace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
TraceFlags: byte(1),
|
||||
},
|
||||
}),
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "secondary parent process",
|
||||
StartTime: startTime,
|
||||
@ -99,11 +99,11 @@ func TestExportSpans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
SpanID: trace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 2}),
|
||||
TraceFlags: byte(1),
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
Name: "internal process",
|
||||
@ -122,11 +122,11 @@ func TestExportSpans(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}),
|
||||
SpanID: trace.SpanID([8]byte{0, 0, 0, 0, 0, 0, 0, 1}),
|
||||
TraceFlags: byte(1),
|
||||
},
|
||||
}),
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "parent process",
|
||||
StartTime: startTime,
|
||||
|
@ -48,11 +48,11 @@ func TestExporter_ExportSpan(t *testing.T) {
|
||||
resource := resource.NewWithAttributes(attribute.String("rk1", "rv11"))
|
||||
|
||||
testSpan := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceState: traceState,
|
||||
},
|
||||
}),
|
||||
Name: "/foo",
|
||||
StartTime: now,
|
||||
EndTime: now,
|
||||
|
@ -328,21 +328,25 @@ func spanSnapshotToThrift(ss *export.SpanSnapshot) *gen.Span {
|
||||
|
||||
var refs []*gen.SpanRef
|
||||
for _, link := range ss.Links {
|
||||
tid := link.TraceID()
|
||||
sid := link.SpanID()
|
||||
refs = append(refs, &gen.SpanRef{
|
||||
TraceIdHigh: int64(binary.BigEndian.Uint64(link.TraceID[0:8])),
|
||||
TraceIdLow: int64(binary.BigEndian.Uint64(link.TraceID[8:16])),
|
||||
SpanId: int64(binary.BigEndian.Uint64(link.SpanID[:])),
|
||||
TraceIdHigh: int64(binary.BigEndian.Uint64(tid[0:8])),
|
||||
TraceIdLow: int64(binary.BigEndian.Uint64(tid[8:16])),
|
||||
SpanId: int64(binary.BigEndian.Uint64(sid[:])),
|
||||
RefType: gen.SpanRefType_FOLLOWS_FROM,
|
||||
})
|
||||
}
|
||||
|
||||
tid := ss.SpanContext.TraceID()
|
||||
sid := ss.SpanContext.SpanID()
|
||||
return &gen.Span{
|
||||
TraceIdHigh: int64(binary.BigEndian.Uint64(ss.SpanContext.TraceID[0:8])),
|
||||
TraceIdLow: int64(binary.BigEndian.Uint64(ss.SpanContext.TraceID[8:16])),
|
||||
SpanId: int64(binary.BigEndian.Uint64(ss.SpanContext.SpanID[:])),
|
||||
TraceIdHigh: int64(binary.BigEndian.Uint64(tid[0:8])),
|
||||
TraceIdLow: int64(binary.BigEndian.Uint64(tid[8:16])),
|
||||
SpanId: int64(binary.BigEndian.Uint64(sid[:])),
|
||||
ParentSpanId: int64(binary.BigEndian.Uint64(ss.ParentSpanID[:])),
|
||||
OperationName: ss.Name, // TODO: if span kind is added then add prefix "Sent"/"Recv"
|
||||
Flags: int32(ss.SpanContext.TraceFlags),
|
||||
Flags: int32(ss.SpanContext.TraceFlags()),
|
||||
StartTime: ss.StartTime.UnixNano() / 1000,
|
||||
Duration: ss.EndTime.Sub(ss.StartTime).Nanoseconds() / 1000,
|
||||
Tags: tags,
|
||||
|
@ -383,19 +383,19 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
||||
{
|
||||
name: "no parent",
|
||||
data: &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
Name: "/foo",
|
||||
StartTime: now,
|
||||
EndTime: now,
|
||||
Links: []trace.Link{
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: linkTraceID,
|
||||
SpanID: linkSpanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -466,16 +466,16 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
||||
name: "with parent",
|
||||
data: &export.SpanSnapshot{
|
||||
ParentSpanID: parentSpanID,
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
},
|
||||
}),
|
||||
Links: []trace.Link{
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: linkTraceID,
|
||||
SpanID: linkSpanID,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Name: "/foo",
|
||||
|
@ -58,8 +58,8 @@ func toZipkinSpanModel(data *export.SpanSnapshot, serviceName string) zkmodel.Sp
|
||||
|
||||
func toZipkinSpanContext(data *export.SpanSnapshot) zkmodel.SpanContext {
|
||||
return zkmodel.SpanContext{
|
||||
TraceID: toZipkinTraceID(data.SpanContext.TraceID),
|
||||
ID: toZipkinID(data.SpanContext.SpanID),
|
||||
TraceID: toZipkinTraceID(data.SpanContext.TraceID()),
|
||||
ID: toZipkinID(data.SpanContext.SpanID()),
|
||||
ParentID: toZipkinParentID(data.ParentSpanID),
|
||||
Debug: false,
|
||||
Sampled: nil,
|
||||
|
@ -35,10 +35,10 @@ func TestModelConversion(t *testing.T) {
|
||||
inputBatch := []*export.SpanSnapshot{
|
||||
// typical span data
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "foo",
|
||||
@ -68,10 +68,10 @@ func TestModelConversion(t *testing.T) {
|
||||
// span data with no parent (same as typical, but has
|
||||
// invalid parent)
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "foo",
|
||||
@ -100,10 +100,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data of unspecified kind
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindUnspecified,
|
||||
Name: "foo",
|
||||
@ -132,10 +132,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data of internal kind
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
Name: "foo",
|
||||
@ -164,10 +164,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data of client kind
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindClient,
|
||||
Name: "foo",
|
||||
@ -196,10 +196,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data of producer kind
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindProducer,
|
||||
Name: "foo",
|
||||
@ -228,10 +228,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data of consumer kind
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindConsumer,
|
||||
Name: "foo",
|
||||
@ -260,10 +260,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data with no events
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "foo",
|
||||
@ -279,10 +279,10 @@ func TestModelConversion(t *testing.T) {
|
||||
},
|
||||
// span data with an "error" attribute set to "false"
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "foo",
|
||||
|
@ -242,10 +242,10 @@ func TestExportSpans(t *testing.T) {
|
||||
spans := []*export.SpanSnapshot{
|
||||
// parent
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "foo",
|
||||
@ -258,10 +258,10 @@ func TestExportSpans(t *testing.T) {
|
||||
},
|
||||
// child
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
|
||||
SpanID: trace.SpanID{0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8},
|
||||
},
|
||||
}),
|
||||
ParentSpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
|
||||
SpanKind: trace.SpanKindServer,
|
||||
Name: "bar",
|
||||
|
@ -33,10 +33,13 @@ func defaultSpanContextFunc() func(context.Context) trace.SpanContext {
|
||||
} else if rsc := trace.RemoteSpanContextFromContext(ctx); rsc.IsValid() {
|
||||
sc = rsc
|
||||
} else {
|
||||
binary.BigEndian.PutUint64(sc.TraceID[:], atomic.AddUint64(&traceID, 1))
|
||||
var tid trace.TraceID
|
||||
binary.BigEndian.PutUint64(tid[:], atomic.AddUint64(&traceID, 1))
|
||||
sc = sc.WithTraceID(tid)
|
||||
}
|
||||
binary.BigEndian.PutUint64(sc.SpanID[:], atomic.AddUint64(&spanID, 1))
|
||||
return sc
|
||||
var sid trace.SpanID
|
||||
binary.BigEndian.PutUint64(sid[:], atomic.AddUint64(&spanID, 1))
|
||||
return sc.WithSpanID(sid)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) {
|
||||
sc1 := span1.SpanContext()
|
||||
sc2 := span2.SpanContext()
|
||||
|
||||
e.Expect(sc1.TraceID).NotToEqual(sc2.TraceID)
|
||||
e.Expect(sc1.SpanID).NotToEqual(sc2.SpanID)
|
||||
e.Expect(sc1.TraceID()).NotToEqual(sc2.TraceID())
|
||||
e.Expect(sc1.SpanID()).NotToEqual(sc2.SpanID())
|
||||
})
|
||||
|
||||
t.Run("records the span if specified", func(t *testing.T) {
|
||||
@ -175,8 +175,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) {
|
||||
psc := parent.SpanContext()
|
||||
csc := child.SpanContext()
|
||||
|
||||
e.Expect(csc.TraceID).ToEqual(psc.TraceID)
|
||||
e.Expect(csc.SpanID).NotToEqual(psc.SpanID)
|
||||
e.Expect(csc.TraceID()).ToEqual(psc.TraceID())
|
||||
e.Expect(csc.SpanID()).NotToEqual(psc.SpanID())
|
||||
})
|
||||
|
||||
t.Run("ignores parent's trace ID when new root is requested", func(t *testing.T) {
|
||||
@ -191,8 +191,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) {
|
||||
psc := parent.SpanContext()
|
||||
csc := child.SpanContext()
|
||||
|
||||
e.Expect(csc.TraceID).NotToEqual(psc.TraceID)
|
||||
e.Expect(csc.SpanID).NotToEqual(psc.SpanID)
|
||||
e.Expect(csc.TraceID()).NotToEqual(psc.TraceID())
|
||||
e.Expect(csc.SpanID()).NotToEqual(psc.SpanID())
|
||||
})
|
||||
|
||||
t.Run("propagates remote parent's trace ID through the context", func(t *testing.T) {
|
||||
@ -208,8 +208,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) {
|
||||
psc := remoteParent.SpanContext()
|
||||
csc := child.SpanContext()
|
||||
|
||||
e.Expect(csc.TraceID).ToEqual(psc.TraceID)
|
||||
e.Expect(csc.SpanID).NotToEqual(psc.SpanID)
|
||||
e.Expect(csc.TraceID()).ToEqual(psc.TraceID())
|
||||
e.Expect(csc.SpanID()).NotToEqual(psc.SpanID())
|
||||
})
|
||||
|
||||
t.Run("ignores remote parent's trace ID when new root is requested", func(t *testing.T) {
|
||||
@ -225,8 +225,8 @@ func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) {
|
||||
psc := remoteParent.SpanContext()
|
||||
csc := child.SpanContext()
|
||||
|
||||
e.Expect(csc.TraceID).NotToEqual(psc.TraceID)
|
||||
e.Expect(csc.SpanID).NotToEqual(psc.SpanID)
|
||||
e.Expect(csc.TraceID()).NotToEqual(psc.TraceID())
|
||||
e.Expect(csc.SpanID()).NotToEqual(psc.SpanID())
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -70,20 +70,20 @@ func (t *Tracer) Start(ctx context.Context, name string, opts ...trace.SpanOptio
|
||||
} else {
|
||||
span.spanContext = t.config.SpanContextFunc(ctx)
|
||||
if lsc := trace.SpanContextFromContext(ctx); lsc.IsValid() {
|
||||
span.spanContext.TraceID = lsc.TraceID
|
||||
span.parentSpanID = lsc.SpanID
|
||||
span.spanContext = span.spanContext.WithTraceID(lsc.TraceID())
|
||||
span.parentSpanID = lsc.SpanID()
|
||||
} else if rsc := trace.RemoteSpanContextFromContext(ctx); rsc.IsValid() {
|
||||
span.spanContext.TraceID = rsc.TraceID
|
||||
span.parentSpanID = rsc.SpanID
|
||||
span.spanContext = span.spanContext.WithTraceID(rsc.TraceID())
|
||||
span.parentSpanID = rsc.SpanID()
|
||||
}
|
||||
}
|
||||
|
||||
for _, link := range c.Links {
|
||||
for i, sl := range span.links {
|
||||
if sl.SpanContext.SpanID == link.SpanContext.SpanID &&
|
||||
sl.SpanContext.TraceID == link.SpanContext.TraceID &&
|
||||
sl.SpanContext.TraceFlags == link.SpanContext.TraceFlags &&
|
||||
sl.SpanContext.TraceState.String() == link.SpanContext.TraceState.String() {
|
||||
if sl.SpanContext.SpanID() == link.SpanContext.SpanID() &&
|
||||
sl.SpanContext.TraceID() == link.SpanContext.TraceID() &&
|
||||
sl.SpanContext.TraceFlags() == link.SpanContext.TraceFlags() &&
|
||||
sl.SpanContext.TraceState().String() == link.SpanContext.TraceState().String() {
|
||||
span.links[i].Attributes = link.Attributes
|
||||
break
|
||||
}
|
||||
|
@ -97,9 +97,9 @@ func TestTracer(t *testing.T) {
|
||||
e.Expect(ok).ToBeTrue()
|
||||
|
||||
childSpanContext := testSpan.SpanContext()
|
||||
e.Expect(childSpanContext.TraceID).ToEqual(parentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.TraceID()).ToEqual(parentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID())
|
||||
})
|
||||
|
||||
t.Run("uses the current span from context as parent, even if it has remote span context", func(t *testing.T) {
|
||||
@ -120,9 +120,9 @@ func TestTracer(t *testing.T) {
|
||||
e.Expect(ok).ToBeTrue()
|
||||
|
||||
childSpanContext := testSpan.SpanContext()
|
||||
e.Expect(childSpanContext.TraceID).ToEqual(parentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.TraceID()).ToEqual(parentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID())
|
||||
})
|
||||
|
||||
t.Run("uses the remote span context from context as parent, if current span is missing", func(t *testing.T) {
|
||||
@ -142,9 +142,9 @@ func TestTracer(t *testing.T) {
|
||||
e.Expect(ok).ToBeTrue()
|
||||
|
||||
childSpanContext := testSpan.SpanContext()
|
||||
e.Expect(childSpanContext.TraceID).ToEqual(remoteParentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(remoteParentSpanContext.SpanID)
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(remoteParentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.TraceID()).ToEqual(remoteParentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(remoteParentSpanContext.SpanID())
|
||||
e.Expect(testSpan.ParentSpanID()).ToEqual(remoteParentSpanContext.SpanID())
|
||||
})
|
||||
|
||||
t.Run("creates new root when both current span and remote span context are missing", func(t *testing.T) {
|
||||
@ -165,10 +165,10 @@ func TestTracer(t *testing.T) {
|
||||
e.Expect(ok).ToBeTrue()
|
||||
|
||||
childSpanContext := testSpan.SpanContext()
|
||||
e.Expect(childSpanContext.TraceID).NotToEqual(parentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.TraceID).NotToEqual(remoteParentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(remoteParentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.TraceID()).NotToEqual(parentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.TraceID()).NotToEqual(remoteParentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(remoteParentSpanContext.SpanID())
|
||||
e.Expect(testSpan.ParentSpanID().IsValid()).ToBeFalse()
|
||||
})
|
||||
|
||||
@ -191,10 +191,10 @@ func TestTracer(t *testing.T) {
|
||||
e.Expect(ok).ToBeTrue()
|
||||
|
||||
childSpanContext := testSpan.SpanContext()
|
||||
e.Expect(childSpanContext.TraceID).NotToEqual(parentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.TraceID).NotToEqual(remoteParentSpanContext.TraceID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(parentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.SpanID).NotToEqual(remoteParentSpanContext.SpanID)
|
||||
e.Expect(childSpanContext.TraceID()).NotToEqual(parentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.TraceID()).NotToEqual(remoteParentSpanContext.TraceID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
|
||||
e.Expect(childSpanContext.SpanID()).NotToEqual(remoteParentSpanContext.SpanID())
|
||||
e.Expect(testSpan.ParentSpanID().IsValid()).ToBeFalse()
|
||||
|
||||
expectedLinks := []trace.Link{
|
||||
|
@ -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,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,10 @@ func generateSpan(t *testing.T, parallel bool, tr trace.Tracer, option testOptio
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
for i := 0; i < option.genNumSpans; i++ {
|
||||
binary.BigEndian.PutUint64(sc.TraceID[0:8], uint64(i+1))
|
||||
tid := sc.TraceID()
|
||||
binary.BigEndian.PutUint64(tid[0:8], uint64(i+1))
|
||||
newSc := sc.WithTraceID(tid)
|
||||
|
||||
wg.Add(1)
|
||||
f := func(sc trace.SpanContext) {
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc)
|
||||
@ -219,9 +222,9 @@ func generateSpan(t *testing.T, parallel bool, tr trace.Tracer, option testOptio
|
||||
wg.Done()
|
||||
}
|
||||
if parallel {
|
||||
go f(sc)
|
||||
go f(newSc)
|
||||
} else {
|
||||
f(sc)
|
||||
f(newSc)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
@ -230,11 +233,11 @@ func generateSpan(t *testing.T, parallel bool, tr trace.Tracer, option testOptio
|
||||
func getSpanContext() trace.SpanContext {
|
||||
tid, _ := trace.TraceIDFromHex("01020304050607080102040810203040")
|
||||
sid, _ := trace.SpanIDFromHex("0102040810203040")
|
||||
return trace.SpanContext{
|
||||
return trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestBatchSpanProcessorShutdown(t *testing.T) {
|
||||
|
@ -117,21 +117,21 @@ func BenchmarkSpanWithAttributes_all_2x(b *testing.B) {
|
||||
|
||||
func BenchmarkTraceID_DotString(b *testing.B) {
|
||||
t, _ := trace.TraceIDFromHex("0000000000000001000000000000002a")
|
||||
sc := trace.SpanContext{TraceID: t}
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{TraceID: t})
|
||||
|
||||
want := "0000000000000001000000000000002a"
|
||||
for i := 0; i < b.N; i++ {
|
||||
if got := sc.TraceID.String(); got != want {
|
||||
if got := sc.TraceID().String(); got != want {
|
||||
b.Fatalf("got = %q want = %q", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSpanID_DotString(b *testing.B) {
|
||||
sc := trace.SpanContext{SpanID: trace.SpanID{1}}
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{SpanID: trace.SpanID{1}})
|
||||
want := "0100000000000000"
|
||||
for i := 0; i < b.N; i++ {
|
||||
if got := sc.SpanID.String(); got != want {
|
||||
if got := sc.SpanID().String(); got != want {
|
||||
b.Fatalf("got = %q want = %q", got, want)
|
||||
}
|
||||
}
|
||||
|
@ -73,12 +73,12 @@ func (ts traceIDRatioSampler) ShouldSample(p SamplingParameters) SamplingResult
|
||||
if x < ts.traceIDUpperBound {
|
||||
return SamplingResult{
|
||||
Decision: RecordAndSample,
|
||||
Tracestate: p.ParentContext.TraceState,
|
||||
Tracestate: p.ParentContext.TraceState(),
|
||||
}
|
||||
}
|
||||
return SamplingResult{
|
||||
Decision: Drop,
|
||||
Tracestate: p.ParentContext.TraceState,
|
||||
Tracestate: p.ParentContext.TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ type alwaysOnSampler struct{}
|
||||
func (as alwaysOnSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
return SamplingResult{
|
||||
Decision: RecordAndSample,
|
||||
Tracestate: p.ParentContext.TraceState,
|
||||
Tracestate: p.ParentContext.TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ type alwaysOffSampler struct{}
|
||||
func (as alwaysOffSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
return SamplingResult{
|
||||
Decision: Drop,
|
||||
Tracestate: p.ParentContext.TraceState,
|
||||
Tracestate: p.ParentContext.TraceState(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,11 @@ func TestParentBasedDefaultLocalParentSampled(t *testing.T) {
|
||||
sampler := ParentBased(AlwaysSample())
|
||||
traceID, _ := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
|
||||
spanID, _ := trace.SpanIDFromHex("00f067aa0ba902b7")
|
||||
parentCtx := trace.SpanContext{
|
||||
parentCtx := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
}
|
||||
})
|
||||
if sampler.ShouldSample(SamplingParameters{ParentContext: parentCtx}).Decision != RecordAndSample {
|
||||
t.Error("Sampling decision should be RecordAndSample")
|
||||
}
|
||||
@ -44,10 +44,10 @@ func TestParentBasedDefaultLocalParentNotSampled(t *testing.T) {
|
||||
sampler := ParentBased(AlwaysSample())
|
||||
traceID, _ := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
|
||||
spanID, _ := trace.SpanIDFromHex("00f067aa0ba902b7")
|
||||
parentCtx := trace.SpanContext{
|
||||
parentCtx := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
}
|
||||
})
|
||||
if sampler.ShouldSample(SamplingParameters{ParentContext: parentCtx}).Decision != Drop {
|
||||
t.Error("Sampling decision should be Drop")
|
||||
}
|
||||
@ -108,13 +108,13 @@ func TestParentBasedWithSamplerOptions(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
traceID, _ := trace.TraceIDFromHex("4bf92f3577b34da6a3ce929d0e0e4736")
|
||||
spanID, _ := trace.SpanIDFromHex("00f067aa0ba902b7")
|
||||
parentCtx := trace.SpanContext{
|
||||
parentCtx := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: traceID,
|
||||
SpanID: spanID,
|
||||
}
|
||||
})
|
||||
|
||||
if tc.isParentSampled {
|
||||
parentCtx.TraceFlags = trace.FlagsSampled
|
||||
parentCtx = parentCtx.WithTraceFlags(trace.FlagsSampled)
|
||||
}
|
||||
|
||||
params := SamplingParameters{ParentContext: parentCtx}
|
||||
@ -225,9 +225,9 @@ func TestTracestateIsPassed(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
parentCtx := trace.SpanContext{
|
||||
parentCtx := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceState: traceState,
|
||||
}
|
||||
})
|
||||
params := SamplingParameters{ParentContext: parentCtx}
|
||||
|
||||
require.Equal(t, traceState, tc.sampler.ShouldSample(params).Tracestate, "TraceState is not equal")
|
||||
|
@ -60,11 +60,11 @@ func TestNewSimpleSpanProcessorWithNilExporter(t *testing.T) {
|
||||
|
||||
func startSpan(tp trace.TracerProvider) trace.Span {
|
||||
tr := tp.Tracer("SimpleSpanProcessor")
|
||||
sc := trace.SpanContext{
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc)
|
||||
_, span := tr.Start(ctx, "OnEnd")
|
||||
return span
|
||||
@ -79,7 +79,7 @@ func TestSimpleSpanProcessorOnEnd(t *testing.T) {
|
||||
startSpan(tp).End()
|
||||
|
||||
wantTraceID := tid
|
||||
gotTraceID := te.spans[0].SpanContext.TraceID
|
||||
gotTraceID := te.spans[0].SpanContext.TraceID()
|
||||
if wantTraceID != gotTraceID {
|
||||
t.Errorf("SimplerSpanProcessor OnEnd() check: got %+v, want %+v\n", gotTraceID, wantTraceID)
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ func (s *span) Snapshot() *export.SpanSnapshot {
|
||||
sd.HasRemoteParent = s.hasRemoteParent
|
||||
sd.InstrumentationLibrary = s.instrumentationLibrary
|
||||
sd.Name = s.name
|
||||
sd.ParentSpanID = s.parent.SpanID
|
||||
sd.ParentSpanID = s.parent.SpanID()
|
||||
sd.Resource = s.resource
|
||||
sd.SpanContext = s.spanContext
|
||||
sd.SpanKind = s.spanKind
|
||||
@ -520,18 +520,28 @@ func (*span) private() {}
|
||||
|
||||
func startSpanInternal(ctx context.Context, tr *tracer, name string, parent trace.SpanContext, remoteParent bool, o *trace.SpanConfig) *span {
|
||||
span := &span{}
|
||||
span.spanContext = parent
|
||||
|
||||
cfg := tr.provider.config.Load().(*Config)
|
||||
|
||||
var tid trace.TraceID
|
||||
var sid trace.SpanID
|
||||
|
||||
if hasEmptySpanContext(parent) {
|
||||
// Generate both TraceID and SpanID
|
||||
span.spanContext.TraceID, span.spanContext.SpanID = cfg.IDGenerator.NewIDs(ctx)
|
||||
tid, sid = cfg.IDGenerator.NewIDs(ctx)
|
||||
} else {
|
||||
// TraceID already exists, just generate a SpanID
|
||||
span.spanContext.SpanID = cfg.IDGenerator.NewSpanID(ctx, parent.TraceID)
|
||||
tid = parent.TraceID()
|
||||
sid = cfg.IDGenerator.NewSpanID(ctx, tid)
|
||||
}
|
||||
|
||||
span.spanContext = trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: parent.TraceFlags(),
|
||||
TraceState: parent.TraceState(),
|
||||
})
|
||||
|
||||
span.attributes = newAttributesMap(cfg.SpanLimits.AttributeCountLimit)
|
||||
span.messageEvents = newEvictedQueue(cfg.SpanLimits.EventCountLimit)
|
||||
span.links = newEvictedQueue(cfg.SpanLimits.LinkCountLimit)
|
||||
@ -549,7 +559,7 @@ func startSpanInternal(ctx context.Context, tr *tracer, name string, parent trac
|
||||
kind: o.SpanKind,
|
||||
}
|
||||
sampled := makeSamplingDecision(data)
|
||||
span.spanContext.TraceState = sampled.Tracestate
|
||||
span.spanContext = span.spanContext.WithTraceState(sampled.Tracestate)
|
||||
|
||||
if !span.spanContext.IsSampled() && !o.Record {
|
||||
return span
|
||||
@ -575,10 +585,7 @@ func startSpanInternal(ctx context.Context, tr *tracer, name string, parent trac
|
||||
}
|
||||
|
||||
func hasEmptySpanContext(parent trace.SpanContext) bool {
|
||||
return parent.SpanID == emptySpanContext.SpanID &&
|
||||
parent.TraceID == emptySpanContext.TraceID &&
|
||||
parent.TraceFlags == emptySpanContext.TraceFlags &&
|
||||
parent.TraceState.IsEmpty()
|
||||
return parent.Equal(emptySpanContext)
|
||||
}
|
||||
|
||||
type samplingData struct {
|
||||
@ -595,10 +602,9 @@ type samplingData struct {
|
||||
|
||||
func makeSamplingDecision(data samplingData) SamplingResult {
|
||||
sampler := data.cfg.DefaultSampler
|
||||
spanContext := &data.span.spanContext
|
||||
sampled := sampler.ShouldSample(SamplingParameters{
|
||||
ParentContext: data.parent,
|
||||
TraceID: spanContext.TraceID,
|
||||
TraceID: data.span.spanContext.TraceID(),
|
||||
Name: data.name,
|
||||
HasRemoteParent: data.remoteParent,
|
||||
Kind: data.kind,
|
||||
@ -606,9 +612,9 @@ func makeSamplingDecision(data samplingData) SamplingResult {
|
||||
Links: data.links,
|
||||
})
|
||||
if sampled.Decision == RecordAndSample {
|
||||
spanContext.TraceFlags |= trace.FlagsSampled
|
||||
data.span.spanContext = data.span.spanContext.WithTraceFlags(data.span.spanContext.TraceFlags() | trace.FlagsSampled)
|
||||
} else {
|
||||
spanContext.TraceFlags &^= trace.FlagsSampled
|
||||
data.span.spanContext = data.span.spanContext.WithTraceFlags(data.span.spanContext.TraceFlags() &^ trace.FlagsSampled)
|
||||
}
|
||||
return sampled
|
||||
}
|
||||
|
@ -43,11 +43,11 @@ func (t *testSpanProcessor) OnStart(parent context.Context, s sdktrace.ReadWrite
|
||||
// a more meaningful way.
|
||||
{
|
||||
Key: "ParentTraceID",
|
||||
Value: attribute.StringValue(psc.TraceID.String()),
|
||||
Value: attribute.StringValue(psc.TraceID().String()),
|
||||
},
|
||||
{
|
||||
Key: "ParentSpanID",
|
||||
Value: attribute.StringValue(psc.SpanID.String()),
|
||||
Value: attribute.StringValue(psc.SpanID().String()),
|
||||
},
|
||||
}
|
||||
s.AddEvent("OnStart", trace.WithAttributes(kv...))
|
||||
@ -79,10 +79,10 @@ func TestRegisterSpanProcessor(t *testing.T) {
|
||||
|
||||
tid, _ := trace.TraceIDFromHex("01020304050607080102040810203040")
|
||||
sid, _ := trace.SpanIDFromHex("0102040810203040")
|
||||
parent := trace.SpanContext{
|
||||
parent := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), parent)
|
||||
|
||||
tr := tp.Tracer("SpanProcessor")
|
||||
@ -114,14 +114,14 @@ func TestRegisterSpanProcessor(t *testing.T) {
|
||||
c++
|
||||
case "ParentTraceID":
|
||||
gotValue := kv.Value.AsString()
|
||||
if gotValue != parent.TraceID.String() {
|
||||
t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.TraceID)
|
||||
if gotValue != parent.TraceID().String() {
|
||||
t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.TraceID())
|
||||
}
|
||||
tidOK = true
|
||||
case "ParentSpanID":
|
||||
gotValue := kv.Value.AsString()
|
||||
if gotValue != parent.SpanID.String() {
|
||||
t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.SpanID)
|
||||
if gotValue != parent.SpanID().String() {
|
||||
t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.SpanID())
|
||||
}
|
||||
sidOK = true
|
||||
default:
|
||||
|
@ -277,12 +277,12 @@ func TestSampling(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
if tc.parent {
|
||||
tid, sid := idg.NewIDs(ctx)
|
||||
psc := trace.SpanContext{
|
||||
psc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
}
|
||||
})
|
||||
if tc.sampledParent {
|
||||
psc.TraceFlags = trace.FlagsSampled
|
||||
psc = psc.WithTraceFlags(trace.FlagsSampled)
|
||||
}
|
||||
ctx = trace.ContextWithRemoteSpanContext(ctx, psc)
|
||||
}
|
||||
@ -313,11 +313,11 @@ func TestStartSpanWithParent(t *testing.T) {
|
||||
tr := tp.Tracer("SpanWithParent")
|
||||
ctx := context.Background()
|
||||
|
||||
sc1 := trace.SpanContext{
|
||||
sc1 := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
_, s1 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc1), "span1-unsampled-parent1")
|
||||
if err := checkChild(t, sc1, s1); err != nil {
|
||||
t.Error(err)
|
||||
@ -332,12 +332,12 @@ func TestStartSpanWithParent(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
sc2 := trace.SpanContext{
|
||||
sc2 := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 0x1,
|
||||
TraceState: ts,
|
||||
}
|
||||
})
|
||||
_, s3 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc2), "span3-sampled-parent2")
|
||||
if err := checkChild(t, sc2, s3); err != nil {
|
||||
t.Error(err)
|
||||
@ -369,10 +369,10 @@ func TestSetSpanAttributesOnStart(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -399,10 +399,10 @@ func TestSetSpanAttributes(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -435,27 +435,27 @@ func TestSamplerAttributesLocalChildSpan(t *testing.T) {
|
||||
|
||||
// endSpan expects only a single span in the test exporter, so manually clear the
|
||||
// fields that can't be tested for easily (times, span and trace ids).
|
||||
pid := got[0].SpanContext.SpanID
|
||||
got[0].SpanContext.TraceID = tid
|
||||
pid := got[0].SpanContext.SpanID()
|
||||
got[0].SpanContext = got[0].SpanContext.WithTraceID(tid)
|
||||
got[0].ParentSpanID = sid
|
||||
|
||||
checkTime(&got[0].StartTime)
|
||||
checkTime(&got[0].EndTime)
|
||||
|
||||
got[1].SpanContext.SpanID = trace.SpanID{}
|
||||
got[1].SpanContext.TraceID = tid
|
||||
got[1].SpanContext = got[1].SpanContext.WithSpanID(trace.SpanID{})
|
||||
got[1].SpanContext = got[1].SpanContext.WithTraceID(tid)
|
||||
got[1].ParentSpanID = pid
|
||||
got[0].SpanContext.SpanID = trace.SpanID{}
|
||||
got[0].SpanContext = got[0].SpanContext.WithSpanID(trace.SpanID{})
|
||||
|
||||
checkTime(&got[1].StartTime)
|
||||
checkTime(&got[1].EndTime)
|
||||
|
||||
want := []*export.SpanSnapshot{
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span1",
|
||||
Attributes: []attribute.KeyValue{attribute.Int("callCount", 2)},
|
||||
@ -464,10 +464,10 @@ func TestSamplerAttributesLocalChildSpan(t *testing.T) {
|
||||
InstrumentationLibrary: instrumentation.Library{Name: "SpanTwo"},
|
||||
},
|
||||
{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: pid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{attribute.Int("callCount", 1)},
|
||||
@ -500,10 +500,10 @@ func TestSetSpanAttributesOverLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -535,10 +535,10 @@ func TestSetSpanAttributesWithInvalidKey(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -580,10 +580,10 @@ func TestEvents(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
HasRemoteParent: true,
|
||||
@ -630,10 +630,10 @@ func TestEventsOverLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
MessageEvents: []trace.Event{
|
||||
@ -658,8 +658,8 @@ func TestLinks(t *testing.T) {
|
||||
k2v2 := attribute.String("key2", "value2")
|
||||
k3v3 := attribute.String("key3", "value3")
|
||||
|
||||
sc1 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc2 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc1 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
sc2 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
|
||||
links := []trace.Link{
|
||||
{SpanContext: sc1, Attributes: []attribute.KeyValue{k1v1}},
|
||||
@ -673,10 +673,10 @@ func TestLinks(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
HasRemoteParent: true,
|
||||
@ -692,9 +692,9 @@ func TestLinks(t *testing.T) {
|
||||
func TestLinksOverLimit(t *testing.T) {
|
||||
te := NewTestExporter()
|
||||
|
||||
sc1 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc2 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc3 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc1 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
sc2 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
sc3 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
|
||||
tp := NewTracerProvider(WithSpanLimits(SpanLimits{LinkCountLimit: 2}), WithSyncer(te), WithResource(resource.Empty()))
|
||||
|
||||
@ -715,10 +715,10 @@ func TestLinksOverLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Links: []trace.Link{
|
||||
@ -741,11 +741,11 @@ func TestSetSpanName(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
want := "SpanName-1"
|
||||
ctx = trace.ContextWithRemoteSpanContext(ctx, trace.SpanContext{
|
||||
ctx = trace.ContextWithRemoteSpanContext(ctx, trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 1,
|
||||
})
|
||||
}))
|
||||
_, span := tp.Tracer("SetSpanName").Start(ctx, "SpanName-1")
|
||||
got, err := endSpan(te, span)
|
||||
if err != nil {
|
||||
@ -769,10 +769,10 @@ func TestSetSpanStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
@ -798,10 +798,10 @@ func TestSetSpanStatusWithoutMessageWhenStatusIsNotError(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
@ -823,11 +823,11 @@ func cmpDiff(x, y interface{}) string {
|
||||
}
|
||||
|
||||
func remoteSpanContext() trace.SpanContext {
|
||||
return trace.SpanContext{
|
||||
return trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: 1,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// checkChild is test utility function that tests that c has fields set appropriately,
|
||||
@ -837,16 +837,16 @@ func checkChild(t *testing.T, p trace.SpanContext, apiSpan trace.Span) error {
|
||||
if s == nil {
|
||||
return fmt.Errorf("got nil child span, want non-nil")
|
||||
}
|
||||
if got, want := s.spanContext.TraceID.String(), p.TraceID.String(); got != want {
|
||||
if got, want := s.spanContext.TraceID().String(), p.TraceID().String(); got != want {
|
||||
return fmt.Errorf("got child trace ID %s, want %s", got, want)
|
||||
}
|
||||
if childID, parentID := s.spanContext.SpanID.String(), p.SpanID.String(); childID == parentID {
|
||||
if childID, parentID := s.spanContext.SpanID().String(), p.SpanID().String(); childID == parentID {
|
||||
return fmt.Errorf("got child span ID %s, parent span ID %s; want unequal IDs", childID, parentID)
|
||||
}
|
||||
if got, want := s.spanContext.TraceFlags, p.TraceFlags; got != want {
|
||||
if got, want := s.spanContext.TraceFlags(), p.TraceFlags(); got != want {
|
||||
return fmt.Errorf("got child trace options %d, want %d", got, want)
|
||||
}
|
||||
got, want := s.spanContext.TraceState, p.TraceState
|
||||
got, want := s.spanContext.TraceState(), p.TraceState()
|
||||
assert.Equal(t, want, got)
|
||||
return nil
|
||||
}
|
||||
@ -909,10 +909,10 @@ func endSpan(te *testExporter, span trace.Span) (*export.SpanSnapshot, error) {
|
||||
return nil, fmt.Errorf("got %d exported spans, want one span", te.Len())
|
||||
}
|
||||
got := te.Spans()[0]
|
||||
if !got.SpanContext.SpanID.IsValid() {
|
||||
if !got.SpanContext.SpanID().IsValid() {
|
||||
return nil, fmt.Errorf("exporting span: expected nonzero SpanID")
|
||||
}
|
||||
got.SpanContext.SpanID = trace.SpanID{}
|
||||
got.SpanContext = got.SpanContext.WithSpanID(trace.SpanID{})
|
||||
if !checkTime(&got.StartTime) {
|
||||
return nil, fmt.Errorf("exporting span: expected nonzero StartTime")
|
||||
}
|
||||
@ -984,16 +984,16 @@ func TestStartSpanAfterEnd(t *testing.T) {
|
||||
t.Fatal("span-2 not recorded")
|
||||
}
|
||||
|
||||
if got, want := gotSpan1.SpanContext.TraceID, gotParent.SpanContext.TraceID; got != want {
|
||||
if got, want := gotSpan1.SpanContext.TraceID(), gotParent.SpanContext.TraceID(); got != want {
|
||||
t.Errorf("span-1.TraceID=%q; want %q", got, want)
|
||||
}
|
||||
if got, want := gotSpan2.SpanContext.TraceID, gotParent.SpanContext.TraceID; got != want {
|
||||
if got, want := gotSpan2.SpanContext.TraceID(), gotParent.SpanContext.TraceID(); got != want {
|
||||
t.Errorf("span-2.TraceID=%q; want %q", got, want)
|
||||
}
|
||||
if got, want := gotSpan1.ParentSpanID, gotParent.SpanContext.SpanID; got != want {
|
||||
if got, want := gotSpan1.ParentSpanID, gotParent.SpanContext.SpanID(); got != want {
|
||||
t.Errorf("span-1.ParentSpanID=%q; want %q (parent.SpanID)", got, want)
|
||||
}
|
||||
if got, want := gotSpan2.ParentSpanID, gotSpan1.SpanContext.SpanID; got != want {
|
||||
if got, want := gotSpan2.ParentSpanID, gotSpan1.SpanContext.SpanID(); got != want {
|
||||
t.Errorf("span-2.ParentSpanID=%q; want %q (span1.SpanID)", got, want)
|
||||
}
|
||||
}
|
||||
@ -1073,11 +1073,11 @@ func TestExecutionTracerTaskEnd(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
ctx = trace.ContextWithRemoteSpanContext(ctx,
|
||||
trace.SpanContext{
|
||||
trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tID,
|
||||
SpanID: sID,
|
||||
TraceFlags: 0,
|
||||
},
|
||||
}),
|
||||
)
|
||||
_, apiSpan = tr.Start(
|
||||
ctx,
|
||||
@ -1158,10 +1158,10 @@ func TestRecordError(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
StatusCode: codes.Unset,
|
||||
@ -1198,10 +1198,10 @@ func TestRecordErrorNil(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
@ -1296,10 +1296,10 @@ func TestWithResource(t *testing.T) {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: []attribute.KeyValue{
|
||||
@ -1333,10 +1333,10 @@ func TestWithInstrumentationVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
SpanKind: trace.SpanKindInternal,
|
||||
@ -1384,20 +1384,20 @@ func TestReadOnlySpan(t *testing.T) {
|
||||
|
||||
// Initialize parent context.
|
||||
tID, sID := cfg.IDGenerator.NewIDs(context.Background())
|
||||
parent := trace.SpanContext{
|
||||
parent := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tID,
|
||||
SpanID: sID,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), parent)
|
||||
|
||||
// Initialize linked context.
|
||||
tID, sID = cfg.IDGenerator.NewIDs(context.Background())
|
||||
linked := trace.SpanContext{
|
||||
linked := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tID,
|
||||
SpanID: sID,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
|
||||
st := time.Now()
|
||||
ctx, span := tr.Start(ctx, "foo", trace.WithTimestamp(st),
|
||||
@ -1464,11 +1464,11 @@ func TestReadWriteSpan(t *testing.T) {
|
||||
|
||||
// Initialize parent context.
|
||||
tID, sID := cfg.IDGenerator.NewIDs(context.Background())
|
||||
parent := trace.SpanContext{
|
||||
parent := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tID,
|
||||
SpanID: sID,
|
||||
TraceFlags: 0x1,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), parent)
|
||||
|
||||
_, span := tr.Start(ctx, "foo")
|
||||
@ -1524,10 +1524,10 @@ func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
Attributes: nil,
|
||||
@ -1570,8 +1570,8 @@ func TestAddLinksWithMoreAttributesThanLimit(t *testing.T) {
|
||||
k3v3 := attribute.String("key3", "value3")
|
||||
k4v4 := attribute.String("key4", "value4")
|
||||
|
||||
sc1 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc2 := trace.SpanContext{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}}
|
||||
sc1 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
sc2 := trace.NewSpanContext(trace.SpanContextConfig{TraceID: trace.TraceID([16]byte{1, 1}), SpanID: trace.SpanID{3}})
|
||||
|
||||
span := startSpan(tp, "Links", trace.WithLinks([]trace.Link{
|
||||
{SpanContext: sc1, Attributes: []attribute.KeyValue{k1v1, k2v2}},
|
||||
@ -1584,10 +1584,10 @@ func TestAddLinksWithMoreAttributesThanLimit(t *testing.T) {
|
||||
}
|
||||
|
||||
want := &export.SpanSnapshot{
|
||||
SpanContext: trace.SpanContext{
|
||||
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
TraceFlags: 0x1,
|
||||
},
|
||||
}),
|
||||
ParentSpanID: sid,
|
||||
Name: "span0",
|
||||
HasRemoteParent: true,
|
||||
@ -1614,7 +1614,7 @@ func (s *stateSampler) ShouldSample(p SamplingParameters) SamplingResult {
|
||||
if strings.HasPrefix(p.Name, s.prefix) {
|
||||
decision = RecordAndSample
|
||||
}
|
||||
return SamplingResult{Decision: decision, Tracestate: s.f(p.ParentContext.TraceState)}
|
||||
return SamplingResult{Decision: decision, Tracestate: s.f(p.ParentContext.TraceState())}
|
||||
}
|
||||
|
||||
func (s stateSampler) Description() string {
|
||||
@ -1714,17 +1714,17 @@ func TestSamplerTraceState(t *testing.T) {
|
||||
tp := NewTracerProvider(WithDefaultSampler(ts.sampler), WithSyncer(te), WithResource(resource.Empty()))
|
||||
tr := tp.Tracer("TraceState")
|
||||
|
||||
sc1 := trace.SpanContext{
|
||||
sc1 := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: tid,
|
||||
SpanID: sid,
|
||||
TraceFlags: trace.FlagsSampled,
|
||||
TraceState: ts.input,
|
||||
}
|
||||
})
|
||||
ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc1)
|
||||
_, span := tr.Start(ctx, ts.spanName)
|
||||
|
||||
// span's TraceState should be set regardless of Sampled/NonSampled state.
|
||||
require.Equal(t, ts.want, span.SpanContext().TraceState)
|
||||
require.Equal(t, ts.want, span.SpanContext().TraceState())
|
||||
|
||||
span.End()
|
||||
|
||||
@ -1736,7 +1736,7 @@ func TestSamplerTraceState(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
receivedState := got[0].SpanContext.TraceState
|
||||
receivedState := got[0].SpanContext.TraceState()
|
||||
|
||||
if diff := cmpDiff(receivedState, ts.want); diff != "" {
|
||||
t.Errorf("TraceState not propagated: -got +want %s", diff)
|
||||
|
@ -32,11 +32,11 @@ func TestNewSpanConfig(t *testing.T) {
|
||||
timestamp1 := time.Unix(0, 0)
|
||||
|
||||
link1 := Link{
|
||||
SpanContext: SpanContext{TraceID: TraceID([16]byte{1, 1}), SpanID: SpanID{3}},
|
||||
SpanContext: SpanContext{traceID: TraceID([16]byte{1, 1}), spanID: SpanID{3}},
|
||||
Attributes: []attribute.KeyValue{k1v1},
|
||||
}
|
||||
link2 := Link{
|
||||
SpanContext: SpanContext{TraceID: TraceID([16]byte{1, 1}), SpanID: SpanID{3}},
|
||||
SpanContext: SpanContext{traceID: TraceID([16]byte{1, 1}), spanID: SpanID{3}},
|
||||
Attributes: []attribute.KeyValue{k1v2, k2v2},
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ replace go.opentelemetry.io/otel/sdk/metric => ../sdk/metric
|
||||
replace go.opentelemetry.io/otel/trace => ./
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opentelemetry.io/otel v0.18.0
|
||||
)
|
||||
|
114
trace/trace.go
114
trace/trace.go
@ -189,6 +189,8 @@ type TraceState struct { //nolint:golint
|
||||
}
|
||||
|
||||
var _ json.Marshaler = TraceState{}
|
||||
var _ json.Marshaler = SpanContext{}
|
||||
|
||||
var keyFormatRegExp = regexp.MustCompile(
|
||||
`^((` + traceStateKeyFormat + `)|(` + traceStateKeyFormatWithMultiTenantVendor + `))$`,
|
||||
)
|
||||
@ -317,43 +319,141 @@ func isTraceStateKeyValueValid(kv attribute.KeyValue) bool {
|
||||
valueFormatRegExp.MatchString(kv.Value.Emit())
|
||||
}
|
||||
|
||||
// SpanContext contains identifying trace information about a Span.
|
||||
type SpanContext struct {
|
||||
// SpanContextConfig contains mutable fields usable for constructing
|
||||
// an immutable SpanContext.
|
||||
type SpanContextConfig struct {
|
||||
TraceID TraceID
|
||||
SpanID SpanID
|
||||
TraceFlags byte
|
||||
TraceState TraceState
|
||||
}
|
||||
|
||||
// NewSpanContext constructs a SpanContext using values from the provided
|
||||
// SpanContextConfig.
|
||||
func NewSpanContext(config SpanContextConfig) SpanContext {
|
||||
return SpanContext{
|
||||
traceID: config.TraceID,
|
||||
spanID: config.SpanID,
|
||||
traceFlags: config.TraceFlags,
|
||||
traceState: config.TraceState,
|
||||
}
|
||||
}
|
||||
|
||||
// SpanContext contains identifying trace information about a Span.
|
||||
type SpanContext struct {
|
||||
traceID TraceID
|
||||
spanID SpanID
|
||||
traceFlags byte
|
||||
traceState TraceState
|
||||
}
|
||||
|
||||
// IsValid returns if the SpanContext is valid. A valid span context has a
|
||||
// valid TraceID and SpanID.
|
||||
func (sc SpanContext) IsValid() bool {
|
||||
return sc.HasTraceID() && sc.HasSpanID()
|
||||
}
|
||||
|
||||
// TraceID returns the TraceID from the SpanContext.
|
||||
func (sc SpanContext) TraceID() TraceID {
|
||||
return sc.traceID
|
||||
}
|
||||
|
||||
// HasTraceID checks if the SpanContext has a valid TraceID.
|
||||
func (sc SpanContext) HasTraceID() bool {
|
||||
return sc.TraceID.IsValid()
|
||||
return sc.traceID.IsValid()
|
||||
}
|
||||
|
||||
// WithTraceID returns a new SpanContext with the TraceID replaced.
|
||||
func (sc SpanContext) WithTraceID(traceID TraceID) SpanContext {
|
||||
return SpanContext{
|
||||
traceID: traceID,
|
||||
spanID: sc.spanID,
|
||||
traceFlags: sc.traceFlags,
|
||||
traceState: sc.traceState,
|
||||
}
|
||||
}
|
||||
|
||||
// SpanID returns the SpanID from the SpanContext.
|
||||
func (sc SpanContext) SpanID() SpanID {
|
||||
return sc.spanID
|
||||
}
|
||||
|
||||
// HasSpanID checks if the SpanContext has a valid SpanID.
|
||||
func (sc SpanContext) HasSpanID() bool {
|
||||
return sc.SpanID.IsValid()
|
||||
return sc.spanID.IsValid()
|
||||
}
|
||||
|
||||
// WithSpanID returns a new SpanContext with the SpanID replaced.
|
||||
func (sc SpanContext) WithSpanID(spanID SpanID) SpanContext {
|
||||
return SpanContext{
|
||||
traceID: sc.traceID,
|
||||
spanID: spanID,
|
||||
traceFlags: sc.traceFlags,
|
||||
traceState: sc.traceState,
|
||||
}
|
||||
}
|
||||
|
||||
// TraceFlags returns the flags from the SpanContext.
|
||||
func (sc SpanContext) TraceFlags() byte {
|
||||
return sc.traceFlags
|
||||
}
|
||||
|
||||
// WithTraceFlags returns a new SpanContext with the TraceFlags replaced.
|
||||
func (sc SpanContext) WithTraceFlags(flags byte) SpanContext {
|
||||
return SpanContext{
|
||||
traceID: sc.traceID,
|
||||
spanID: sc.spanID,
|
||||
traceFlags: flags,
|
||||
traceState: sc.traceState,
|
||||
}
|
||||
}
|
||||
|
||||
// IsDeferred returns if the deferred bit is set in the trace flags.
|
||||
func (sc SpanContext) IsDeferred() bool {
|
||||
return sc.TraceFlags&FlagsDeferred == FlagsDeferred
|
||||
return sc.traceFlags&FlagsDeferred == FlagsDeferred
|
||||
}
|
||||
|
||||
// IsDebug returns if the debug bit is set in the trace flags.
|
||||
func (sc SpanContext) IsDebug() bool {
|
||||
return sc.TraceFlags&FlagsDebug == FlagsDebug
|
||||
return sc.traceFlags&FlagsDebug == FlagsDebug
|
||||
}
|
||||
|
||||
// IsSampled returns if the sampling bit is set in the trace flags.
|
||||
func (sc SpanContext) IsSampled() bool {
|
||||
return sc.TraceFlags&FlagsSampled == FlagsSampled
|
||||
return sc.traceFlags&FlagsSampled == FlagsSampled
|
||||
}
|
||||
|
||||
// TraceState returns the TraceState from the SpanContext.
|
||||
func (sc SpanContext) TraceState() TraceState {
|
||||
return sc.traceState
|
||||
}
|
||||
|
||||
// WithTraceState returns a new SpanContext with the TraceState replaced.
|
||||
func (sc SpanContext) WithTraceState(state TraceState) SpanContext {
|
||||
return SpanContext{
|
||||
traceID: sc.traceID,
|
||||
spanID: sc.spanID,
|
||||
traceFlags: sc.traceFlags,
|
||||
traceState: state,
|
||||
}
|
||||
}
|
||||
|
||||
// Equal is a predicate that determines whether two SpanContext values are equal.
|
||||
func (sc SpanContext) Equal(other SpanContext) bool {
|
||||
return sc.traceID == other.traceID &&
|
||||
sc.spanID == other.spanID &&
|
||||
sc.traceFlags == other.traceFlags &&
|
||||
sc.traceState.String() == other.traceState.String()
|
||||
}
|
||||
|
||||
// MarshalJSON implements a custom marshal function to encode a SpanContext.
|
||||
func (sc SpanContext) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(SpanContextConfig{
|
||||
TraceID: sc.traceID,
|
||||
SpanID: sc.spanID,
|
||||
TraceFlags: sc.traceFlags,
|
||||
TraceState: sc.traceState,
|
||||
})
|
||||
}
|
||||
|
||||
type traceContextKeyType int
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -31,7 +32,7 @@ type testSpan struct {
|
||||
ID byte
|
||||
}
|
||||
|
||||
func (s testSpan) SpanContext() SpanContext { return SpanContext{SpanID: [8]byte{s.ID}} }
|
||||
func (s testSpan) SpanContext() SpanContext { return SpanContext{spanID: [8]byte{s.ID}} }
|
||||
|
||||
func TestContextSpan(t *testing.T) {
|
||||
testCases := []struct {
|
||||
@ -77,7 +78,7 @@ func TestContextRemoteSpanContext(t *testing.T) {
|
||||
t.Errorf("RemoteSpanContextFromContext returned %v from an empty context, want %v", got, empty)
|
||||
}
|
||||
|
||||
want := SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{42}}
|
||||
want := SpanContext{traceID: [16]byte{1}, spanID: [8]byte{42}}
|
||||
ctx = ContextWithRemoteSpanContext(ctx, want)
|
||||
if got, ok := ctx.Value(remoteContextKey).(SpanContext); !ok {
|
||||
t.Errorf("failed to set SpanContext with %#v", want)
|
||||
@ -89,7 +90,7 @@ func TestContextRemoteSpanContext(t *testing.T) {
|
||||
t.Errorf("RemoteSpanContextFromContext returned %v from a set context, want %v", got, want)
|
||||
}
|
||||
|
||||
want = SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{43}}
|
||||
want = SpanContext{traceID: [16]byte{1}, spanID: [8]byte{43}}
|
||||
ctx = ContextWithRemoteSpanContext(ctx, want)
|
||||
if got, ok := ctx.Value(remoteContextKey).(SpanContext); !ok {
|
||||
t.Errorf("failed to set SpanContext with %#v", want)
|
||||
@ -134,8 +135,8 @@ func TestIsValid(t *testing.T) {
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
sc := SpanContext{
|
||||
TraceID: testcase.tid,
|
||||
SpanID: testcase.sid,
|
||||
traceID: testcase.tid,
|
||||
spanID: testcase.sid,
|
||||
}
|
||||
have := sc.IsValid()
|
||||
if have != testcase.want {
|
||||
@ -207,7 +208,7 @@ func TestHasTraceID(t *testing.T) {
|
||||
} {
|
||||
t.Run(testcase.name, func(t *testing.T) {
|
||||
//proto: func (sc SpanContext) HasTraceID() bool{}
|
||||
sc := SpanContext{TraceID: testcase.tid}
|
||||
sc := SpanContext{traceID: testcase.tid}
|
||||
have := sc.HasTraceID()
|
||||
if have != testcase.want {
|
||||
t.Errorf("Want: %v, but have: %v", testcase.want, have)
|
||||
@ -224,7 +225,7 @@ func TestHasSpanID(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "SpanContext.HasSpanID() returns true if self.SpanID != 0",
|
||||
sc: SpanContext{SpanID: [8]byte{42}},
|
||||
sc: SpanContext{spanID: [8]byte{42}},
|
||||
want: true,
|
||||
}, {
|
||||
name: "SpanContext.HasSpanID() returns false if self.SpanID == 0",
|
||||
@ -251,27 +252,27 @@ func TestSpanContextIsSampled(t *testing.T) {
|
||||
{
|
||||
name: "sampled",
|
||||
sc: SpanContext{
|
||||
TraceID: TraceID([16]byte{1}),
|
||||
TraceFlags: FlagsSampled,
|
||||
traceID: TraceID([16]byte{1}),
|
||||
traceFlags: FlagsSampled,
|
||||
},
|
||||
want: true,
|
||||
}, {
|
||||
name: "unused bits are ignored, still not sampled",
|
||||
sc: SpanContext{
|
||||
TraceID: TraceID([16]byte{1}),
|
||||
TraceFlags: ^FlagsSampled,
|
||||
traceID: TraceID([16]byte{1}),
|
||||
traceFlags: ^FlagsSampled,
|
||||
},
|
||||
want: false,
|
||||
}, {
|
||||
name: "unused bits are ignored, still sampled",
|
||||
sc: SpanContext{
|
||||
TraceID: TraceID([16]byte{1}),
|
||||
TraceFlags: FlagsSampled | ^FlagsSampled,
|
||||
traceID: TraceID([16]byte{1}),
|
||||
traceFlags: FlagsSampled | ^FlagsSampled,
|
||||
},
|
||||
want: true,
|
||||
}, {
|
||||
name: "not sampled/default",
|
||||
sc: SpanContext{TraceID: TraceID{}},
|
||||
sc: SpanContext{traceID: TraceID{}},
|
||||
want: false,
|
||||
},
|
||||
} {
|
||||
@ -431,7 +432,7 @@ func TestSpanContextFromContext(t *testing.T) {
|
||||
{
|
||||
name: "span 1",
|
||||
context: ContextWithSpan(context.Background(), testSpan{ID: 1}),
|
||||
expectedSpanContext: SpanContext{SpanID: [8]byte{1}},
|
||||
expectedSpanContext: SpanContext{spanID: [8]byte{1}},
|
||||
},
|
||||
}
|
||||
|
||||
@ -978,10 +979,10 @@ func TestTraceStateFromKeyValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func assertSpanContextEqual(got SpanContext, want SpanContext) bool {
|
||||
return got.SpanID == want.SpanID &&
|
||||
got.TraceID == want.TraceID &&
|
||||
got.TraceFlags == want.TraceFlags &&
|
||||
assertTraceStateEqual(got.TraceState, want.TraceState)
|
||||
return got.spanID == want.spanID &&
|
||||
got.traceID == want.traceID &&
|
||||
got.traceFlags == want.traceFlags &&
|
||||
assertTraceStateEqual(got.traceState, want.traceState)
|
||||
}
|
||||
|
||||
func assertTraceStateEqual(got TraceState, want TraceState) bool {
|
||||
@ -1006,3 +1007,92 @@ var kvsWithMaxMembers = func() []attribute.KeyValue {
|
||||
}
|
||||
return kvs
|
||||
}()
|
||||
|
||||
func TestNewSpanContext(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
config SpanContextConfig
|
||||
expectedSpanContext SpanContext
|
||||
}{
|
||||
{
|
||||
name: "Complete SpanContext",
|
||||
config: SpanContextConfig{
|
||||
TraceID: TraceID([16]byte{1}),
|
||||
SpanID: SpanID([8]byte{42}),
|
||||
TraceFlags: 0x1,
|
||||
TraceState: TraceState{kvs: []attribute.KeyValue{
|
||||
attribute.String("foo", "bar"),
|
||||
}},
|
||||
},
|
||||
expectedSpanContext: SpanContext{
|
||||
traceID: TraceID([16]byte{1}),
|
||||
spanID: SpanID([8]byte{42}),
|
||||
traceFlags: 0x1,
|
||||
traceState: TraceState{kvs: []attribute.KeyValue{
|
||||
attribute.String("foo", "bar"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Empty SpanContext",
|
||||
config: SpanContextConfig{},
|
||||
expectedSpanContext: SpanContext{},
|
||||
},
|
||||
{
|
||||
name: "Partial SpanContext",
|
||||
config: SpanContextConfig{
|
||||
TraceID: TraceID([16]byte{1}),
|
||||
SpanID: SpanID([8]byte{42}),
|
||||
},
|
||||
expectedSpanContext: SpanContext{
|
||||
traceID: TraceID([16]byte{1}),
|
||||
spanID: SpanID([8]byte{42}),
|
||||
traceFlags: 0x0,
|
||||
traceState: TraceState{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
sctx := NewSpanContext(tc.config)
|
||||
if !assertSpanContextEqual(sctx, tc.expectedSpanContext) {
|
||||
t.Fatalf("%s: Unexpected context created: %s", tc.name, cmp.Diff(sctx, tc.expectedSpanContext))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanContextDerivation(t *testing.T) {
|
||||
from := SpanContext{}
|
||||
to := SpanContext{traceID: TraceID([16]byte{1})}
|
||||
|
||||
modified := from.WithTraceID(to.TraceID())
|
||||
if !assertSpanContextEqual(modified, to) {
|
||||
t.Fatalf("WithTraceID: Unexpected context created: %s", cmp.Diff(modified, to))
|
||||
}
|
||||
|
||||
from = to
|
||||
to.spanID = SpanID([8]byte{42})
|
||||
|
||||
modified = from.WithSpanID(to.SpanID())
|
||||
if !assertSpanContextEqual(modified, to) {
|
||||
t.Fatalf("WithSpanID: Unexpected context created: %s", cmp.Diff(modified, to))
|
||||
}
|
||||
|
||||
from = to
|
||||
to.traceFlags = 0x13
|
||||
|
||||
modified = from.WithTraceFlags(to.TraceFlags())
|
||||
if !assertSpanContextEqual(modified, to) {
|
||||
t.Fatalf("WithTraceFlags: Unexpected context created: %s", cmp.Diff(modified, to))
|
||||
}
|
||||
|
||||
from = to
|
||||
to.traceState = TraceState{kvs: []attribute.KeyValue{attribute.String("foo", "bar")}}
|
||||
|
||||
modified = from.WithTraceState(to.TraceState())
|
||||
if !assertSpanContextEqual(modified, to) {
|
||||
t.Fatalf("WithTraceState: Unexpected context created: %s", cmp.Diff(modified, to))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user