diff --git a/CHANGELOG.md b/CHANGELOG.md index 226f05bf600..6eb237bf931 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - The storage of a local or remote Span in a `context.Context` using its SpanContext is unified to store just the current Span. The Span's SpanContext can now self-identify as being remote or not. This means that `"go.opentelemetry.io/otel/trace".ContextWithRemoteSpanContext` will now overwrite any existing current Span, not just existing remote Spans, and make it the current Span in a `context.Context`. (#1731) +- Information about a parent span context in a `"go.opentelemetry.io/otel/export/trace".SpanSnapshot` is unified in a new `Parent` field. + The existing `ParentSpanID` and `HasRemoteParent` fields are removed in favor of this. (#1748) ### Removed diff --git a/exporters/otlp/internal/otlptest/data.go b/exporters/otlp/internal/otlptest/data.go index 354e6c43d6c..40eac27ce75 100644 --- a/exporters/otlp/internal/otlptest/data.go +++ b/exporters/otlp/internal/otlptest/data.go @@ -87,7 +87,11 @@ func SingleSpanSnapshot() []*exporttrace.SpanSnapshot { 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}, + Parent: 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{1, 2, 3, 4, 5, 6, 7, 8}, + TraceFlags: trace.FlagsSampled, + }), SpanKind: trace.SpanKindInternal, Name: "foo", StartTime: time.Date(2020, time.December, 8, 20, 23, 0, 0, time.UTC), @@ -97,7 +101,6 @@ func SingleSpanSnapshot() []*exporttrace.SpanSnapshot { Links: []trace.Link{}, StatusCode: codes.Ok, StatusMessage: "", - HasRemoteParent: false, DroppedAttributeCount: 0, DroppedMessageEventCount: 0, DroppedLinkCount: 0, diff --git a/exporters/otlp/internal/transform/span.go b/exporters/otlp/internal/transform/span.go index 6cda57e70eb..a4ffc4c1637 100644 --- a/exporters/otlp/internal/transform/span.go +++ b/exporters/otlp/internal/transform/span.go @@ -121,8 +121,8 @@ func span(sd *export.SpanSnapshot) *tracepb.Span { DroppedLinksCount: uint32(sd.DroppedLinkCount), } - if sd.ParentSpanID.IsValid() { - s.ParentSpanId = sd.ParentSpanID[:] + if psid := sd.Parent.SpanID(); psid.IsValid() { + s.ParentSpanId = psid[:] } return s diff --git a/exporters/otlp/internal/transform/span_test.go b/exporters/otlp/internal/transform/span_test.go index e64308ef8dd..bc2998e71ae 100644 --- a/exporters/otlp/internal/transform/span_test.go +++ b/exporters/otlp/internal/transform/span_test.go @@ -205,11 +205,16 @@ func TestSpanData(t *testing.T) { 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", - StartTime: startTime, - EndTime: endTime, + Parent: 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{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, + TraceState: traceState, + Remote: true, + }), + SpanKind: trace.SpanKindServer, + Name: "span data to span data", + StartTime: startTime, + EndTime: endTime, MessageEvents: []trace.Event{ {Time: startTime, Attributes: []attribute.KeyValue{ @@ -244,9 +249,8 @@ func TestSpanData(t *testing.T) { }, }, }, - StatusCode: codes.Error, - StatusMessage: "utterly unrecognized", - HasRemoteParent: true, + StatusCode: codes.Error, + StatusMessage: "utterly unrecognized", Attributes: []attribute.KeyValue{ attribute.Int64("timeout_ns", 12e9), }, diff --git a/exporters/otlp/otlp_span_test.go b/exporters/otlp/otlp_span_test.go index 62fdc39ee88..7e71df21d41 100644 --- a/exporters/otlp/otlp_span_test.go +++ b/exporters/otlp/otlp_span_test.go @@ -104,11 +104,15 @@ func TestExportSpans(t *testing.T) { 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", - StartTime: startTime, - EndTime: endTime, + Parent: 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.SpanKindInternal, + Name: "internal process", + StartTime: startTime, + EndTime: endTime, Attributes: []attribute.KeyValue{ attribute.String("user", "alice"), attribute.Bool("authenticated", true), diff --git a/exporters/stdout/trace_test.go b/exporters/stdout/trace_test.go index 851bef0355a..7c0f7e91714 100644 --- a/exporters/stdout/trace_test.go +++ b/exporters/stdout/trace_test.go @@ -84,7 +84,13 @@ func TestExporter_ExportSpan(t *testing.T) { `"Key":"key",` + `"Value":{"Type":"STRING","Value":"val"}` + `}],"Remote":false},` + - `"ParentSpanID":"0000000000000000",` + + `"Parent":{` + + `"TraceID":"00000000000000000000000000000000",` + + `"SpanID":"0000000000000000",` + + `"TraceFlags":0,` + + `"TraceState":null,` + + `"Remote":false` + + `},` + `"SpanKind":1,` + `"Name":"/foo",` + `"StartTime":` + string(expectedSerializedNow) + "," + @@ -123,7 +129,6 @@ func TestExporter_ExportSpan(t *testing.T) { `"Links":null,` + `"StatusCode":"Error",` + `"StatusMessage":"interesting",` + - `"HasRemoteParent":false,` + `"DroppedAttributeCount":0,` + `"DroppedMessageEventCount":0,` + `"DroppedLinkCount":0,` + diff --git a/exporters/trace/jaeger/jaeger.go b/exporters/trace/jaeger/jaeger.go index 11b3e5d9c46..b1b9960da61 100644 --- a/exporters/trace/jaeger/jaeger.go +++ b/exporters/trace/jaeger/jaeger.go @@ -314,11 +314,12 @@ func spanSnapshotToThrift(ss *export.SpanSnapshot) *gen.Span { tid := ss.SpanContext.TraceID() sid := ss.SpanContext.SpanID() + psid := ss.Parent.SpanID() return &gen.Span{ 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[:])), + ParentSpanId: int64(binary.BigEndian.Uint64(psid[:])), OperationName: ss.Name, // TODO: if span kind is added then add prefix "Sent"/"Recv" Flags: int32(ss.SpanContext.TraceFlags()), StartTime: ss.StartTime.UnixNano() / 1000, diff --git a/exporters/trace/jaeger/jaeger_test.go b/exporters/trace/jaeger/jaeger_test.go index 0226d79a8a0..a107af00af3 100644 --- a/exporters/trace/jaeger/jaeger_test.go +++ b/exporters/trace/jaeger/jaeger_test.go @@ -445,11 +445,14 @@ func Test_spanSnapshotToThrift(t *testing.T) { { name: "with parent", data: &export.SpanSnapshot{ - ParentSpanID: parentSpanID, SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ TraceID: traceID, SpanID: spanID, }), + Parent: trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: traceID, + SpanID: parentSpanID, + }), Links: []trace.Link{ { SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ @@ -499,11 +502,14 @@ func Test_spanSnapshotToThrift(t *testing.T) { { name: "resources do not affect the tags", data: &export.SpanSnapshot{ - ParentSpanID: parentSpanID, SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ TraceID: traceID, SpanID: spanID, }), + Parent: trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: traceID, + SpanID: parentSpanID, + }), Name: "/foo", StartTime: now, EndTime: now, diff --git a/exporters/trace/zipkin/model.go b/exporters/trace/zipkin/model.go index 26df037ff72..b54048f39da 100644 --- a/exporters/trace/zipkin/model.go +++ b/exporters/trace/zipkin/model.go @@ -72,7 +72,7 @@ func toZipkinSpanContext(data *export.SpanSnapshot) zkmodel.SpanContext { return zkmodel.SpanContext{ TraceID: toZipkinTraceID(data.SpanContext.TraceID()), ID: toZipkinID(data.SpanContext.SpanID()), - ParentID: toZipkinParentID(data.ParentSpanID), + ParentID: toZipkinParentID(data.Parent.SpanID()), Debug: false, Sampled: nil, Err: nil, diff --git a/exporters/trace/zipkin/model_test.go b/exporters/trace/zipkin/model_test.go index e4575728560..77e4e99963c 100644 --- a/exporters/trace/zipkin/model_test.go +++ b/exporters/trace/zipkin/model_test.go @@ -46,11 +46,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindServer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -80,11 +83,10 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + SpanKind: trace.SpanKindServer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -113,11 +115,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindUnspecified, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -146,11 +151,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindInternal, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -179,11 +187,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindClient, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -212,11 +223,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindProducer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -245,11 +259,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindConsumer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -278,11 +295,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindServer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.Int64("attr1", 42), attribute.String("attr2", "bar"), @@ -298,11 +318,14 @@ func TestModelConversion(t *testing.T) { 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", - StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), - EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), + Parent: 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{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38}, + }), + SpanKind: trace.SpanKindServer, + Name: "foo", + StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), + EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC), Attributes: []attribute.KeyValue{ attribute.String("error", "false"), }, diff --git a/exporters/trace/zipkin/zipkin_test.go b/exporters/trace/zipkin/zipkin_test.go index e45cf91e137..07748a87c53 100644 --- a/exporters/trace/zipkin/zipkin_test.go +++ b/exporters/trace/zipkin/zipkin_test.go @@ -241,7 +241,6 @@ func TestExportSpans(t *testing.T) { 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", StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC), @@ -258,7 +257,10 @@ func TestExportSpans(t *testing.T) { 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}, + Parent: 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}, + }), SpanKind: trace.SpanKindServer, Name: "bar", StartTime: time.Date(2020, time.March, 11, 19, 24, 15, 0, time.UTC), diff --git a/sdk/export/trace/trace.go b/sdk/export/trace/trace.go index 28fcb368981..66e1826a2cf 100644 --- a/sdk/export/trace/trace.go +++ b/sdk/export/trace/trace.go @@ -54,20 +54,19 @@ type SpanExporter interface { // SpanSnapshot should be treated as immutable. Changes to the span from which // the SpanSnapshot was created are NOT reflected in the SpanSnapshot. type SpanSnapshot struct { - SpanContext trace.SpanContext - ParentSpanID trace.SpanID - SpanKind trace.SpanKind - Name string - StartTime time.Time + SpanContext trace.SpanContext + Parent trace.SpanContext + SpanKind trace.SpanKind + Name string + StartTime time.Time // The wall clock time of EndTime will be adjusted to always be offset // from StartTime by the duration of the span. - EndTime time.Time - Attributes []attribute.KeyValue - MessageEvents []trace.Event - Links []trace.Link - StatusCode codes.Code - StatusMessage string - HasRemoteParent bool + EndTime time.Time + Attributes []attribute.KeyValue + MessageEvents []trace.Event + Links []trace.Link + StatusCode codes.Code + StatusMessage string // DroppedAttributeCount contains dropped attributes for the span itself, events and links. DroppedAttributeCount int diff --git a/sdk/trace/span.go b/sdk/trace/span.go index cbf37769b39..15e8402e9e5 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -443,10 +443,9 @@ func (s *span) Snapshot() *export.SpanSnapshot { sd.ChildSpanCount = s.childSpanCount sd.EndTime = s.endTime - sd.HasRemoteParent = s.parent.IsRemote() sd.InstrumentationLibrary = s.instrumentationLibrary sd.Name = s.name - sd.ParentSpanID = s.parent.SpanID() + sd.Parent = s.parent sd.Resource = s.resource sd.SpanContext = s.spanContext sd.SpanKind = s.spanKind diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 1bb05b417f7..3eee3c3606f 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -58,6 +58,7 @@ func (s *storingHandler) Reset() { var ( tid trace.TraceID sid trace.SpanID + sc trace.SpanContext handler *storingHandler = &storingHandler{} @@ -68,6 +69,11 @@ var ( func init() { tid, _ = trace.TraceIDFromHex("01020304050607080102040810203040") sid, _ = trace.SpanIDFromHex("0102040810203040") + sc = trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: tid, + SpanID: sid, + TraceFlags: 0x1, + }) k1 = attribute.Key("k1") kv1 = k1.String("v1") @@ -314,18 +320,13 @@ func TestStartSpanWithParent(t *testing.T) { tr := tp.Tracer("SpanWithParent") ctx := context.Background() - 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 { + _, s1 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc), "span1-unsampled-parent1") + if err := checkChild(t, sc, s1); err != nil { t.Error(err) } - _, s2 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc1), "span2-unsampled-parent1") - if err := checkChild(t, sc1, s2); err != nil { + _, s2 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc), "span2-unsampled-parent1") + if err := checkChild(t, sc, s2); err != nil { t.Error(err) } @@ -333,12 +334,7 @@ func TestStartSpanWithParent(t *testing.T) { if err != nil { t.Error(err) } - sc2 := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - TraceFlags: 0x1, - TraceState: ts, - }) + sc2 := sc.WithTraceState(ts) _, s3 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc2), "span3-sampled-parent2") if err := checkChild(t, sc2, s3); err != nil { t.Error(err) @@ -374,14 +370,13 @@ func TestSetSpanAttributesOnStart(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Attributes: []attribute.KeyValue{ attribute.String("key1", "value1"), attribute.String("key2", "value2"), }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "StartSpanAttribute"}, } if diff := cmpDiff(got, want); diff != "" { @@ -404,13 +399,12 @@ func TestSetSpanAttributes(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Attributes: []attribute.KeyValue{ attribute.String("key1", "value1"), }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "SpanAttribute"}, } if diff := cmpDiff(got, want); diff != "" { @@ -418,8 +412,6 @@ func TestSetSpanAttributes(t *testing.T) { } } -// Test that the sampler is called for local child spans. This is verified by checking -// that the attributes set in the sampler are set on the child span. func TestSamplerAttributesLocalChildSpan(t *testing.T) { sampler := &testSampler{prefix: "span", t: t} te := NewTestExporter() @@ -433,55 +425,13 @@ func TestSamplerAttributesLocalChildSpan(t *testing.T) { span.End() got := te.Spans() - - // 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 = got[0].SpanContext.WithTraceID(tid) - got[0].ParentSpanID = sid - - checkTime(&got[0].StartTime) - checkTime(&got[0].EndTime) - - got[1].SpanContext = got[1].SpanContext.WithSpanID(trace.SpanID{}) - got[1].SpanContext = got[1].SpanContext.WithTraceID(tid) - got[1].ParentSpanID = pid - got[0].SpanContext = got[0].SpanContext.WithSpanID(trace.SpanID{}) - - checkTime(&got[1].StartTime) - checkTime(&got[1].EndTime) - - want := []*export.SpanSnapshot{ - { - SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - TraceFlags: 0x1, - }), - ParentSpanID: sid, - Name: "span1", - Attributes: []attribute.KeyValue{attribute.Int("callCount", 2)}, - SpanKind: trace.SpanKindInternal, - HasRemoteParent: false, - InstrumentationLibrary: instrumentation.Library{Name: "SpanTwo"}, - }, - { - SpanContext: trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - TraceFlags: 0x1, - }), - ParentSpanID: pid, - Name: "span0", - Attributes: []attribute.KeyValue{attribute.Int("callCount", 1)}, - SpanKind: trace.SpanKindInternal, - HasRemoteParent: false, - ChildSpanCount: 1, - InstrumentationLibrary: instrumentation.Library{Name: "SpanOne"}, - }, - } - - if diff := cmpDiff(got, want); diff != "" { - t.Errorf("SetSpanAttributesLocalChildSpan: -got +want %s", diff) - } + require.Len(t, got, 2) + // FILO order above means spanTwo <-> gotSpan0 and span <-> gotSpan1. + gotSpan0, gotSpan1 := got[0], got[1] + // Ensure sampler is called for local child spans by verifying the + // attributes set by the sampler are set on the child span. + assert.Equal(t, []attribute.KeyValue{attribute.Int("callCount", 2)}, gotSpan0.Attributes) + assert.Equal(t, []attribute.KeyValue{attribute.Int("callCount", 1)}, gotSpan1.Attributes) } func TestSetSpanAttributesOverLimit(t *testing.T) { @@ -505,14 +455,13 @@ func TestSetSpanAttributesOverLimit(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Attributes: []attribute.KeyValue{ attribute.Bool("key1", false), attribute.Int64("key4", 4), }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, DroppedAttributeCount: 1, InstrumentationLibrary: instrumentation.Library{Name: "SpanAttributesOverLimit"}, } @@ -540,13 +489,12 @@ func TestSetSpanAttributesWithInvalidKey(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Attributes: []attribute.KeyValue{ attribute.Bool("key1", false), }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, DroppedAttributeCount: 0, InstrumentationLibrary: instrumentation.Library{Name: "SpanToSetInvalidKeyOrValue"}, } @@ -585,9 +533,8 @@ func TestEvents(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", - HasRemoteParent: true, + Parent: sc.WithRemote(true), + Name: "span0", MessageEvents: []trace.Event{ {Name: "foo", Attributes: []attribute.KeyValue{k1v1}}, {Name: "bar", Attributes: []attribute.KeyValue{k2v2, k3v3}}, @@ -635,14 +582,13 @@ func TestEventsOverLimit(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", MessageEvents: []trace.Event{ {Name: "foo", Attributes: []attribute.KeyValue{k1v1}}, {Name: "bar", Attributes: []attribute.KeyValue{k2v2, k3v3}}, }, DroppedMessageEventCount: 2, - HasRemoteParent: true, SpanKind: trace.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "EventsOverLimit"}, } @@ -678,9 +624,8 @@ func TestLinks(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, + Parent: sc.WithRemote(true), Name: "span0", - HasRemoteParent: true, Links: links, SpanKind: trace.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "Links"}, @@ -720,14 +665,13 @@ func TestLinksOverLimit(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Links: []trace.Link{ {SpanContext: sc2, Attributes: []attribute.KeyValue{k2v2}}, {SpanContext: sc3, Attributes: []attribute.KeyValue{k3v3}}, }, DroppedLinkCount: 1, - HasRemoteParent: true, SpanKind: trace.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{Name: "LinksOverLimit"}, } @@ -742,11 +686,7 @@ func TestSetSpanName(t *testing.T) { ctx := context.Background() want := "SpanName-1" - ctx = trace.ContextWithRemoteSpanContext(ctx, trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - TraceFlags: 1, - })) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) _, span := tp.Tracer("SetSpanName").Start(ctx, "SpanName-1") got, err := endSpan(te, span) if err != nil { @@ -774,12 +714,11 @@ func TestSetSpanStatus(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, + Parent: sc.WithRemote(true), Name: "span0", SpanKind: trace.SpanKindInternal, StatusCode: codes.Error, StatusMessage: "Error", - HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "SpanStatus"}, } if diff := cmpDiff(got, want); diff != "" { @@ -803,12 +742,11 @@ func TestSetSpanStatusWithoutMessageWhenStatusIsNotError(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, + Parent: sc.WithRemote(true), Name: "span0", SpanKind: trace.SpanKindInternal, StatusCode: codes.Ok, StatusMessage: "", - HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "SpanStatus"}, } if diff := cmpDiff(got, want); diff != "" { @@ -823,14 +761,6 @@ func cmpDiff(x, y interface{}) string { cmp.AllowUnexported(trace.TraceState{})) } -func remoteSpanContext() 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, // given that it is a child span of p. func checkChild(t *testing.T, p trace.SpanContext, apiSpan trace.Span) error { @@ -863,10 +793,8 @@ func startSpan(tp *TracerProvider, trName string, args ...trace.SpanOption) trac // context contains TraceFlags with sampled bit set. This allows the // span to be automatically sampled. func startNamedSpan(tp *TracerProvider, trName, name string, args ...trace.SpanOption) trace.Span { - ctx := context.Background() - ctx = trace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) _, span := tp.Tracer(trName).Start( - ctx, + trace.ContextWithRemoteSpanContext(context.Background(), sc), name, args..., ) @@ -958,7 +886,7 @@ func TestStartSpanAfterEnd(t *testing.T) { ctx := context.Background() tr := tp.Tracer("SpanAfterEnd") - ctx, span0 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()), "parent") + ctx, span0 := tr.Start(trace.ContextWithRemoteSpanContext(ctx, sc), "parent") ctx1, span1 := tr.Start(ctx, "span-1") span1.End() // Start a new span with the context containing span-1 @@ -989,10 +917,10 @@ func TestStartSpanAfterEnd(t *testing.T) { 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.Parent.SpanID(), 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.Parent.SpanID(), gotSpan1.SpanContext.SpanID(); got != want { t.Errorf("span-2.ParentSpanID=%q; want %q (span1.SpanID)", got, want) } } @@ -1160,11 +1088,10 @@ func TestRecordError(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", - StatusCode: codes.Unset, - SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, + Parent: sc.WithRemote(true), + Name: "span0", + StatusCode: codes.Unset, + SpanKind: trace.SpanKindInternal, MessageEvents: []trace.Event{ { Name: errorEventName, @@ -1200,10 +1127,9 @@ func TestRecordErrorNil(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, + Parent: sc.WithRemote(true), Name: "span0", SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, StatusCode: codes.Unset, StatusMessage: "", InstrumentationLibrary: instrumentation.Library{Name: "RecordErrorNil"}, @@ -1298,13 +1224,12 @@ func TestWithResource(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", + Parent: sc.WithRemote(true), + Name: "span0", Attributes: []attribute.KeyValue{ attribute.String("key1", "value1"), }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, Resource: tc.want, InstrumentationLibrary: instrumentation.Library{Name: "WithResource"}, } @@ -1320,7 +1245,7 @@ func TestWithInstrumentationVersion(t *testing.T) { tp := NewTracerProvider(WithSyncer(te), WithResource(resource.Empty())) ctx := context.Background() - ctx = trace.ContextWithRemoteSpanContext(ctx, remoteSpanContext()) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) _, span := tp.Tracer( "WithInstrumentationVersion", trace.WithInstrumentationVersion("v0.1.0"), @@ -1335,10 +1260,9 @@ func TestWithInstrumentationVersion(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", - SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, + Parent: sc.WithRemote(true), + Name: "span0", + SpanKind: trace.SpanKindInternal, InstrumentationLibrary: instrumentation.Library{ Name: "WithInstrumentationVersion", Version: "v0.1.0", @@ -1524,9 +1448,9 @@ func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", - Attributes: nil, + Parent: sc.WithRemote(true), + Name: "span0", + Attributes: nil, MessageEvents: []trace.Event{ { Name: "test1", @@ -1544,7 +1468,6 @@ func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) { }, }, SpanKind: trace.SpanKindInternal, - HasRemoteParent: true, DroppedAttributeCount: 2, InstrumentationLibrary: instrumentation.Library{Name: "AddSpanEventWithOverLimitedAttributes"}, } @@ -1584,9 +1507,8 @@ func TestAddLinksWithMoreAttributesThanLimit(t *testing.T) { TraceID: tid, TraceFlags: 0x1, }), - ParentSpanID: sid, - Name: "span0", - HasRemoteParent: true, + Parent: sc.WithRemote(true), + Name: "span0", Links: []trace.Link{ {SpanContext: sc1, Attributes: []attribute.KeyValue{k1v1}}, {SpanContext: sc2, Attributes: []attribute.KeyValue{k2v2}},