Skip to content

Commit 260f34f

Browse files
authored
[receiver/skywalking]: fix parentSpanId lost when crossing segments (open-telemetry#21799)
In Skywalking, parentSpanId == -1 indicates that the span is [the first span within the current segment](https://github.com/apache/skywalking-data-collect-protocol/blob/0da9c8b3e111fb51c9f8854cae16d4519462ecfe/language-agent/Tracing.proto#L119), rather than within the entire trace. Leaving parentSpanId blank can cause the call relationship to be lost when crossing segments.
1 parent f709809 commit 260f34f

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Use this changelog template to create an entry for release notes.
2+
# If your change doesn't affect end users, such as a test fix or a tooling change,
3+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
4+
5+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
6+
change_type: bug_fix
7+
8+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
9+
component: receiver/skywalking
10+
11+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
12+
note: Fix the issue where `ParentSpanId` is lost when crossing segments.
13+
14+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
15+
issues: [21799]
16+
17+
# (Optional) One or more lines of additional information to render under the primary note.
18+
# These lines will be padded with 2 spaces and then inserted directly into the document.
19+
# Use pipe (|) for multiline entries.
20+
subtext:
21+

receiver/skywalkingreceiver/internal/trace/skywalkingproto_to_traces.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,13 @@ func swSpanToSpan(traceID string, segmentID string, span *agentV3.SpanObject, de
106106
// so use segmentId to convert to an unique otel-span
107107
dest.SetSpanID(segmentIDToSpanID(segmentID, uint32(span.GetSpanId())))
108108

109-
// parent spanid = -1, means(root span) no parent span in skywalking,so just make otlp's parent span id empty.
109+
// parent spanid = -1, means(root span) no parent span in current skywalking segment, so it is necessary to search for the parent segment.
110110
if span.ParentSpanId != -1 {
111111
dest.SetParentSpanID(segmentIDToSpanID(segmentID, uint32(span.GetParentSpanId())))
112+
} else if len(span.Refs) == 1 {
113+
// TODO: SegmentReference references usually have only one element, but in batch consumer case, such as in MQ or async batch process, it could be multiple.
114+
// We only handle one element for now.
115+
dest.SetParentSpanID(segmentIDToSpanID(span.Refs[0].GetParentTraceSegmentId(), uint32(span.Refs[0].GetParentSpanId())))
112116
}
113117

114118
dest.SetName(span.OperationName)

receiver/skywalkingreceiver/internal/trace/skywalkingproto_to_traces_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,41 @@ func Test_segmentIdToSpanId_Unique(t *testing.T) {
301301
assert.NotEqual(t, results[0], results[1])
302302
}
303303

304+
func Test_swSpanToSpan_ParentSpanId(t *testing.T) {
305+
type args struct {
306+
span *agentV3.SpanObject
307+
}
308+
tests := []struct {
309+
name string
310+
args args
311+
want pcommon.SpanID
312+
}{
313+
{
314+
name: "mock-sw-span-with-parent-segment",
315+
args: args{span: &agentV3.SpanObject{
316+
ParentSpanId: -1,
317+
Refs: []*agentV3.SegmentReference{{
318+
ParentTraceSegmentId: "4f2f27748b8e44ecaf18fe0347194e86.33.16560607369950066",
319+
ParentSpanId: 123,
320+
}}}},
321+
want: [8]byte{233, 196, 85, 168, 37, 66, 48, 106},
322+
},
323+
{
324+
name: "mock-sw-span-without-parent-segment",
325+
args: args{span: &agentV3.SpanObject{Refs: []*agentV3.SegmentReference{{
326+
ParentSpanId: -1,
327+
}}}},
328+
},
329+
}
330+
for _, tt := range tests {
331+
t.Run(tt.name, func(t *testing.T) {
332+
dest := ptrace.NewSpan()
333+
swSpanToSpan("de5980b8-fce3-4a37-aab9-b4ac3af7eedd", "", tt.args.span, dest)
334+
assert.Equal(t, tt.want, dest.ParentSpanID())
335+
})
336+
}
337+
}
338+
304339
func generateTracesOneEmptyResourceSpans() ptrace.Span {
305340
td := ptrace.NewTraces()
306341
resourceSpan := td.ResourceSpans().AppendEmpty()

0 commit comments

Comments
 (0)