diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-span-processing-util.ts b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-span-processing-util.ts index 49d0a2c..3014e72 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-span-processing-util.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/src/aws-span-processing-util.ts @@ -76,7 +76,21 @@ export class AwsSpanProcessingUtil { if (httpTarget == null || httpTarget === '') { return '/'; } - const paths: string[] = httpTarget.split('/'); + // Divergence from Java/Python + // https://github.com/open-telemetry/semantic-conventions/blob/4e7c42ee8e4c3a39a899c4c85c64df28cd543f78/docs/attributes-registry/http.md#deprecated-http-attributes + // According to OTel Spec, httpTarget may include query and fragment: + // - `/search?q=OpenTelemetry#SemConv` + // We do NOT want the `?` or `#` parts, so let us strip it out, + // because HTTP (ingress) instrumentation was observed to include the query (`?`) part + // - https://github.com/open-telemetry/opentelemetry-js/blob/b418d36609c371d1fcae46898e9ede6278aca917/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts#L502-L504 + // According to RFC Specification, "The path is terminated by the first question mark ("?") or number sign ("#") character, or by the end of the URI." + // - https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 + // + // This is a fix that can be applied here since this is the central location for generating API Path Value + // TODO: Possibly contribute fix to upstream for this diff between langauges. However, the current attribute value in JS is according to spec. + // + // Interestingly, according to Spec, Java/Python should be affected, but they are not. + const paths: string[] = httpTarget.split(/[/?#]/); if (paths.length > 1) { return '/' + paths[1]; } diff --git a/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-span-processing-util.test.ts b/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-span-processing-util.test.ts index f002006..bfd3e4d 100644 --- a/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-span-processing-util.test.ts +++ b/aws-distro-opentelemetry-node-autoinstrumentation/test/aws-span-processing-util.test.ts @@ -171,6 +171,24 @@ describe('AwsSpanProcessingUtilTest', () => { expect(pathValue).toEqual('/users'); }); + it('testExtractAPIPathValidPathSingleSlash', () => { + let validTarget: string = '/users?query#fragment'; + let pathValue: string = AwsSpanProcessingUtil.extractAPIPathValue(validTarget); + expect(pathValue).toEqual('/users'); + + validTarget = '/users#fragment?fragment_part_2'; + pathValue = AwsSpanProcessingUtil.extractAPIPathValue(validTarget); + expect(pathValue).toEqual('/users'); + + validTarget = '/users?query'; + pathValue = AwsSpanProcessingUtil.extractAPIPathValue(validTarget); + expect(pathValue).toEqual('/users'); + + validTarget = '/users#fragment'; + pathValue = AwsSpanProcessingUtil.extractAPIPathValue(validTarget); + expect(pathValue).toEqual('/users'); + }); + it('testIsKeyPresentKeyPresent', () => { attributesMock[SEMATTRS_HTTP_TARGET] = 'target'; expect(AwsSpanProcessingUtil.isKeyPresent(spanDataMock, SEMATTRS_HTTP_TARGET)).toBeTruthy();