-
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.
[Fix] Update AWS SDK Instrumentation to inject XRay trace context int…
…o HTTP Headers (#131) *Issue #, if available:* Fixes the absence of broken X-Ray context propagation when the underlying HTTP instrumentation is suppressed or disabled. Similarly to Java and Python, AWS SDK Js instrumentation itself should be able to inject the X-Ray Context into the HTTP Headers: - [Java example](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/81c7713bb2f638c85006c3e152ad13d6e02f3259/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/TracingExecutionInterceptor.java#L308) - [Python example ](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py#L163-L165) - See Specification that clarifies that AWS SDK instrumentations should use X-Ray propagator specifically. - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.40.0/supplementary-guidelines/compatibility/aws.md?plain=1#L9-L12 Note - If the underlying HTTP instrumentation is enabled, then the underlying HTTP Child Span of the AWS SDK Span will overwrite the Trace Context to propagate through headers. *Description of changes:* - Move patched/extended instrumentations to an `patches/extended-instrumentations/` directory - Created `AwsSdkInstrumentationExtended` class that extends upstream AwsInstrumentation to override its patching mechanism of the `send` method. The overridden method will additionally update the AWS SDK middleware stack to inject the `X-Amzn-Trace-Id` HTTP header. 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
9 changed files
with
176 additions
and
7 deletions.
There are no files selected for viewing
3 changes: 2 additions & 1 deletion
3
aws-distro-opentelemetry-node-autoinstrumentation/.eslintignore
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 |
---|---|---|
@@ -1,4 +1,5 @@ | ||
build | ||
node_modules | ||
.eslintrc.js | ||
version.ts | ||
version.ts | ||
src/third-party |
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
File renamed without changes.
42 changes: 42 additions & 0 deletions
42
...instrumentation/src/patches/extended-instrumentations/aws-sdk-instrumentation-extended.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,42 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; | ||
import { context as otelContext, defaultTextMapSetter } from '@opentelemetry/api'; | ||
import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray'; | ||
import type { Command as AwsV3Command } from '@aws-sdk/types'; | ||
|
||
const awsXrayPropagator = new AWSXRayPropagator(); | ||
const V3_CLIENT_CONFIG_KEY = Symbol('opentelemetry.instrumentation.aws-sdk.client.config'); | ||
type V3PluginCommand = AwsV3Command<any, any, any, any, any> & { | ||
[V3_CLIENT_CONFIG_KEY]?: any; | ||
}; | ||
|
||
// This class extends the upstream AwsInstrumentation to override its patching mechanism of the `send` method. | ||
// The overriden method will additionally update the AWS SDK middleware stack to inject the `X-Amzn-Trace-Id` HTTP header. | ||
// | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
export class AwsSdkInstrumentationExtended extends AwsInstrumentation { | ||
// Override the upstream private _getV3SmithyClientSendPatch method to add middleware to inject X-Ray Trace Context into HTTP Headers | ||
// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/instrumentation-aws-sdk-v0.48.0/plugins/node/opentelemetry-instrumentation-aws-sdk/src/aws-sdk.ts#L373-L384 | ||
override _getV3SmithyClientSendPatch(original: (...args: unknown[]) => Promise<any>) { | ||
return function send(this: any, command: V3PluginCommand, ...args: unknown[]): Promise<any> { | ||
this.middlewareStack?.add( | ||
(next: any, context: any) => async (middlewareArgs: any) => { | ||
awsXrayPropagator.inject(otelContext.active(), middlewareArgs.request.headers, defaultTextMapSetter); | ||
const result = await next(middlewareArgs); | ||
return result; | ||
}, | ||
{ | ||
step: 'build', | ||
name: '_adotInjectXrayContextMiddleware', | ||
override: true, | ||
} | ||
); | ||
|
||
command[V3_CLIENT_CONFIG_KEY] = this.config; | ||
return original.apply(this, [command, ...args]); | ||
}; | ||
} | ||
} |
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
48 changes: 48 additions & 0 deletions
48
...mentation/test/patches/extended-instrumentations/aws-sdk-instrumentation-extended.test.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,48 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
import * as sinon from 'sinon'; | ||
import { AwsSdkInstrumentationExtended } from '../../../src/patches/extended-instrumentations/aws-sdk-instrumentation-extended'; | ||
import expect from 'expect'; | ||
import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray'; | ||
import { Context, TextMapSetter } from '@opentelemetry/api'; | ||
|
||
describe('AwsSdkInstrumentationExtended', () => { | ||
let instrumentation: AwsSdkInstrumentationExtended; | ||
|
||
beforeEach(() => { | ||
instrumentation = new AwsSdkInstrumentationExtended({}); | ||
}); | ||
|
||
afterEach(() => { | ||
sinon.restore(); | ||
}); | ||
|
||
it('overridden _getV3SmithyClientSendPatch updates MiddlewareStack', async () => { | ||
const mockedMiddlewareStackInternal: any = []; | ||
const mockedMiddlewareStack = { | ||
add: (arg1: any, arg2: any) => mockedMiddlewareStackInternal.push([arg1, arg2]), | ||
}; | ||
const send = instrumentation | ||
._getV3SmithyClientSendPatch((...args: unknown[]) => Promise.resolve()) | ||
.bind({ middlewareStack: mockedMiddlewareStack }); | ||
sinon | ||
.stub(AWSXRayPropagator.prototype, 'inject') | ||
.callsFake((context: Context, carrier: unknown, setter: TextMapSetter) => { | ||
(carrier as any)['isCarrierModified'] = 'carrierIsModified'; | ||
}); | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
await send({}, null); | ||
|
||
const middlewareArgs: any = { | ||
request: { | ||
headers: {}, | ||
}, | ||
}; | ||
await mockedMiddlewareStackInternal[0][0]((arg: any) => Promise.resolve(), null)(middlewareArgs); | ||
|
||
expect(middlewareArgs.request.headers['isCarrierModified']).toEqual('carrierIsModified'); | ||
expect(mockedMiddlewareStackInternal[0][1].name).toEqual('_adotInjectXrayContextMiddleware'); | ||
}); | ||
}); |
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