Skip to content

Commit 8586074

Browse files
committed
feat(aws-sdk): add exception hook
1 parent 215c2b5 commit 8586074

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

packages/instrumentation-aws-sdk/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ aws-sdk instrumentation has few options available to choose from. You can set th
5252
| ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
5353
| `preRequestHook` | `AwsSdkRequestCustomAttributeFunction` | Hook called before request send, which allow to add custom attributes to span. |
5454
| `responseHook` | `AwsSdkResponseCustomAttributeFunction` | Hook for adding custom attributes when response is received from aws. |
55+
| `exceptionHook` | `AwsSdkExceptionCustomAttributeFunction` | Hook for adding custom attributes when exception is received from aws. |
5556
| `sqsProcessHook` | `AwsSdkSqsProcessCustomAttributeFunction` | Hook called after starting sqs `process` span (for each sqs received message), which allow to add custom attributes to it. |
5657
| `suppressInternalInstrumentation` | `boolean` | Most aws operation use http requests under the hood. Set this to `true` to hide all underlying http spans. |
5758
| `sqsExtractContextPropagationFromPayload` | `boolean` | Will parse and extract context propagation headers from SQS Payload, false by default. [When should it be used?](./doc/sns.md#integration-with-sqs) |

packages/instrumentation-aws-sdk/src/aws-sdk.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,11 @@ export class AwsInstrumentation extends InstrumentationBase<AwsSdkInstrumentatio
443443
message: err.message,
444444
});
445445
span.recordException(err);
446+
self._callUserExceptionResponseHook(
447+
span,
448+
normalizedRequest,
449+
err
450+
);
446451
throw err;
447452
})
448453
.finally(() => {

packages/instrumentation-aws-sdk/src/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export interface AwsSdkResponseHookInformation {
4848
moduleVersion?: string;
4949
response: NormalizedResponse;
5050
}
51+
5152
/**
5253
* span can be used to add custom attributes, or for any other need.
5354
* response is the object that is returned to the user calling the aws-sdk operation.
@@ -57,6 +58,14 @@ export interface AwsSdkResponseCustomAttributeFunction {
5758
(span: Span, responseInfo: AwsSdkResponseHookInformation): void;
5859
}
5960

61+
/**
62+
* span can be used to modify the status.
63+
* As we have no response object, the request can be used to determine the failed aws-sdk operation.
64+
*/
65+
export interface AwsSdkExceptionCustomAttributeFunction {
66+
(span: Span, requestInfo: AwsSdkRequestHookInformation, err: any): void;
67+
}
68+
6069
export interface AwsSdkSqsProcessHookInformation {
6170
message: SQS.Message;
6271
}
@@ -76,6 +85,12 @@ export interface AwsSdkInstrumentationConfig extends InstrumentationConfig {
7685
/** hook for adding custom attributes when response is received from aws */
7786
responseHook?: AwsSdkResponseCustomAttributeFunction;
7887

88+
/**
89+
* Hook for adding custom attributes when exception is received from aws.
90+
* This hook is only available with aws sdk v3
91+
*/
92+
exceptionHook?: AwsSdkExceptionCustomAttributeFunction;
93+
7994
/** hook for adding custom attribute when an sqs process span is started */
8095
sqsProcessHook?: AwsSdkSqsProcessCustomAttributeFunction;
8196

packages/instrumentation-aws-sdk/test/aws-sdk-v3-s3.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,5 +270,49 @@ describe('instrumentation-aws-sdk-v3 (client-s3)', () => {
270270
);
271271
});
272272
});
273+
274+
it('handle aws sdk exception', async () => {
275+
instrumentation.disable();
276+
instrumentation.setConfig({
277+
exceptionHook: (
278+
span: Span,
279+
requestInfo: AwsSdkRequestHookInformation,
280+
err: any
281+
) => {
282+
span.setAttribute(
283+
'attribute.from.exception.hook',
284+
requestInfo.request.commandInput.Bucket
285+
);
286+
span.setAttribute('error.from.exception.hook', err.name);
287+
},
288+
289+
suppressInternalInstrumentation: true,
290+
});
291+
instrumentation.enable();
292+
293+
nock(`https://ot-demo-test.s3.${region}.amazonaws.com/`)
294+
.put('/aws-ot-s3-test-object.txt?x-id=PutObject')
295+
.reply(
296+
404,
297+
fs.readFileSync('./test/mock-responses/s3-put-object.xml', 'utf8')
298+
);
299+
300+
const params = {
301+
Bucket: 'ot-demo-test',
302+
Key: 'aws-ot-s3-test-object.txt',
303+
};
304+
try {
305+
await s3Client.putObject(params);
306+
} catch {
307+
expect(getTestSpans().length).toBe(1);
308+
const [span] = getTestSpans();
309+
expect(span.attributes['attribute.from.exception.hook']).toEqual(
310+
params.Bucket
311+
);
312+
expect(span.attributes['error.from.exception.hook']).toEqual(
313+
'NotFound'
314+
);
315+
}
316+
});
273317
});
274318
});

0 commit comments

Comments
 (0)