File tree Expand file tree Collapse file tree 4 files changed +88
-0
lines changed
packages/instrumentation-aws-sdk Expand file tree Collapse file tree 4 files changed +88
-0
lines changed Original file line number Diff line number Diff 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 ) |
Original file line number Diff line number Diff line change @@ -233,6 +233,30 @@ export class AwsInstrumentation extends InstrumentationBase<AwsSdkInstrumentatio
233233 ) ;
234234 }
235235
236+ private _callUserExceptionResponseHook (
237+ span : Span ,
238+ request : NormalizedRequest ,
239+ err : any
240+ ) {
241+ const { exceptionHook } = this . getConfig ( ) ;
242+ if ( ! exceptionHook ) return ;
243+ const requestInfo : AwsSdkRequestHookInformation = {
244+ request,
245+ } ;
246+
247+ safeExecuteInTheMiddle (
248+ ( ) => exceptionHook ( span , requestInfo , err ) ,
249+ ( e : Error | undefined ) => {
250+ if ( e )
251+ diag . error (
252+ `${ AwsInstrumentation . component } instrumentation: exceptionHook error` ,
253+ e
254+ ) ;
255+ } ,
256+ true
257+ ) ;
258+ }
259+
236260 private _getV3ConstructStackPatch (
237261 moduleVersion : string | undefined ,
238262 original : ( ...args : unknown [ ] ) => MiddlewareStack < any , any >
@@ -443,6 +467,11 @@ export class AwsInstrumentation extends InstrumentationBase<AwsSdkInstrumentatio
443467 message : err . message ,
444468 } ) ;
445469 span . recordException ( err ) ;
470+ self . _callUserExceptionResponseHook (
471+ span ,
472+ normalizedRequest ,
473+ err
474+ ) ;
446475 throw err ;
447476 } )
448477 . finally ( ( ) => {
Original file line number Diff line number Diff 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+
6069export 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
Original file line number Diff line number Diff line change @@ -270,5 +270,48 @@ 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+ suppressInternalInstrumentation : true ,
289+ } ) ;
290+ instrumentation . enable ( ) ;
291+
292+ nock ( `https://ot-demo-test.s3.${ region } .amazonaws.com/` )
293+ . put ( '/aws-ot-s3-test-object.txt?x-id=PutObject' )
294+ . reply (
295+ 404 ,
296+ fs . readFileSync ( './test/mock-responses/s3-put-object.xml' , 'utf8' )
297+ ) ;
298+
299+ const params = {
300+ Bucket : 'ot-demo-test' ,
301+ Key : 'aws-ot-s3-test-object.txt' ,
302+ } ;
303+ try {
304+ await s3Client . putObject ( params ) ;
305+ } catch {
306+ expect ( getTestSpans ( ) . length ) . toBe ( 1 ) ;
307+ const [ span ] = getTestSpans ( ) ;
308+ expect ( span . attributes [ 'attribute.from.exception.hook' ] ) . toEqual (
309+ params . Bucket
310+ ) ;
311+ expect ( span . attributes [ 'error.from.exception.hook' ] ) . toEqual (
312+ 'NotFound'
313+ ) ;
314+ }
315+ } ) ;
273316 } ) ;
274317} ) ;
You can’t perform that action at this time.
0 commit comments