Skip to content

Commit 621ae50

Browse files
authored
feat(tracer): add support for capturing DynamoDB DocumentClient (#450)
* feat: add support for capturing DynamoDB DocumentClient * removed unused error ref * chore: rebase * chore: added e2e tests with DynamoDB Table
1 parent 900aba9 commit 621ae50

10 files changed

+1865
-708
lines changed

Diff for: packages/tracing/package-lock.json

+1,714-628
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/tracing/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@
3030
"main": "./lib/index.js",
3131
"types": "./lib/index.d.ts",
3232
"devDependencies": {
33-
"@aws-cdk/aws-lambda-nodejs": "^1.137.0",
34-
"@aws-cdk/core": "^1.137.0",
35-
"@aws-sdk/client-sts": "^3.45.0",
33+
"@aws-cdk/aws-dynamodb": "^1.139.0",
34+
"@aws-cdk/aws-lambda-nodejs": "^1.139.0",
35+
"@aws-cdk/core": "^1.139.0",
36+
"@aws-sdk/client-dynamodb": "^3.47.0",
3637
"@types/aws-lambda": "^8.10.72",
3738
"@types/jest": "^27.0.0",
3839
"@types/node": "^17.0.8",
3940
"@typescript-eslint/eslint-plugin": "^5.4.0",
4041
"@typescript-eslint/parser": "^5.4.0",
41-
"aws-cdk": "^1.137.0",
42+
"aws-cdk": "^1.139.0",
4243
"aws-sdk": "^2.1048.0",
4344
"esbuild": "^0.14.10",
4445
"eslint": "^8.3.0",

Diff for: packages/tracing/src/Tracer.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,15 @@ class Tracer implements TracerInterface {
257257
public captureAWSClient<T>(service: T): T {
258258
if (!this.isTracingEnabled()) return service;
259259

260-
return this.provider.captureAWSClient(service);
260+
try {
261+
return this.provider.captureAWSClient(service);
262+
} catch (error) {
263+
try {
264+
return this.provider.captureAWSClient((service as unknown as T & { service: T }).service);
265+
} catch {
266+
throw error;
267+
}
268+
}
261269
}
262270

263271
/**

Diff for: packages/tracing/tests/e2e/tracer.test.Decorator.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Tracer } from '../../src';
22
import { Callback, Context } from 'aws-lambda';
3-
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
3+
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb';
44
// eslint-disable-next-line @typescript-eslint/no-var-requires
55
let AWS = require('aws-sdk');
66

@@ -11,6 +11,7 @@ const customMetadataKey = process.env.EXPECTED_CUSTOM_METADATA_KEY ?? 'myMetadat
1111
const customMetadataValue = JSON.parse(process.env.EXPECTED_CUSTOM_METADATA_VALUE) ?? { bar: 'baz' };
1212
const customResponseValue = JSON.parse(process.env.EXPECTED_CUSTOM_RESPONSE_VALUE) ?? { foo: 'bar' };
1313
const customErrorMessage = process.env.EXPECTED_CUSTOM_ERROR_MESSAGE ?? 'An error has occurred';
14+
const testTableName = process.env.TEST_TABLE_NAME ?? 'TestTable';
1415

1516
interface CustomEvent {
1617
throw: boolean
@@ -31,7 +32,7 @@ const refreshAWSSDKImport = (): void => {
3132
};
3233

3334
const tracer = new Tracer({ serviceName: serviceName });
34-
const stsv3 = tracer.captureAWSv3Client(new STSClient({}));
35+
const dynamoDBv3 = tracer.captureAWSv3Client(new DynamoDBClient({}));
3536

3637
export class MyFunctionWithDecorator {
3738
@tracer.captureLambdaHandler()
@@ -41,18 +42,18 @@ export class MyFunctionWithDecorator {
4142
tracer.putAnnotation(customAnnotationKey, customAnnotationValue);
4243
tracer.putMetadata(customMetadataKey, customMetadataValue);
4344

44-
let stsv2;
45+
let dynamoDBv2;
4546
refreshAWSSDKImport();
4647
if (event.sdkV2 === 'client') {
47-
stsv2 = tracer.captureAWSClient(new AWS.STS());
48+
dynamoDBv2 = tracer.captureAWSClient(new AWS.DynamoDB.DocumentClient());
4849
} else if (event.sdkV2 === 'all') {
4950
AWS = tracer.captureAWS(AWS);
50-
stsv2 = new AWS.STS();
51+
dynamoDBv2 = new AWS.DynamoDB.DocumentClient();
5152
}
5253

5354
return Promise.all([
54-
stsv2.getCallerIdentity().promise(),
55-
stsv3.send(new GetCallerIdentityCommand({})),
55+
dynamoDBv2.scan({ TableName: testTableName }).promise(),
56+
dynamoDBv3.send(new ScanCommand({ TableName: testTableName })),
5657
new Promise((resolve, reject) => {
5758
setTimeout(() => {
5859
const res = this.myMethod();
@@ -64,7 +65,7 @@ export class MyFunctionWithDecorator {
6465
}, 2000); // We need to wait for to make sure previous calls are finished
6566
})
6667
])
67-
.then(([ _stsv2Res, _stsv3Res, promiseRes ]) => promiseRes)
68+
.then(([ _dynamoDBv2Res, _dynamoDBv3Res, promiseRes ]) => promiseRes)
6869
.catch((err) => {
6970
throw err;
7071
});

Diff for: packages/tracing/tests/e2e/tracer.test.DecoratorWithAsyncHandler.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Tracer } from '../../src';
22
import { Context } from 'aws-lambda';
3-
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
3+
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb';
44
// eslint-disable-next-line @typescript-eslint/no-var-requires
55
let AWS = require('aws-sdk');
66

@@ -11,6 +11,7 @@ const customMetadataKey = process.env.EXPECTED_CUSTOM_METADATA_KEY ?? 'myMetadat
1111
const customMetadataValue = JSON.parse(process.env.EXPECTED_CUSTOM_METADATA_VALUE) ?? { bar: 'baz' };
1212
const customResponseValue = JSON.parse(process.env.EXPECTED_CUSTOM_RESPONSE_VALUE) ?? { foo: 'bar' };
1313
const customErrorMessage = process.env.EXPECTED_CUSTOM_ERROR_MESSAGE ?? 'An error has occurred';
14+
const testTableName = process.env.TEST_TABLE_NAME ?? 'TestTable';
1415

1516
interface CustomEvent {
1617
throw: boolean
@@ -31,7 +32,7 @@ const refreshAWSSDKImport = (): void => {
3132
};
3233

3334
const tracer = new Tracer({ serviceName: serviceName });
34-
const stsv3 = tracer.captureAWSv3Client(new STSClient({}));
35+
const dynamoDBv3 = tracer.captureAWSv3Client(new DynamoDBClient({}));
3536

3637
export class MyFunctionWithDecorator {
3738
@tracer.captureLambdaHandler()
@@ -41,23 +42,23 @@ export class MyFunctionWithDecorator {
4142
tracer.putAnnotation(customAnnotationKey, customAnnotationValue);
4243
tracer.putMetadata(customMetadataKey, customMetadataValue);
4344

44-
let stsv2;
45+
let dynamoDBv2;
4546
refreshAWSSDKImport();
4647
if (event.sdkV2 === 'client') {
47-
stsv2 = tracer.captureAWSClient(new AWS.STS());
48+
dynamoDBv2 = tracer.captureAWSClient(new AWS.DynamoDB.DocumentClient());
4849
} else if (event.sdkV2 === 'all') {
4950
AWS = tracer.captureAWS(AWS);
50-
stsv2 = new AWS.STS();
51+
dynamoDBv2 = new AWS.DynamoDB.DocumentClient();
5152
}
5253

5354
try {
54-
await stsv2.getCallerIdentity().promise();
55+
await dynamoDBv2.scan({ TableName: testTableName }).promise();
5556
} catch (err) {
5657
console.error(err);
5758
}
5859

5960
try {
60-
await stsv3.send(new GetCallerIdentityCommand({}));
61+
await dynamoDBv3.send(new ScanCommand({ TableName: testTableName }));
6162
} catch (err) {
6263
console.error(err);
6364
}

Diff for: packages/tracing/tests/e2e/tracer.test.Manual.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Tracer } from '../../src';
22
import { Context } from 'aws-lambda';
3-
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
3+
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb';
44
// eslint-disable-next-line @typescript-eslint/no-var-requires
55
let AWS = require('aws-sdk');
66

@@ -11,6 +11,7 @@ const customMetadataKey = process.env.EXPECTED_CUSTOM_METADATA_KEY ?? 'myMetadat
1111
const customMetadataValue = JSON.parse(process.env.EXPECTED_CUSTOM_METADATA_VALUE) ?? { bar: 'baz' };
1212
const customResponseValue = JSON.parse(process.env.EXPECTED_CUSTOM_RESPONSE_VALUE) ?? { foo: 'bar' };
1313
const customErrorMessage = process.env.EXPECTED_CUSTOM_ERROR_MESSAGE ?? 'An error has occurred';
14+
const testTableName = process.env.TEST_TABLE_NAME ?? 'TestTable';
1415

1516
interface CustomEvent {
1617
throw: boolean
@@ -31,7 +32,7 @@ const refreshAWSSDKImport = (): void => {
3132
};
3233

3334
const tracer = new Tracer({ serviceName: serviceName });
34-
const stsv3 = tracer.captureAWSv3Client(new STSClient({}));
35+
const dynamoDBv3 = tracer.captureAWSv3Client(new DynamoDBClient({}));
3536

3637
export const handler = async (event: CustomEvent, _context: Context): Promise<void> => {
3738
const segment = tracer.getSegment();
@@ -45,22 +46,22 @@ export const handler = async (event: CustomEvent, _context: Context): Promise<vo
4546
tracer.putAnnotation(customAnnotationKey, customAnnotationValue);
4647
tracer.putMetadata(customMetadataKey, customMetadataValue);
4748

48-
let stsv2;
49+
let dynamoDBv2;
4950
refreshAWSSDKImport();
5051
if (event.sdkV2 === 'client') {
51-
stsv2 = tracer.captureAWSClient(new AWS.STS());
52+
dynamoDBv2 = tracer.captureAWSClient(new AWS.DynamoDB.DocumentClient());
5253
} else if (event.sdkV2 === 'all') {
5354
AWS = tracer.captureAWS(AWS);
54-
stsv2 = new AWS.STS();
55+
dynamoDBv2 = new AWS.DynamoDB.DocumentClient();
5556
}
5657
try {
57-
await stsv2.getCallerIdentity().promise();
58+
await dynamoDBv2.scan({ TableName: testTableName }).promise();
5859
} catch (err) {
5960
console.error(err);
6061
}
6162

6263
try {
63-
await stsv3.send(new GetCallerIdentityCommand({}));
64+
await dynamoDBv3.send(new ScanCommand({ TableName: testTableName }));
6465
} catch (err) {
6566
console.error(err);
6667
}

Diff for: packages/tracing/tests/e2e/tracer.test.Middleware.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import middy from '@middy/core';
22
import { captureLambdaHandler, Tracer } from '../../src';
33
import { Context } from 'aws-lambda';
4-
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
4+
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb';
55
// eslint-disable-next-line @typescript-eslint/no-var-requires
66
let AWS = require('aws-sdk');
77

@@ -12,6 +12,7 @@ const customMetadataKey = process.env.EXPECTED_CUSTOM_METADATA_KEY ?? 'myMetadat
1212
const customMetadataValue = JSON.parse(process.env.EXPECTED_CUSTOM_METADATA_VALUE) ?? { bar: 'baz' };
1313
const customResponseValue = JSON.parse(process.env.EXPECTED_CUSTOM_RESPONSE_VALUE) ?? { foo: 'bar' };
1414
const customErrorMessage = process.env.EXPECTED_CUSTOM_ERROR_MESSAGE ?? 'An error has occurred';
15+
const testTableName = process.env.TEST_TABLE_NAME ?? 'TestTable';
1516

1617
interface CustomEvent {
1718
throw: boolean
@@ -32,29 +33,29 @@ const refreshAWSSDKImport = (): void => {
3233
};
3334

3435
const tracer = new Tracer({ serviceName: serviceName });
35-
const stsv3 = tracer.captureAWSv3Client(new STSClient({}));
36+
const dynamoDBv3 = tracer.captureAWSv3Client(new DynamoDBClient({}));
3637

3738
export const handler = middy(async (event: CustomEvent, _context: Context): Promise<void> => {
3839
tracer.putAnnotation('invocation', event.invocation);
3940
tracer.putAnnotation(customAnnotationKey, customAnnotationValue);
4041
tracer.putMetadata(customMetadataKey, customMetadataValue);
4142

42-
let stsv2;
43+
let dynamoDBv2;
4344
refreshAWSSDKImport();
4445
if (event.sdkV2 === 'client') {
45-
stsv2 = tracer.captureAWSClient(new AWS.STS());
46+
dynamoDBv2 = tracer.captureAWSClient(new AWS.DynamoDB.DocumentClient());
4647
} else if (event.sdkV2 === 'all') {
4748
AWS = tracer.captureAWS(AWS);
48-
stsv2 = new AWS.STS();
49+
dynamoDBv2 = new AWS.DynamoDB.DocumentClient();
4950
}
5051
try {
51-
await stsv2.getCallerIdentity().promise();
52+
await dynamoDBv2.scan({ TableName: testTableName }).promise();
5253
} catch (err) {
5354
console.error(err);
5455
}
5556

5657
try {
57-
await stsv3.send(new GetCallerIdentityCommand({}));
58+
await dynamoDBv3.send(new ScanCommand({ TableName: testTableName }));
5859
} catch (err) {
5960
console.error(err);
6061
}

0 commit comments

Comments
 (0)