Skip to content

Commit 03aa3b5

Browse files
authored
Merge branch 'aws-observability:main' into main
2 parents 27468e5 + a9375ff commit 03aa3b5

File tree

16 files changed

+194
-25
lines changed

16 files changed

+194
-25
lines changed

.github/workflows/daily-scan.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
id: high_scan
7474
uses: ./.github/actions/image_scan
7575
with:
76-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.3.0"
76+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.4.0"
7777
severity: 'CRITICAL,HIGH'
7878

7979
# TODO: Update image to public once available
@@ -82,7 +82,7 @@ jobs:
8282
id: low_scan
8383
uses: ./.github/actions/image_scan
8484
with:
85-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.3.0"
85+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.4.0"
8686
severity: 'MEDIUM,LOW,UNKNOWN'
8787

8888
- name: Configure AWS Credentials for emitting metrics
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build
22
node_modules
33
.eslintrc.js
4-
version.ts
4+
version.ts
5+
src/third-party

aws-distro-opentelemetry-node-autoinstrumentation/package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@aws/aws-distro-opentelemetry-node-autoinstrumentation",
3-
"version": "0.3.0-dev0",
3+
"version": "0.4.0-dev0",
44
"description": "This package provides Amazon Web Services distribution of the OpenTelemetry Node Instrumentation, which allows for auto-instrumentation of NodeJS applications.",
55
"author": {
66
"name": "Amazon Web Services",
@@ -31,9 +31,18 @@
3131
"prepublishOnly": "npm run compile",
3232
"tdd": "yarn test -- --watch-extensions ts --watch",
3333
"test": "nyc ts-mocha --timeout 10000 -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/*.ts'",
34-
"test:coverage": "nyc --all --check-coverage --functions 95 --lines 95 ts-mocha --timeout 10000 -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/*.ts'",
34+
"test:coverage": "nyc --check-coverage --functions 95 --lines 95 ts-mocha --timeout 10000 -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/*.ts'",
3535
"watch": "tsc -w"
3636
},
37+
"nyc": {
38+
"all": true,
39+
"include": [
40+
"src/**/*.ts"
41+
],
42+
"exclude": [
43+
"src/third-party/**/*.ts"
44+
]
45+
},
3746
"bugs": {
3847
"url": "https://github.com/aws-observability/aws-otel-js-instrumentation/issues"
3948
},

aws-distro-opentelemetry-node-autoinstrumentation/src/patches/aws/services/bedrock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const KNOWLEDGE_BASE_ID: string = 'knowledgeBaseId';
1616
const DATA_SOURCE_ID: string = 'dataSourceId';
1717
const GUARDRAIL_ID: string = 'guardrailId';
1818
const MODEL_ID: string = 'modelId';
19-
const AWS_BEDROCK_SYSTEM: string = 'aws_bedrock';
19+
const AWS_BEDROCK_SYSTEM: string = 'aws.bedrock';
2020

2121
const AGENT_OPERATIONS = [
2222
'CreateAgentActionGroup',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';
5+
import { context as otelContext, defaultTextMapSetter } from '@opentelemetry/api';
6+
import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray';
7+
import type { Command as AwsV3Command } from '@aws-sdk/types';
8+
9+
const awsXrayPropagator = new AWSXRayPropagator();
10+
const V3_CLIENT_CONFIG_KEY = Symbol('opentelemetry.instrumentation.aws-sdk.client.config');
11+
type V3PluginCommand = AwsV3Command<any, any, any, any, any> & {
12+
[V3_CLIENT_CONFIG_KEY]?: any;
13+
};
14+
15+
// This class extends the upstream AwsInstrumentation to override its patching mechanism of the `send` method.
16+
// The overriden method will additionally update the AWS SDK middleware stack to inject the `X-Amzn-Trace-Id` HTTP header.
17+
//
18+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
19+
// @ts-ignore
20+
export class AwsSdkInstrumentationExtended extends AwsInstrumentation {
21+
// Override the upstream private _getV3SmithyClientSendPatch method to add middleware to inject X-Ray Trace Context into HTTP Headers
22+
// 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
23+
override _getV3SmithyClientSendPatch(original: (...args: unknown[]) => Promise<any>) {
24+
return function send(this: any, command: V3PluginCommand, ...args: unknown[]): Promise<any> {
25+
this.middlewareStack?.add(
26+
(next: any, context: any) => async (middlewareArgs: any) => {
27+
awsXrayPropagator.inject(otelContext.active(), middlewareArgs.request.headers, defaultTextMapSetter);
28+
const result = await next(middlewareArgs);
29+
return result;
30+
},
31+
{
32+
step: 'build',
33+
name: '_adotInjectXrayContextMiddleware',
34+
override: true,
35+
}
36+
);
37+
38+
command[V3_CLIENT_CONFIG_KEY] = this.config;
39+
return original.apply(this, [command, ...args]);
40+
};
41+
}
42+
}

aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import {
2525
} from './aws/services/bedrock';
2626
import { KinesisServiceExtension } from './aws/services/kinesis';
2727
import { S3ServiceExtension } from './aws/services/s3';
28-
import { AwsLambdaInstrumentationPatch } from './aws/services/aws-lambda';
28+
import { AwsLambdaInstrumentationPatch } from './extended-instrumentations/aws-lambda';
29+
import { InstrumentationConfigMap } from '@opentelemetry/auto-instrumentations-node';
30+
import { AwsSdkInstrumentationExtended } from './extended-instrumentations/aws-sdk-instrumentation-extended';
2931

3032
export const traceContextEnvironmentKey = '_X_AMZN_TRACE_ID';
3133
const awsPropagator = new AWSXRayPropagator();
@@ -38,7 +40,10 @@ export const headerGetter: TextMapGetter<APIGatewayProxyEventHeaders> = {
3840
},
3941
};
4042

41-
export function applyInstrumentationPatches(instrumentations: Instrumentation[]): void {
43+
export function applyInstrumentationPatches(
44+
instrumentations: Instrumentation[],
45+
instrumentationConfigs?: InstrumentationConfigMap
46+
): void {
4247
/*
4348
Apply patches to upstream instrumentation libraries.
4449
@@ -50,10 +55,16 @@ export function applyInstrumentationPatches(instrumentations: Instrumentation[])
5055
*/
5156
instrumentations.forEach((instrumentation, index) => {
5257
if (instrumentation.instrumentationName === '@opentelemetry/instrumentation-aws-sdk') {
58+
diag.debug('Overriding aws sdk instrumentation');
59+
instrumentations[index] = new AwsSdkInstrumentationExtended(
60+
instrumentationConfigs ? instrumentationConfigs['@opentelemetry/instrumentation-aws-sdk'] : undefined
61+
);
62+
5363
// Access private property servicesExtensions of AwsInstrumentation
5464
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
5565
// @ts-ignore
56-
const services: Map<string, ServiceExtension> | undefined = (instrumentation as any).servicesExtensions?.services;
66+
const services: Map<string, ServiceExtension> | undefined = (instrumentations[index] as any).servicesExtensions
67+
?.services;
5768
if (services) {
5869
services.set('S3', new S3ServiceExtension());
5970
services.set('Kinesis', new KinesisServiceExtension());

aws-distro-opentelemetry-node-autoinstrumentation/src/register.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const instrumentationConfigs: InstrumentationConfigMap = {
6262
const instrumentations: Instrumentation[] = getNodeAutoInstrumentations(instrumentationConfigs);
6363

6464
// Apply instrumentation patches
65-
applyInstrumentationPatches(instrumentations);
65+
applyInstrumentationPatches(instrumentations, instrumentationConfigs);
6666

6767
const configurator: AwsOpentelemetryConfigurator = new AwsOpentelemetryConfigurator(instrumentations, useXraySampler);
6868
const configuration: Partial<opentelemetry.NodeSDKConfiguration> = configurator.configure();

aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/bedrock.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ describe('BedrockRuntime', () => {
331331
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
332332
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
333333
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
334-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
334+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
335335
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
336336
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(512);
337337
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0.6);
@@ -384,7 +384,7 @@ describe('BedrockRuntime', () => {
384384
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
385385
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
386386
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
387-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
387+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
388388
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
389389
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(4096);
390390
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0);
@@ -448,7 +448,7 @@ describe('BedrockRuntime', () => {
448448
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
449449
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
450450
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
451-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
451+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
452452
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
453453
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(1000);
454454
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(1.0);
@@ -506,7 +506,7 @@ describe('BedrockRuntime', () => {
506506
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
507507
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
508508
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
509-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
509+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
510510
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
511511
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(512);
512512
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0.5);
@@ -560,7 +560,7 @@ describe('BedrockRuntime', () => {
560560
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
561561
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
562562
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
563-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
563+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
564564
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
565565
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(512);
566566
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0.5);
@@ -614,7 +614,7 @@ describe('BedrockRuntime', () => {
614614
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
615615
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
616616
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
617-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
617+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
618618
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
619619
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(512);
620620
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0.5);
@@ -676,7 +676,7 @@ describe('BedrockRuntime', () => {
676676
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_AGENT_ID]).toBeUndefined();
677677
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_KNOWLEDGE_BASE_ID]).toBeUndefined();
678678
expect(invokeModelSpan.attributes[AWS_ATTRIBUTE_KEYS.AWS_BEDROCK_DATA_SOURCE_ID]).toBeUndefined();
679-
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws_bedrock');
679+
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_SYSTEM]).toBe('aws.bedrock');
680680
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MODEL]).toBe(modelId);
681681
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_MAX_TOKENS]).toBe(4096);
682682
expect(invokeModelSpan.attributes[AwsSpanProcessingUtil.GEN_AI_REQUEST_TEMPERATURE]).toBe(0.75);

aws-distro-opentelemetry-node-autoinstrumentation/test/patches/aws/services/aws-lambda.test.ts renamed to aws-distro-opentelemetry-node-autoinstrumentation/test/patches/extended-instrumentations/aws-lambda.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as path from 'path';
66
import * as fs from 'fs';
77
import { diag } from '@opentelemetry/api';
88
import { InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
9-
import { AwsLambdaInstrumentationPatch } from '../../../../src/patches/aws/services/aws-lambda';
9+
import { AwsLambdaInstrumentationPatch } from '../../../src/patches/extended-instrumentations/aws-lambda';
1010

1111
describe('AwsLambdaInstrumentationPatch', () => {
1212
let instrumentation: AwsLambdaInstrumentationPatch;

0 commit comments

Comments
 (0)