@@ -52,76 +52,83 @@ function instrumentationS3 (orig, origArguments, request, AWS, agent, { version,
5252 name += ' ' + resource
5353 }
5454
55- const span = agent . startSpan ( name , TYPE , SUBTYPE , opName )
56- if ( span ) {
57- request . on ( 'complete' , function onComplete ( response ) {
58- // `response` is an AWS.Response
59- // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html
60-
61- // Determining the bucket's region.
62- // `request.httpRequest.region` isn't documented, but the aws-sdk@2
63- // lib/services/s3.js will set it to the bucket's determined region.
64- // This can be asynchronously determined -- e.g. if it differs from the
65- // configured service endpoint region -- so this won't be set until
66- // 'complete'.
67- const region = request . httpRequest && request . httpRequest . region
68-
69- // Destination context.
70- // '.httpRequest.endpoint' might differ from '.service.endpoint' if
71- // the bucket is in a different region.
72- const endpoint = request . httpRequest && request . httpRequest . endpoint
73- const destContext = {
74- service : {
75- name : SUBTYPE ,
76- type : TYPE
77- }
78- }
79- if ( endpoint ) {
80- destContext . address = endpoint . hostname
81- destContext . port = endpoint . port
82- }
83- if ( resource ) {
84- destContext . service . resource = resource
55+ const ins = agent . _instrumentation
56+ const span = ins . currTx ( ) . startSpan ( name , TYPE , SUBTYPE , opName )
57+ if ( ! span ) {
58+ return orig . apply ( request , origArguments )
59+ }
60+
61+ function onComplete ( response ) {
62+ // `response` is an AWS.Response
63+ // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html
64+
65+ // Determining the bucket's region.
66+ // `request.httpRequest.region` isn't documented, but the aws-sdk@2
67+ // lib/services/s3.js will set it to the bucket's determined region.
68+ // This can be asynchronously determined -- e.g. if it differs from the
69+ // configured service endpoint region -- so this won't be set until
70+ // 'complete'.
71+ const region = request . httpRequest && request . httpRequest . region
72+
73+ // Destination context.
74+ // '.httpRequest.endpoint' might differ from '.service.endpoint' if
75+ // the bucket is in a different region.
76+ const endpoint = request . httpRequest && request . httpRequest . endpoint
77+ const destContext = {
78+ service : {
79+ name : SUBTYPE ,
80+ type : TYPE
8581 }
86- if ( region ) {
87- destContext . cloud = { region }
82+ }
83+ if ( endpoint ) {
84+ destContext . address = endpoint . hostname
85+ destContext . port = endpoint . port
86+ }
87+ if ( resource ) {
88+ destContext . service . resource = resource
89+ }
90+ if ( region ) {
91+ destContext . cloud = { region }
92+ }
93+ span . setDestinationContext ( destContext )
94+
95+ if ( response ) {
96+ // Follow the spec for HTTP client span outcome.
97+ // https://github.com/elastic/apm/blob/master/specs/agents/tracing-instrumentation-http.md#outcome
98+ //
99+ // For example, a S3 GetObject conditional request (e.g. using the
100+ // IfNoneMatch param) will respond with response.error=NotModifed and
101+ // statusCode=304. This is a *successful* outcome.
102+ const statusCode = response . httpResponse && response . httpResponse . statusCode
103+ if ( statusCode ) {
104+ span . _setOutcomeFromHttpStatusCode ( statusCode )
105+ } else {
106+ // `statusCode` will be undefined for errors before sending a request, e.g.:
107+ // InvalidConfiguration: Custom endpoint is not compatible with access point ARN
108+ span . _setOutcomeFromErrorCapture ( constants . OUTCOME_FAILURE )
88109 }
89- span . setDestinationContext ( destContext )
90-
91- if ( response ) {
92- // Follow the spec for HTTP client span outcome.
93- // https://github.com/elastic/apm/blob/master/specs/agents/tracing-instrumentation-http.md#outcome
94- //
95- // For example, a S3 GetObject conditional request (e.g. using the
96- // IfNoneMatch param) will respond with response.error=NotModifed and
97- // statusCode=304. This is a *successful* outcome.
98- const statusCode = response . httpResponse && response . httpResponse . statusCode
99- if ( statusCode ) {
100- span . _setOutcomeFromHttpStatusCode ( statusCode )
101- } else {
102- // `statusCode` will be undefined for errors before sending a request, e.g.:
103- // InvalidConfiguration: Custom endpoint is not compatible with access point ARN
104- span . _setOutcomeFromErrorCapture ( constants . OUTCOME_FAILURE )
105- }
106-
107- if ( response . error && ( ! statusCode || statusCode >= 400 ) ) {
108- agent . captureError ( response . error , { skipOutcome : true } )
109- }
110+
111+ if ( response . error && ( ! statusCode || statusCode >= 400 ) ) {
112+ agent . captureError ( response . error , { skipOutcome : true } )
110113 }
114+ }
111115
112- // Workaround a bug in the agent's handling of `span.sync`.
113- //
114- // The bug: Currently this span.sync is not set `false` because there is
115- // an HTTP span created (for this S3 request) in the same async op. That
116- // HTTP span becomes the "active span" for this async op, and *it* gets
117- // marked as sync=false in `before()` in async-hooks.js.
118- span . sync = false
119-
120- span . end ( )
121- } )
116+ // Workaround a bug in the agent's handling of `span.sync`.
117+ //
118+ // The bug: Currently this span.sync is not set `false` because there is
119+ // an HTTP span created (for this S3 request) in the same async op. That
120+ // HTTP span becomes the "active span" for this async op, and *it* gets
121+ // marked as sync=false in `before()` in async-hooks.js.
122+ span . sync = false
123+
124+ span . end ( )
122125 }
123126
124- return orig . apply ( request , origArguments )
127+ // Derive a new run context from the current one for this span. Then run
128+ // the AWS.Request.send and a 'complete' event handler in that run context.
129+ const runContext = ins . _runCtxMgr . active ( ) . enterSpan ( span ) // XXX I don't like `enterSpan` name here, perhaps `newWithSpan()`?
130+ request . on ( 'complete' , ins . _runCtxMgr . bind ( runContext , onComplete ) )
131+ return ins . _runCtxMgr . with ( runContext , orig , request , ...origArguments )
125132}
126133
127134module . exports = {
0 commit comments