-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Patching Mechanism with AWS SDK telemetry improvements (#13)
*Issue #, if available:* *Description of changes:* 1. `aws-attribute-keys.ts`: - Update values for keys: `AWS_BUCKET_NAME, AWS_QUEUE_URL, AWS_QUEUE_NAME, AWS_STREAM_NAME, AWS_TABLE_NAME` in order to match the actual attribute collected from AWS SDK auto-instrumentation 2. `aws-metric-attribute-generator.ts`: - [Similarly to Python](https://github.com/aws-observability/aws-otel-python-instrumentation/blob/2c00bd07eaaf703880a24a2fcfe874cdb4196678/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_aws_metric_attribute_generator.py#L378-L380), accommodates the fact that AWS_ATTRIBUTE_KEYS.AWS_TABLE_NAMES [has an array of table names](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/931318cac21ee3707f3735a64ac751566ee37182/plugins/node/opentelemetry-instrumentation-aws-sdk/src/services/dynamodb.ts#L99-L105) from aws-sdk dynamodb client instrumentation 3. `aws-opentelemetry-configurator.ts`: - Takes and sets instrumentations in constructor. 4. `instrumentation-patch.ts`: - Applies patches for AWS SDK Instrumentation 5. `register.ts`: - Applies patches from (4.) by default, unless `AWS_APPLY_PATCHES` env var is not `'true'` The following files are copied from upstream: ``` aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/ServiceExtension.ts ``` The following files are being contributed to upstream: See: open-telemetry/opentelemetry-js-contrib#2361 ``` aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/kinesis.ts aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/s3.ts ``` *Testing:* - Add unit tests By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
- Loading branch information
Showing
18 changed files
with
2,603 additions
and
278 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/kinesis.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { Attributes, SpanKind } from '@opentelemetry/api'; | ||
import { AwsSdkInstrumentationConfig, NormalizedRequest } from '@opentelemetry/instrumentation-aws-sdk'; | ||
import { AWS_ATTRIBUTE_KEYS } from '../../../aws-attribute-keys'; | ||
import { RequestMetadata, ServiceExtension } from '../../../third-party/otel/aws/services/ServiceExtension'; | ||
|
||
/* | ||
This file's contents are being contributed to upstream | ||
- https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2361 | ||
This class is a service extension to be used for the AWS JavaScript SDK instrumentation patch for Kinesis. | ||
The instrumentation patch adds this extension to the upstream's Map of known extension for Kinesis. | ||
Extensions allow for custom logic for adding service-specific information to spans, such as attributes. | ||
Specifically, we are adding logic to add the `aws.kinesis.stream.name` attribute, to be used to generate | ||
RemoteTarget and achieve parity with the Java/Python instrumentation. | ||
*/ | ||
export class KinesisServiceExtension implements ServiceExtension { | ||
requestPreSpanHook(request: NormalizedRequest, _config: AwsSdkInstrumentationConfig): RequestMetadata { | ||
const streamName = request.commandInput?.StreamName; | ||
|
||
const spanKind: SpanKind = SpanKind.CLIENT; | ||
let spanName: string | undefined; | ||
|
||
const spanAttributes: Attributes = {}; | ||
|
||
if (streamName) { | ||
spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_KINESIS_STREAM_NAME] = streamName; | ||
} | ||
|
||
const isIncoming = false; | ||
|
||
return { | ||
isIncoming, | ||
spanAttributes, | ||
spanKind, | ||
spanName, | ||
}; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/s3.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { Attributes, SpanKind } from '@opentelemetry/api'; | ||
import { AwsSdkInstrumentationConfig, NormalizedRequest } from '@opentelemetry/instrumentation-aws-sdk'; | ||
import { AWS_ATTRIBUTE_KEYS } from '../../../aws-attribute-keys'; | ||
import { RequestMetadata, ServiceExtension } from '../../../third-party/otel/aws/services/ServiceExtension'; | ||
|
||
/* | ||
This file's contents are being contributed to upstream | ||
- https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2361 | ||
This class is a service extension to be used for the AWS JavaScript SDK instrumentation patch for S3. | ||
The instrumentation patch adds this extension to the upstream's Map of known extension for S3. | ||
Extensions allow for custom logic for adding service-specific information to spans, such as attributes. | ||
Specifically, we are adding logic to add the `aws.s3.bucket` attribute, to be used to generate | ||
RemoteTarget and achieve parity with the Java/Python instrumentation. | ||
*/ | ||
export class S3ServiceExtension implements ServiceExtension { | ||
requestPreSpanHook(request: NormalizedRequest, _config: AwsSdkInstrumentationConfig): RequestMetadata { | ||
const bucketName = request.commandInput?.Bucket; | ||
|
||
const spanKind: SpanKind = SpanKind.CLIENT; | ||
let spanName: string | undefined; | ||
|
||
const spanAttributes: Attributes = {}; | ||
|
||
if (bucketName) { | ||
spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_S3_BUCKET] = bucketName; | ||
} | ||
|
||
const isIncoming = false; | ||
|
||
return { | ||
isIncoming, | ||
spanAttributes, | ||
spanKind, | ||
spanName, | ||
}; | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { Instrumentation } from '@opentelemetry/instrumentation'; | ||
import { AwsSdkInstrumentationConfig, NormalizedRequest } from '@opentelemetry/instrumentation-aws-sdk'; | ||
import { AWS_ATTRIBUTE_KEYS } from '../aws-attribute-keys'; | ||
import { RequestMetadata } from '../third-party/otel/aws/services/ServiceExtension'; | ||
import { KinesisServiceExtension } from './aws/services/kinesis'; | ||
import { S3ServiceExtension } from './aws/services/s3'; | ||
|
||
export function applyInstrumentationPatches(instrumentations: Instrumentation[]): void { | ||
/* | ||
Apply patches to upstream instrumentation libraries. | ||
This method is invoked to apply changes to upstream instrumentation libraries, typically when changes to upstream | ||
are required on a timeline that cannot wait for upstream release. Generally speaking, patches should be short-term | ||
local solutions that are comparable to long-term upstream solutions. | ||
Where possible, automated testing should be run to catch upstream changes resulting in broken patches | ||
*/ | ||
instrumentations.forEach(instrumentation => { | ||
if (instrumentation.instrumentationName === '@opentelemetry/instrumentation-aws-sdk') { | ||
// Access private property servicesExtensions of AwsInstrumentation | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
const services: Map<string, ServiceExtension> | undefined = (instrumentation as any).servicesExtensions?.services; | ||
if (services) { | ||
services.set('S3', new S3ServiceExtension()); | ||
services.set('Kinesis', new KinesisServiceExtension()); | ||
patchSqsServiceExtension(services.get('SQS')); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
/* | ||
* This patch extends the existing upstream extension for SQS. Extensions allow for custom logic for adding | ||
* service-specific information to spans, such as attributes. Specifically, we are adding logic to add | ||
* `aws.sqs.queue.url` and `aws.sqs.queue.name` attributes, to be used to generate RemoteTarget and achieve parity | ||
* with the Java/Python instrumentation. | ||
* | ||
* Callout that today, the upstream logic adds `messaging.url` and `messaging.destination` but we feel that | ||
* `aws.sqs` is more in line with existing AWS Semantic Convention attributes like `AWS_S3_BUCKET`, etc. | ||
* | ||
* @param sqsServiceExtension SQS Service Extension obtained the service extension list from the AWS SDK OTel Instrumentation | ||
*/ | ||
function patchSqsServiceExtension(sqsServiceExtension: any): void { | ||
// It is not expected that `sqsServiceExtension` is undefined | ||
if (sqsServiceExtension) { | ||
const requestPreSpanHook = sqsServiceExtension.requestPreSpanHook; | ||
// Save original `requestPreSpanHook` under a similar name, to be invoked by the patched hook | ||
sqsServiceExtension._requestPreSpanHook = requestPreSpanHook; | ||
// The patched hook will populate the 'aws.sqs.queue.url' and 'aws.sqs.queue.name' attributes according to spec | ||
// from the 'messaging.url' attribute | ||
const patchedRequestPreSpanHook = ( | ||
request: NormalizedRequest, | ||
_config: AwsSdkInstrumentationConfig | ||
): RequestMetadata => { | ||
const requestMetadata: RequestMetadata = sqsServiceExtension._requestPreSpanHook(request, _config); | ||
// It is not expected that `requestMetadata.spanAttributes` can possibly be undefined, but still be careful anyways | ||
if (requestMetadata.spanAttributes) { | ||
if (request.commandInput?.QueueUrl) { | ||
requestMetadata.spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_URL] = request.commandInput.QueueUrl; | ||
} | ||
if (request.commandInput?.QueueName) { | ||
requestMetadata.spanAttributes[AWS_ATTRIBUTE_KEYS.AWS_SQS_QUEUE_NAME] = request.commandInput.QueueName; | ||
} | ||
} | ||
return requestMetadata; | ||
}; | ||
sqsServiceExtension.requestPreSpanHook = patchedRequestPreSpanHook; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.