From a0ca95ea7c2210f47a92e935f39fac188c1d59cb Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 13 Dec 2024 20:58:09 -0500 Subject: [PATCH 01/13] Implement OTEL Tag Adjuster To Operate on OTLP Data Model Signed-off-by: Mahad Zaryab --- .../app/querysvc/adjuster/otelattribute.go | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 cmd/query/app/querysvc/adjuster/otelattribute.go diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go new file mode 100644 index 00000000000..858ff7c6182 --- /dev/null +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -0,0 +1,57 @@ +// Copyright (c) 2023 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package adjuster + +import ( + "github.com/jaegertracing/jaeger/pkg/otelsemconv" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/ptrace" +) + +var otelLibraryKeys = map[string]struct{}{ + string(otelsemconv.TelemetrySDKLanguageKey): {}, + string(otelsemconv.TelemetrySDKNameKey): {}, + string(otelsemconv.TelemetrySDKVersionKey): {}, + string(otelsemconv.TelemetryDistroNameKey): {}, + string(otelsemconv.TelemetryDistroVersionKey): {}, +} + +// OTELAttribute creates an adjuster that removes the OpenTelemetry library attributes +// from spans and adds them to the attributes of a resource. +func OTELAttribute() Adjuster { + return Func(func(traces ptrace.Traces) (ptrace.Traces, error) { + adjuster := otelAttributeAdjuster{} + resourceSpans := traces.ResourceSpans() + for i := 0; i < resourceSpans.Len(); i++ { + rs := resourceSpans.At(i) + resource := rs.Resource() + scopeSpans := rs.ScopeSpans() + for j := 0; j < scopeSpans.Len(); j++ { + ss := scopeSpans.At(j) + spans := ss.Spans() + for k := 0; k < spans.Len(); k++ { + span := spans.At(k) + adjuster.adjust(span, resource) + } + } + } + return traces, nil + }) +} + +type otelAttributeAdjuster struct{} + +func (o otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) { + replace := make(map[string]pcommon.Value) + span.Attributes().Range(func(k string, v pcommon.Value) bool { + if _, ok := otelLibraryKeys[k]; ok { + replace[k] = v + } + return true + }) + for k, v := range replace { + v.CopyTo(resource.Attributes().PutEmpty(k)) + span.Attributes().Remove(k) + } +} From 1aee1d10416f5104766dc7a8480403f47bb51b02 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 13 Dec 2024 20:59:09 -0500 Subject: [PATCH 02/13] Add Unit Tests Signed-off-by: Mahad Zaryab --- .../querysvc/adjuster/otelattribute_test.go | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 cmd/query/app/querysvc/adjuster/otelattribute_test.go diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go new file mode 100644 index 00000000000..205b1606104 --- /dev/null +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -0,0 +1,78 @@ +// Copyright (c) 2023 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package adjuster + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/ptrace" + + "github.com/jaegertracing/jaeger/pkg/otelsemconv" +) + +func TestOTELAttributeAdjuster(t *testing.T) { + tests := []struct { + name string + input ptrace.Traces + expected ptrace.Traces + }{ + { + name: "span with otel library attributes", + input: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") + span.Attributes().PutStr("another_key", "another_value") + return traces + }(), + expected: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr("another_key", "another_value") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") + return traces + }(), + }, + { + name: "span without otel library attributes", + input: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + return traces + }(), + expected: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + return traces + }(), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + adjuster := OTELAttribute() + result, err := adjuster.Adjust(test.input) + require.NoError(t, err) + assert.Equal(t, test.expected, result) + }) + } +} From e620684512a23f40531330fb7bd323c19fc011f7 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 13 Dec 2024 21:04:19 -0500 Subject: [PATCH 03/13] Fix Linter Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/adjuster/otelattribute.go | 7 ++++--- cmd/query/app/querysvc/adjuster/otelattribute_test.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index 858ff7c6182..dec37219c34 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -1,12 +1,13 @@ -// Copyright (c) 2023 The Jaeger Authors. +// Copyright (c) 2024 The Jaeger Authors. // SPDX-License-Identifier: Apache-2.0 package adjuster import ( - "github.com/jaegertracing/jaeger/pkg/otelsemconv" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" + + "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) var otelLibraryKeys = map[string]struct{}{ @@ -42,7 +43,7 @@ func OTELAttribute() Adjuster { type otelAttributeAdjuster struct{} -func (o otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) { +func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) { replace := make(map[string]pcommon.Value) span.Attributes().Range(func(k string, v pcommon.Value) bool { if _, ok := otelLibraryKeys[k]; ok { diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index 205b1606104..028b2f901e6 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2023 The Jaeger Authors. +// Copyright (c) 2024 The Jaeger Authors. // SPDX-License-Identifier: Apache-2.0 package adjuster From 0c812d9c0c8e0277081c5661dea28d331d1bc7cf Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 13:35:53 -0500 Subject: [PATCH 04/13] Add Warning If There Is a Conflicting Value Signed-off-by: Mahad Zaryab --- .../app/querysvc/adjuster/otelattribute.go | 13 +++++++-- .../querysvc/adjuster/otelattribute_test.go | 28 ++++++++++++++++--- cmd/query/app/querysvc/adjuster/warning.go | 5 ++++ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 cmd/query/app/querysvc/adjuster/warning.go diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index dec37219c34..8cae02bb131 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -4,6 +4,8 @@ package adjuster import ( + "fmt" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" @@ -52,7 +54,14 @@ func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) return true }) for k, v := range replace { - v.CopyTo(resource.Attributes().PutEmpty(k)) - span.Attributes().Remove(k) + if existing, ok := resource.Attributes().Get(k); ok { + if existing.AsRaw() != v.AsRaw() { + span.Attributes().PutStr(adjusterWarningAttribute, fmt.Sprintf("conflicting attribute values for %s", k)) + continue + } + } else { + v.CopyTo(resource.Attributes().PutEmpty(k)) + span.Attributes().Remove(k) + } } } diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index 028b2f901e6..fe75425943b 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -6,11 +6,10 @@ package adjuster import ( "testing" + "github.com/jaegertracing/jaeger/pkg/otelsemconv" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/ptrace" - - "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) func TestOTELAttributeAdjuster(t *testing.T) { @@ -65,14 +64,35 @@ func TestOTELAttributeAdjuster(t *testing.T) { return traces }(), }, + { + name: "span with conflicting otel library attributes", + input: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") + return traces + }(), + expected: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") + span.Attributes().PutStr("jaeger.adjuster.warning", "conflicting attribute values for telemetry.sdk.language") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + return traces + }(), + }, } - for _, test := range tests { t.Run(test.name, func(t *testing.T) { adjuster := OTELAttribute() result, err := adjuster.Adjust(test.input) require.NoError(t, err) - assert.Equal(t, test.expected, result) + assert.EqualValues(t, test.expected, result) }) } } diff --git a/cmd/query/app/querysvc/adjuster/warning.go b/cmd/query/app/querysvc/adjuster/warning.go new file mode 100644 index 00000000000..1490e4a24a3 --- /dev/null +++ b/cmd/query/app/querysvc/adjuster/warning.go @@ -0,0 +1,5 @@ +package adjuster + +const ( + adjusterWarningAttribute = "jaeger.adjuster.warning" +) From 1fe8893cc091269fe075a1cc85a91788352a9ee0 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 13:37:34 -0500 Subject: [PATCH 05/13] Remove Continue Block Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/adjuster/otelattribute.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index 8cae02bb131..e784830caa6 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -57,7 +57,6 @@ func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) if existing, ok := resource.Attributes().Get(k); ok { if existing.AsRaw() != v.AsRaw() { span.Attributes().PutStr(adjusterWarningAttribute, fmt.Sprintf("conflicting attribute values for %s", k)) - continue } } else { v.CopyTo(resource.Attributes().PutEmpty(k)) From adfb793e5d96017db6617a6939b461975cfe0a7f Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 13:44:10 -0500 Subject: [PATCH 06/13] Remove From Span Attributes Signed-off-by: Mahad Zaryab --- .../app/querysvc/adjuster/otelattribute.go | 2 +- .../querysvc/adjuster/otelattribute_test.go | 25 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index e784830caa6..40ce2c5b4d9 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -60,7 +60,7 @@ func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) } } else { v.CopyTo(resource.Attributes().PutEmpty(k)) - span.Attributes().Remove(k) } + span.Attributes().Remove(k) } } diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index fe75425943b..60f7744e9d5 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -80,17 +80,38 @@ func TestOTELAttributeAdjuster(t *testing.T) { rs := traces.ResourceSpans().AppendEmpty() span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") span.Attributes().PutStr("jaeger.adjuster.warning", "conflicting attribute values for telemetry.sdk.language") rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") return traces }(), }, + { + name: "span with non-conflicting otel library attributes", + input: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + return traces + }(), + expected: func() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + return traces + }(), + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { adjuster := OTELAttribute() - result, err := adjuster.Adjust(test.input) + input := ptrace.NewTraces() + test.input.CopyTo(input) + result, err := adjuster.Adjust(input) require.NoError(t, err) assert.EqualValues(t, test.expected, result) }) From 2462d69942b4fed8a16fb80683ae37801b3b5d9b Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 13:44:25 -0500 Subject: [PATCH 07/13] Fix Linting Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/adjuster/otelattribute_test.go | 3 ++- cmd/query/app/querysvc/adjuster/warning.go | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index 60f7744e9d5..1182e0bc012 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -6,10 +6,11 @@ package adjuster import ( "testing" - "github.com/jaegertracing/jaeger/pkg/otelsemconv" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/ptrace" + + "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) func TestOTELAttributeAdjuster(t *testing.T) { diff --git a/cmd/query/app/querysvc/adjuster/warning.go b/cmd/query/app/querysvc/adjuster/warning.go index 1490e4a24a3..ad8e785a78d 100644 --- a/cmd/query/app/querysvc/adjuster/warning.go +++ b/cmd/query/app/querysvc/adjuster/warning.go @@ -1,3 +1,6 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package adjuster const ( From fa4fc437d692dc479a61120503096fb1f16335cb Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 13:54:16 -0500 Subject: [PATCH 08/13] Fix Lint Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/adjuster/otelattribute.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index 40ce2c5b4d9..89a7f48fb31 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -4,8 +4,6 @@ package adjuster import ( - "fmt" - "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" @@ -56,7 +54,7 @@ func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) for k, v := range replace { if existing, ok := resource.Attributes().Get(k); ok { if existing.AsRaw() != v.AsRaw() { - span.Attributes().PutStr(adjusterWarningAttribute, fmt.Sprintf("conflicting attribute values for %s", k)) + span.Attributes().PutStr(adjusterWarningAttribute, "conflicting attribute values for "+k) } } else { v.CopyTo(resource.Attributes().PutEmpty(k)) From 2b94c0d51778fd9792e82e868e862bc440e33c85 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 14:36:34 -0500 Subject: [PATCH 09/13] Fix Unit Tests And Create Helper For Adding Warning Signed-off-by: Mahad Zaryab --- .../app/querysvc/adjuster/otelattribute.go | 48 ++-- .../querysvc/adjuster/otelattribute_test.go | 223 +++++++++--------- cmd/query/app/querysvc/adjuster/warning.go | 15 ++ 3 files changed, 158 insertions(+), 128 deletions(-) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/otelattribute.go index 89a7f48fb31..e3f74cda877 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute.go @@ -18,32 +18,33 @@ var otelLibraryKeys = map[string]struct{}{ string(otelsemconv.TelemetryDistroVersionKey): {}, } -// OTELAttribute creates an adjuster that removes the OpenTelemetry library attributes -// from spans and adds them to the attributes of a resource. -func OTELAttribute() Adjuster { - return Func(func(traces ptrace.Traces) (ptrace.Traces, error) { - adjuster := otelAttributeAdjuster{} - resourceSpans := traces.ResourceSpans() - for i := 0; i < resourceSpans.Len(); i++ { - rs := resourceSpans.At(i) - resource := rs.Resource() - scopeSpans := rs.ScopeSpans() - for j := 0; j < scopeSpans.Len(); j++ { - ss := scopeSpans.At(j) - spans := ss.Spans() - for k := 0; k < spans.Len(); k++ { - span := spans.At(k) - adjuster.adjust(span, resource) - } +// OTELAttribute creates an adjuster that moves the OpenTelemetry library +// attributes from spans to the parent resource. +func OTELAttribute() OTELAttributeAdjuster { + return OTELAttributeAdjuster{} +} + +type OTELAttributeAdjuster struct{} + +func (o OTELAttributeAdjuster) Adjust(traces ptrace.Traces) (ptrace.Traces, error) { + resourceSpans := traces.ResourceSpans() + for i := 0; i < resourceSpans.Len(); i++ { + rs := resourceSpans.At(i) + resource := rs.Resource() + scopeSpans := rs.ScopeSpans() + for j := 0; j < scopeSpans.Len(); j++ { + ss := scopeSpans.At(j) + spans := ss.Spans() + for k := 0; k < spans.Len(); k++ { + span := spans.At(k) + o.moveAttributes(span, resource) } } - return traces, nil - }) + } + return traces, nil } -type otelAttributeAdjuster struct{} - -func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) { +func (OTELAttributeAdjuster) moveAttributes(span ptrace.Span, resource pcommon.Resource) { replace := make(map[string]pcommon.Value) span.Attributes().Range(func(k string, v pcommon.Value) bool { if _, ok := otelLibraryKeys[k]; ok { @@ -54,7 +55,8 @@ func (otelAttributeAdjuster) adjust(span ptrace.Span, resource pcommon.Resource) for k, v := range replace { if existing, ok := resource.Attributes().Get(k); ok { if existing.AsRaw() != v.AsRaw() { - span.Attributes().PutStr(adjusterWarningAttribute, "conflicting attribute values for "+k) + warning := "conflicting attribute values for " + k + addWarning(span, warning) } } else { v.CopyTo(resource.Attributes().PutEmpty(k)) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index 1182e0bc012..791112a1a73 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -6,115 +6,128 @@ package adjuster import ( "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/ptrace" "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) -func TestOTELAttributeAdjuster(t *testing.T) { - tests := []struct { - name string - input ptrace.Traces - expected ptrace.Traces - }{ - { - name: "span with otel library attributes", - input: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") - span.Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") - span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") - span.Attributes().PutStr("another_key", "another_value") - return traces - }(), - expected: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr("another_key", "another_value") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") - return traces - }(), - }, - { - name: "span without otel library attributes", - input: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - return traces - }(), - expected: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - return traces - }(), - }, - { - name: "span with conflicting otel library attributes", - input: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") - return traces - }(), - expected: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr("jaeger.adjuster.warning", "conflicting attribute values for telemetry.sdk.language") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - return traces - }(), - }, - { - name: "span with non-conflicting otel library attributes", - input: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - return traces - }(), - expected: func() ptrace.Traces { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - return traces - }(), - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - adjuster := OTELAttribute() - input := ptrace.NewTraces() - test.input.CopyTo(input) - result, err := adjuster.Adjust(input) - require.NoError(t, err) - assert.EqualValues(t, test.expected, result) - }) - } +func TestOTELAttributeAdjuster_SpanWithOTELLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") + span.Attributes().PutStr("another_key", "another_value") + + adjuster := OTELAttribute() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 2, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + val, ok = resultSpanAttributes.Get("another_key") + require.True(t, ok) + require.Equal(t, "another_value", val.Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKNameKey)) + require.True(t, ok) + require.Equal(t, "opentelemetry", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKVersionKey)) + require.True(t, ok) + require.Equal(t, "1.27.0", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroNameKey)) + require.True(t, ok) + require.Equal(t, "opentelemetry", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroVersionKey)) + require.True(t, ok) + require.Equal(t, "blah", val.Str()) +} + +func TestOTELAttributeAdjuster_SpanWithoutOTELLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + + adjuster := OTELAttribute() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 1, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) +} + +func TestOTELAttributeAdjuster_SpanWithConflictingOTELLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") + + adjuster := OTELAttribute() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 2, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + val, ok = resultSpanAttributes.Get("jaeger.adjuster.warning") + require.True(t, ok) + warnings := val.Slice() + require.Equal(t, 1, warnings.Len()) + require.Equal(t, "conflicting attribute values for telemetry.sdk.language", warnings.At(0).Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) +} + +func TestOTELAttributeAdjuster_SpanWithNonConflictingOTELLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + + adjuster := OTELAttribute() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 1, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) } diff --git a/cmd/query/app/querysvc/adjuster/warning.go b/cmd/query/app/querysvc/adjuster/warning.go index ad8e785a78d..e7f1331bfab 100644 --- a/cmd/query/app/querysvc/adjuster/warning.go +++ b/cmd/query/app/querysvc/adjuster/warning.go @@ -3,6 +3,21 @@ package adjuster +import ( + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/ptrace" +) + const ( adjusterWarningAttribute = "jaeger.adjuster.warning" ) + +func addWarning(span ptrace.Span, warning string) { + var warnings pcommon.Slice + if currWarnings, ok := span.Attributes().Get(adjusterWarningAttribute); ok { + warnings = currWarnings.Slice() + } else { + warnings = span.Attributes().PutEmptySlice(adjusterWarningAttribute) + } + warnings.AppendEmpty().SetStr(warning) +} From c6e87f674a673600e87c406bf2ae95c1f654e385 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 14:40:26 -0500 Subject: [PATCH 10/13] Add Unit Tests For addWarning Helper Signed-off-by: Mahad Zaryab --- .../app/querysvc/adjuster/warning_test.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 cmd/query/app/querysvc/adjuster/warning_test.go diff --git a/cmd/query/app/querysvc/adjuster/warning_test.go b/cmd/query/app/querysvc/adjuster/warning_test.go new file mode 100644 index 00000000000..fb89195116b --- /dev/null +++ b/cmd/query/app/querysvc/adjuster/warning_test.go @@ -0,0 +1,55 @@ +package adjuster + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/ptrace" +) + +func TestAddWarning(t *testing.T) { + tests := []struct { + name string + existing []string + newWarn string + expected []string + }{ + { + name: "add to nil warnings", + existing: nil, + newWarn: "new warning", + expected: []string{"new warning"}, + }, + { + name: "add to empty warnings", + existing: []string{}, + newWarn: "new warning", + expected: []string{"new warning"}, + }, + { + name: "add to existing warnings", + existing: []string{"existing warning 1", "existing warning 2"}, + newWarn: "new warning", + expected: []string{"existing warning 1", "existing warning 2", "new warning"}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + span := ptrace.NewSpan() + attrs := span.Attributes() + if test.existing != nil { + warnings := attrs.PutEmptySlice("jaeger.adjuster.warning") + for _, warn := range test.existing { + warnings.AppendEmpty().SetStr(warn) + } + } + addWarning(span, test.newWarn) + warnings, ok := attrs.Get("jaeger.adjuster.warning") + assert.True(t, ok) + assert.Equal(t, len(test.expected), warnings.Slice().Len()) + for i, expectedWarn := range test.expected { + assert.Equal(t, expectedWarn, warnings.Slice().At(i).Str()) + } + }) + } +} From f13cd765f71c009e7955334033ee2b94e3eb7f70 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 14:49:29 -0500 Subject: [PATCH 11/13] Run Formatter Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/adjuster/warning_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/query/app/querysvc/adjuster/warning_test.go b/cmd/query/app/querysvc/adjuster/warning_test.go index fb89195116b..209d794e639 100644 --- a/cmd/query/app/querysvc/adjuster/warning_test.go +++ b/cmd/query/app/querysvc/adjuster/warning_test.go @@ -1,3 +1,6 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + package adjuster import ( From 9ccc4f81277fc22fd6946686ab1cdf828509ab2a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 16:33:53 -0500 Subject: [PATCH 12/13] Address Feedback Signed-off-by: Mahad Zaryab --- .../querysvc/adjuster/otelattribute_test.go | 23 +++++++------ ...otelattribute.go => resourceattributes.go} | 32 +++++++++---------- ...age_test.go => resourceattributes_test.go} | 0 3 files changed, 30 insertions(+), 25 deletions(-) rename cmd/query/app/querysvc/adjuster/{otelattribute.go => resourceattributes.go} (57%) rename cmd/query/app/querysvc/adjuster/{package_test.go => resourceattributes_test.go} (100%) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go index 791112a1a73..40901298f4e 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ b/cmd/query/app/querysvc/adjuster/otelattribute_test.go @@ -12,7 +12,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) -func TestOTELAttributeAdjuster_SpanWithOTELLibraryAttributes(t *testing.T) { +func TestResourceAttributesAdjuster_SpanWithLibraryAttributes(t *testing.T) { traces := ptrace.NewTraces() rs := traces.ResourceSpans().AppendEmpty() span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() @@ -24,7 +24,7 @@ func TestOTELAttributeAdjuster_SpanWithOTELLibraryAttributes(t *testing.T) { span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") span.Attributes().PutStr("another_key", "another_value") - adjuster := OTELAttribute() + adjuster := ResourceAttributes() result, err := adjuster.Adjust(traces) require.NoError(t, err) @@ -61,13 +61,13 @@ func TestOTELAttributeAdjuster_SpanWithOTELLibraryAttributes(t *testing.T) { require.Equal(t, "blah", val.Str()) } -func TestOTELAttributeAdjuster_SpanWithoutOTELLibraryAttributes(t *testing.T) { +func TestResourceAttributesAdjuster_SpanWithoutLibraryAttributes(t *testing.T) { traces := ptrace.NewTraces() rs := traces.ResourceSpans().AppendEmpty() span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() span.Attributes().PutStr("random_key", "random_value") - adjuster := OTELAttribute() + adjuster := ResourceAttributes() result, err := adjuster.Adjust(traces) require.NoError(t, err) @@ -78,7 +78,7 @@ func TestOTELAttributeAdjuster_SpanWithoutOTELLibraryAttributes(t *testing.T) { require.Equal(t, "random_value", val.Str()) } -func TestOTELAttributeAdjuster_SpanWithConflictingOTELLibraryAttributes(t *testing.T) { +func TestResourceAttributesAdjuster_SpanWithConflictingLibraryAttributes(t *testing.T) { traces := ptrace.NewTraces() rs := traces.ResourceSpans().AppendEmpty() rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") @@ -86,16 +86,21 @@ func TestOTELAttributeAdjuster_SpanWithConflictingOTELLibraryAttributes(t *testi span.Attributes().PutStr("random_key", "random_value") span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") - adjuster := OTELAttribute() + adjuster := ResourceAttributes() result, err := adjuster.Adjust(traces) require.NoError(t, err) resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() - require.Equal(t, 2, resultSpanAttributes.Len()) + require.Equal(t, 3, resultSpanAttributes.Len()) val, ok := resultSpanAttributes.Get("random_key") require.True(t, ok) require.Equal(t, "random_value", val.Str()) + // value remains in the span + val, ok = resultSpanAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Java", val.Str()) + val, ok = resultSpanAttributes.Get("jaeger.adjuster.warning") require.True(t, ok) warnings := val.Slice() @@ -108,7 +113,7 @@ func TestOTELAttributeAdjuster_SpanWithConflictingOTELLibraryAttributes(t *testi require.Equal(t, "Go", val.Str()) } -func TestOTELAttributeAdjuster_SpanWithNonConflictingOTELLibraryAttributes(t *testing.T) { +func TestResourceAttributesAdjuster_SpanWithNonConflictingLibraryAttributes(t *testing.T) { traces := ptrace.NewTraces() rs := traces.ResourceSpans().AppendEmpty() rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") @@ -116,7 +121,7 @@ func TestOTELAttributeAdjuster_SpanWithNonConflictingOTELLibraryAttributes(t *te span.Attributes().PutStr("random_key", "random_value") span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - adjuster := OTELAttribute() + adjuster := ResourceAttributes() result, err := adjuster.Adjust(traces) require.NoError(t, err) diff --git a/cmd/query/app/querysvc/adjuster/otelattribute.go b/cmd/query/app/querysvc/adjuster/resourceattributes.go similarity index 57% rename from cmd/query/app/querysvc/adjuster/otelattribute.go rename to cmd/query/app/querysvc/adjuster/resourceattributes.go index e3f74cda877..a068cb15fb5 100644 --- a/cmd/query/app/querysvc/adjuster/otelattribute.go +++ b/cmd/query/app/querysvc/adjuster/resourceattributes.go @@ -10,7 +10,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) -var otelLibraryKeys = map[string]struct{}{ +var libraryKeys = map[string]struct{}{ string(otelsemconv.TelemetrySDKLanguageKey): {}, string(otelsemconv.TelemetrySDKNameKey): {}, string(otelsemconv.TelemetrySDKVersionKey): {}, @@ -18,15 +18,17 @@ var otelLibraryKeys = map[string]struct{}{ string(otelsemconv.TelemetryDistroVersionKey): {}, } -// OTELAttribute creates an adjuster that moves the OpenTelemetry library -// attributes from spans to the parent resource. -func OTELAttribute() OTELAttributeAdjuster { - return OTELAttributeAdjuster{} +// ResourceAttributes creates an adjuster that moves the OpenTelemetry library +// attributes from spans to the parent resource so that the UI can +// display them separately under Process. +// https://github.com/jaegertracing/jaeger/issues/4534 +func ResourceAttributes() ResourceAttributesAdjuster { + return ResourceAttributesAdjuster{} } -type OTELAttributeAdjuster struct{} +type ResourceAttributesAdjuster struct{} -func (o OTELAttributeAdjuster) Adjust(traces ptrace.Traces) (ptrace.Traces, error) { +func (o ResourceAttributesAdjuster) Adjust(traces ptrace.Traces) (ptrace.Traces, error) { resourceSpans := traces.ResourceSpans() for i := 0; i < resourceSpans.Len(); i++ { rs := resourceSpans.At(i) @@ -44,23 +46,21 @@ func (o OTELAttributeAdjuster) Adjust(traces ptrace.Traces) (ptrace.Traces, erro return traces, nil } -func (OTELAttributeAdjuster) moveAttributes(span ptrace.Span, resource pcommon.Resource) { +func (ResourceAttributesAdjuster) moveAttributes(span ptrace.Span, resource pcommon.Resource) { replace := make(map[string]pcommon.Value) span.Attributes().Range(func(k string, v pcommon.Value) bool { - if _, ok := otelLibraryKeys[k]; ok { + if _, ok := libraryKeys[k]; ok { replace[k] = v } return true }) for k, v := range replace { - if existing, ok := resource.Attributes().Get(k); ok { - if existing.AsRaw() != v.AsRaw() { - warning := "conflicting attribute values for " + k - addWarning(span, warning) - } - } else { - v.CopyTo(resource.Attributes().PutEmpty(k)) + existing, ok := resource.Attributes().Get(k) + if ok && existing.AsRaw() != v.AsRaw() { + addWarning(span, "conflicting attribute values for "+k) + continue } + v.CopyTo(resource.Attributes().PutEmpty(k)) span.Attributes().Remove(k) } } diff --git a/cmd/query/app/querysvc/adjuster/package_test.go b/cmd/query/app/querysvc/adjuster/resourceattributes_test.go similarity index 100% rename from cmd/query/app/querysvc/adjuster/package_test.go rename to cmd/query/app/querysvc/adjuster/resourceattributes_test.go From b92c7e63394ad477c10f604ece5718d562cf4d5a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 14 Dec 2024 17:03:11 -0500 Subject: [PATCH 13/13] Address Feedback Signed-off-by: Mahad Zaryab --- .../querysvc/adjuster/otelattribute_test.go | 138 ------------------ .../app/querysvc/adjuster/package_test.go | 14 ++ .../querysvc/adjuster/resourceattributes.go | 2 +- .../adjuster/resourceattributes_test.go | 130 ++++++++++++++++- 4 files changed, 142 insertions(+), 142 deletions(-) delete mode 100644 cmd/query/app/querysvc/adjuster/otelattribute_test.go create mode 100644 cmd/query/app/querysvc/adjuster/package_test.go diff --git a/cmd/query/app/querysvc/adjuster/otelattribute_test.go b/cmd/query/app/querysvc/adjuster/otelattribute_test.go deleted file mode 100644 index 40901298f4e..00000000000 --- a/cmd/query/app/querysvc/adjuster/otelattribute_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2024 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package adjuster - -import ( - "testing" - - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/pdata/ptrace" - - "github.com/jaegertracing/jaeger/pkg/otelsemconv" -) - -func TestResourceAttributesAdjuster_SpanWithLibraryAttributes(t *testing.T) { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") - span.Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") - span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") - span.Attributes().PutStr("another_key", "another_value") - - adjuster := ResourceAttributes() - result, err := adjuster.Adjust(traces) - require.NoError(t, err) - - resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() - require.Equal(t, 2, resultSpanAttributes.Len()) - val, ok := resultSpanAttributes.Get("random_key") - require.True(t, ok) - require.Equal(t, "random_value", val.Str()) - - val, ok = resultSpanAttributes.Get("another_key") - require.True(t, ok) - require.Equal(t, "another_value", val.Str()) - - resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() - - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) - require.True(t, ok) - require.Equal(t, "Go", val.Str()) - - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKNameKey)) - require.True(t, ok) - require.Equal(t, "opentelemetry", val.Str()) - - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKVersionKey)) - require.True(t, ok) - require.Equal(t, "1.27.0", val.Str()) - - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroNameKey)) - require.True(t, ok) - require.Equal(t, "opentelemetry", val.Str()) - - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroVersionKey)) - require.True(t, ok) - require.Equal(t, "blah", val.Str()) -} - -func TestResourceAttributesAdjuster_SpanWithoutLibraryAttributes(t *testing.T) { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - - adjuster := ResourceAttributes() - result, err := adjuster.Adjust(traces) - require.NoError(t, err) - - resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() - require.Equal(t, 1, resultSpanAttributes.Len()) - val, ok := resultSpanAttributes.Get("random_key") - require.True(t, ok) - require.Equal(t, "random_value", val.Str()) -} - -func TestResourceAttributesAdjuster_SpanWithConflictingLibraryAttributes(t *testing.T) { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") - - adjuster := ResourceAttributes() - result, err := adjuster.Adjust(traces) - require.NoError(t, err) - - resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() - require.Equal(t, 3, resultSpanAttributes.Len()) - val, ok := resultSpanAttributes.Get("random_key") - require.True(t, ok) - require.Equal(t, "random_value", val.Str()) - - // value remains in the span - val, ok = resultSpanAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) - require.True(t, ok) - require.Equal(t, "Java", val.Str()) - - val, ok = resultSpanAttributes.Get("jaeger.adjuster.warning") - require.True(t, ok) - warnings := val.Slice() - require.Equal(t, 1, warnings.Len()) - require.Equal(t, "conflicting attribute values for telemetry.sdk.language", warnings.At(0).Str()) - - resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) - require.True(t, ok) - require.Equal(t, "Go", val.Str()) -} - -func TestResourceAttributesAdjuster_SpanWithNonConflictingLibraryAttributes(t *testing.T) { - traces := ptrace.NewTraces() - rs := traces.ResourceSpans().AppendEmpty() - rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() - span.Attributes().PutStr("random_key", "random_value") - span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") - - adjuster := ResourceAttributes() - result, err := adjuster.Adjust(traces) - require.NoError(t, err) - - resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() - require.Equal(t, 1, resultSpanAttributes.Len()) - val, ok := resultSpanAttributes.Get("random_key") - require.True(t, ok) - require.Equal(t, "random_value", val.Str()) - - resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() - val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) - require.True(t, ok) - require.Equal(t, "Go", val.Str()) -} diff --git a/cmd/query/app/querysvc/adjuster/package_test.go b/cmd/query/app/querysvc/adjuster/package_test.go new file mode 100644 index 00000000000..d5e9585aa5c --- /dev/null +++ b/cmd/query/app/querysvc/adjuster/package_test.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package adjuster + +import ( + "testing" + + "github.com/jaegertracing/jaeger/pkg/testutils" +) + +func TestMain(m *testing.M) { + testutils.VerifyGoLeaks(m) +} diff --git a/cmd/query/app/querysvc/adjuster/resourceattributes.go b/cmd/query/app/querysvc/adjuster/resourceattributes.go index a068cb15fb5..0c3cd6d512f 100644 --- a/cmd/query/app/querysvc/adjuster/resourceattributes.go +++ b/cmd/query/app/querysvc/adjuster/resourceattributes.go @@ -57,7 +57,7 @@ func (ResourceAttributesAdjuster) moveAttributes(span ptrace.Span, resource pcom for k, v := range replace { existing, ok := resource.Attributes().Get(k) if ok && existing.AsRaw() != v.AsRaw() { - addWarning(span, "conflicting attribute values for "+k) + addWarning(span, "conflicting values between Span and Resource for attribute "+k) continue } v.CopyTo(resource.Attributes().PutEmpty(k)) diff --git a/cmd/query/app/querysvc/adjuster/resourceattributes_test.go b/cmd/query/app/querysvc/adjuster/resourceattributes_test.go index d5e9585aa5c..0d445671ad0 100644 --- a/cmd/query/app/querysvc/adjuster/resourceattributes_test.go +++ b/cmd/query/app/querysvc/adjuster/resourceattributes_test.go @@ -6,9 +6,133 @@ package adjuster import ( "testing" - "github.com/jaegertracing/jaeger/pkg/testutils" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/ptrace" + + "github.com/jaegertracing/jaeger/pkg/otelsemconv" ) -func TestMain(m *testing.M) { - testutils.VerifyGoLeaks(m) +func TestResourceAttributesAdjuster_SpanWithLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKVersionKey), "1.27.0") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroNameKey), "opentelemetry") + span.Attributes().PutStr(string(otelsemconv.TelemetryDistroVersionKey), "blah") + span.Attributes().PutStr("another_key", "another_value") + + adjuster := ResourceAttributes() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 2, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + val, ok = resultSpanAttributes.Get("another_key") + require.True(t, ok) + require.Equal(t, "another_value", val.Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKNameKey)) + require.True(t, ok) + require.Equal(t, "opentelemetry", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKVersionKey)) + require.True(t, ok) + require.Equal(t, "1.27.0", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroNameKey)) + require.True(t, ok) + require.Equal(t, "opentelemetry", val.Str()) + + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetryDistroVersionKey)) + require.True(t, ok) + require.Equal(t, "blah", val.Str()) +} + +func TestResourceAttributesAdjuster_SpanWithoutLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + + adjuster := ResourceAttributes() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 1, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) +} + +func TestResourceAttributesAdjuster_SpanWithConflictingLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Java") + + adjuster := ResourceAttributes() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 3, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + // value remains in the span + val, ok = resultSpanAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Java", val.Str()) + + val, ok = resultSpanAttributes.Get("jaeger.adjuster.warning") + require.True(t, ok) + warnings := val.Slice() + require.Equal(t, 1, warnings.Len()) + require.Equal(t, "conflicting values between Span and Resource for attribute telemetry.sdk.language", warnings.At(0).Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) +} + +func TestResourceAttributesAdjuster_SpanWithNonConflictingLibraryAttributes(t *testing.T) { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("random_key", "random_value") + span.Attributes().PutStr(string(otelsemconv.TelemetrySDKLanguageKey), "Go") + + adjuster := ResourceAttributes() + result, err := adjuster.Adjust(traces) + require.NoError(t, err) + + resultSpanAttributes := result.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Attributes() + require.Equal(t, 1, resultSpanAttributes.Len()) + val, ok := resultSpanAttributes.Get("random_key") + require.True(t, ok) + require.Equal(t, "random_value", val.Str()) + + resultResourceAttributes := result.ResourceSpans().At(0).Resource().Attributes() + val, ok = resultResourceAttributes.Get(string(otelsemconv.TelemetrySDKLanguageKey)) + require.True(t, ok) + require.Equal(t, "Go", val.Str()) }