diff --git a/.chloggen/fix_awsxrayexporter_trace.yaml b/.chloggen/fix_awsxrayexporter_trace.yaml new file mode 100644 index 0000000000000..1485f76d0b6d3 --- /dev/null +++ b/.chloggen/fix_awsxrayexporter_trace.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: awsxrayexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Fix incorrect http url generation in trace segment when url.path is present + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [40809] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/exporter/awsxrayexporter/internal/translator/http.go b/exporter/awsxrayexporter/internal/translator/http.go index 43ab59c958e78..32b0e284df806 100644 --- a/exporter/awsxrayexporter/internal/translator/http.go +++ b/exporter/awsxrayexporter/internal/translator/http.go @@ -6,6 +6,7 @@ package translator // import "github.com/open-telemetry/opentelemetry-collector- import ( "net" "strconv" + "strings" "github.com/aws/aws-sdk-go-v2/aws" "go.opentelemetry.io/collector/pdata/pcommon" @@ -59,8 +60,8 @@ func makeHTTP(span ptrace.Span) (map[string]pcommon.Value, *awsxray.HTTPData) { urlParts[key] = value.Str() hasHTTP = true hasHTTPRequestURLAttributes = true - case string(conventionsv112.HTTPTargetKey), string(conventions.URLQueryKey): - urlParts[string(conventionsv112.HTTPTargetKey)] = value.Str() + case string(conventionsv112.HTTPTargetKey): + urlParts[key] = value.Str() hasHTTP = true case string(conventionsv112.HTTPServerNameKey): urlParts[key] = value.Str() @@ -110,6 +111,9 @@ func makeHTTP(span ptrace.Span) (map[string]pcommon.Value, *awsxray.HTTPData) { case string(conventions.URLPathKey): urlParts[key] = value.Str() hasHTTP = true + case string(conventions.URLQueryKey): + urlParts[key] = value.Str() + hasHTTP = true case string(conventions.ServerAddressKey): urlParts[key] = value.Str() hasHTTPRequestURLAttributes = true @@ -205,7 +209,19 @@ func constructClientURL(urlParts map[string]string) string { if ok { url += target } else { - url += "/" + path, ok := urlParts[string(conventions.URLPathKey)] + if ok { + url += path + } else { + url += "/" + } + query, ok := urlParts[string(conventions.URLQueryKey)] + if ok { + if !strings.HasPrefix(query, "?") { + query = "?" + query + } + url += query + } } return url } @@ -259,6 +275,13 @@ func constructServerURL(urlParts map[string]string) string { } else { url += "/" } + query, ok := urlParts[string(conventions.URLQueryKey)] + if ok { + if !strings.HasPrefix(query, "?") { + query = "?" + query + } + url += query + } } return url } diff --git a/exporter/awsxrayexporter/internal/translator/http_test.go b/exporter/awsxrayexporter/internal/translator/http_test.go index 5b3560d2b25cb..a3a80a4f38afd 100644 --- a/exporter/awsxrayexporter/internal/translator/http_test.go +++ b/exporter/awsxrayexporter/internal/translator/http_test.go @@ -79,7 +79,8 @@ func TestClientSpanWithSchemeHostTargetAttributesStable(t *testing.T) { attributes[string(conventions.HTTPRequestMethodKey)] = "GET" attributes[string(conventions.URLSchemeKey)] = "https" attributes[string(conventionsv112.HTTPHostKey)] = "api.example.com" - attributes[string(conventions.URLQueryKey)] = "/users/junit" + attributes[string(conventions.URLPathKey)] = "/users/junit" + attributes[string(conventions.URLQueryKey)] = "v=1" attributes[string(conventions.HTTPResponseStatusCodeKey)] = 200 attributes["user.id"] = "junit" span := constructHTTPClientSpan(attributes) @@ -92,7 +93,7 @@ func TestClientSpanWithSchemeHostTargetAttributesStable(t *testing.T) { require.NoError(t, w.Encode(httpData)) jsonStr := w.String() testWriters.release(w) - assert.Contains(t, jsonStr, "https://api.example.com/users/junit") + assert.Contains(t, jsonStr, "https://api.example.com/users/junit?v=1") } func TestClientSpanWithPeerAttributes(t *testing.T) { @@ -128,7 +129,7 @@ func TestClientSpanWithPeerAttributesStable(t *testing.T) { attributes[string(conventionsv112.NetPeerNameKey)] = "kb234.example.com" attributes[string(conventionsv112.NetPeerPortKey)] = 8080 attributes[string(conventionsv112.NetPeerIPKey)] = "10.8.17.36" - attributes[string(conventions.URLQueryKey)] = "/users/junit" + attributes[string(conventions.URLQueryKey)] = "users=junit" attributes[string(conventions.HTTPResponseStatusCodeKey)] = 200 span := constructHTTPClientSpan(attributes) @@ -143,7 +144,7 @@ func TestClientSpanWithPeerAttributesStable(t *testing.T) { require.NoError(t, w.Encode(httpData)) jsonStr := w.String() testWriters.release(w) - assert.Contains(t, jsonStr, "http://kb234.example.com:8080/users/junit") + assert.Contains(t, jsonStr, "http://kb234.example.com:8080/?users=junit") } func TestClientSpanWithHttpPeerAttributes(t *testing.T) { @@ -279,7 +280,7 @@ func TestServerSpanWithSchemeHostTargetAttributesStable(t *testing.T) { attributes[string(conventions.HTTPRequestMethodKey)] = http.MethodGet attributes[string(conventions.URLSchemeKey)] = "https" attributes[string(conventions.ServerAddressKey)] = "api.example.com" - attributes[string(conventions.URLQueryKey)] = "/users/junit" + attributes[string(conventions.URLPathKey)] = "/users/junit" attributes[string(conventions.ClientAddressKey)] = "192.168.15.32" attributes[string(conventions.HTTPResponseStatusCodeKey)] = 200 span := constructHTTPServerSpan(attributes) @@ -295,6 +296,28 @@ func TestServerSpanWithSchemeHostTargetAttributesStable(t *testing.T) { assert.Contains(t, jsonStr, "https://api.example.com/users/junit") } +func TestServerSpanWithNewConventionsWithURLPath(t *testing.T) { + attributes := make(map[string]any) + attributes[string(conventions.HTTPRequestMethodKey)] = http.MethodGet + attributes[string(conventions.ServerAddressKey)] = "localhost" + attributes[string(conventions.URLSchemeKey)] = "http" + attributes[string(conventions.URLQueryKey)] = "?version=test" + attributes[string(conventions.URLPathKey)] = "/api" + attributes[string(conventions.ClientAddressKey)] = "127.0.0.1" + attributes[string(conventions.HTTPResponseStatusCodeKey)] = 200 + span := constructHTTPServerSpan(attributes) + + filtered, httpData := makeHTTP(span) + + assert.NotNil(t, httpData) + assert.NotNil(t, filtered) + w := testWriters.borrow() + require.NoError(t, w.Encode(httpData)) + jsonStr := w.String() + testWriters.release(w) + assert.Contains(t, jsonStr, "http://localhost/api?version=test") +} + func TestServerSpanWithSchemeServernamePortTargetAttributes(t *testing.T) { attributes := make(map[string]any) attributes[string(conventionsv112.HTTPMethodKey)] = http.MethodGet @@ -323,7 +346,7 @@ func TestServerSpanWithSchemeServernamePortTargetAttributesStable(t *testing.T) attributes[string(conventions.URLSchemeKey)] = "https" attributes[string(conventions.ServerAddressKey)] = "api.example.com" attributes[string(conventions.ServerPortKey)] = 443 - attributes[string(conventions.URLQueryKey)] = "/users/junit" + attributes[string(conventions.URLQueryKey)] = "users=junit" attributes[string(conventions.ClientAddressKey)] = "192.168.15.32" attributes[string(conventions.HTTPResponseStatusCodeKey)] = 200 span := constructHTTPServerSpan(attributes) @@ -336,7 +359,7 @@ func TestServerSpanWithSchemeServernamePortTargetAttributesStable(t *testing.T) require.NoError(t, w.Encode(httpData)) jsonStr := w.String() testWriters.release(w) - assert.Contains(t, jsonStr, "https://api.example.com/users/junit") + assert.Contains(t, jsonStr, "https://api.example.com/?users=junit") } func TestServerSpanWithSchemeNamePortTargetAttributes(t *testing.T) {