newrelic 8.4.0 → 8.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NEWS.md +79 -25
- package/README.md +7 -6
- package/THIRD_PARTY_NOTICES.md +94 -34
- package/api.js +121 -135
- package/lib/agent.js +11 -2
- package/lib/context-manager/create-context-manager.js +32 -0
- package/lib/context-manager/diagnostics/legacy-diagnostic-context-manager.js +36 -0
- package/lib/context-manager/legacy-context-manager.js +66 -0
- package/lib/feature_flags.js +7 -5
- package/lib/instrumentation/core/http-outbound.js +1 -1
- package/lib/instrumentation/fastify/spec-builders.js +57 -47
- package/lib/instrumentation/fastify.js +85 -24
- package/lib/instrumentation/mongodb/common.js +12 -4
- package/lib/instrumentation/promise.js +28 -41
- package/lib/instrumentation/undici.js +242 -0
- package/lib/instrumentations.js +1 -0
- package/lib/parse-proc-cpuinfo.js +8 -2
- package/lib/parse-proc-meminfo.js +6 -0
- package/lib/serverless/aws-lambda.js +8 -2
- package/lib/shim/message-shim.js +45 -90
- package/lib/shim/shim.js +139 -324
- package/lib/shim/transaction-shim.js +9 -39
- package/lib/shimmer.js +110 -10
- package/lib/transaction/tracer/index.js +24 -22
- package/package.json +8 -5
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
2
|
+
* Copyright 2021 New Relic Corporation. All rights reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Retrieves the IncomingMessage from a Fastify request. Depending on the
|
|
10
|
+
* context of this function it either exists on `request.raw` or just `request`
|
|
11
|
+
*
|
|
12
|
+
* @param {WebFrameworkShim} shim
|
|
13
|
+
* @param {Function} fn middleware function executing
|
|
14
|
+
* @param {string} fnName name of middleware executing
|
|
15
|
+
* @param {args} args that are passed to middleware
|
|
16
|
+
* @returns {IncomingMessage}
|
|
17
|
+
*/
|
|
18
|
+
const getRequestFromFastify = (shim, fn, fnName, args) => {
|
|
19
|
+
const [request] = args
|
|
20
|
+
|
|
21
|
+
// request is Fastify request
|
|
22
|
+
// object, get IncomingMessage from .raw
|
|
10
23
|
if (request && request.raw) {
|
|
11
24
|
return request.raw
|
|
12
25
|
}
|
|
26
|
+
|
|
27
|
+
return request
|
|
13
28
|
}
|
|
14
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves the params from the Fastify request.
|
|
32
|
+
*
|
|
33
|
+
* @param {WebFrameworkShim} shim
|
|
34
|
+
* @param {Function} fn middleware function executing
|
|
35
|
+
* @param {string} fnName name of middleware executing
|
|
36
|
+
* @param {args} args that are passed to middleware
|
|
37
|
+
* @returns {object} URL params on a Fastify request
|
|
38
|
+
*/
|
|
15
39
|
const getParamsFromFastifyRequest = (shim, fn, fnName, args) => {
|
|
16
|
-
const req = args
|
|
40
|
+
const [req] = args
|
|
17
41
|
return req && req.params
|
|
18
42
|
}
|
|
19
43
|
|
|
@@ -21,32 +45,17 @@ const getParamsFromFastifyRequest = (shim, fn, fnName, args) => {
|
|
|
21
45
|
* Builds the recordMiddleware Spec for the route handler
|
|
22
46
|
*
|
|
23
47
|
* A spec is basically a specification -- or a list
|
|
24
|
-
* of
|
|
48
|
+
* of instructions to the recordMiddleware function
|
|
25
49
|
* that provide it with the information it needs to
|
|
26
50
|
* do its job. You could also think of it as a
|
|
27
51
|
* mini-DSL
|
|
52
|
+
*
|
|
53
|
+
* @param {WebFrameworkShim} shim
|
|
54
|
+
* @param {string} path URL route being executed
|
|
55
|
+
* @returns {object} spec for Fastify route handler
|
|
28
56
|
*/
|
|
29
57
|
function buildMiddlewareSpecForRouteHandler(shim, path) {
|
|
30
58
|
return {
|
|
31
|
-
/**
|
|
32
|
-
* The path to use for transaction naming
|
|
33
|
-
*/
|
|
34
|
-
route: path,
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* A function the returns the NodeJS Request Object
|
|
38
|
-
*
|
|
39
|
-
* The job of the `req` callback is to return the current NodeJS
|
|
40
|
-
* IncomingMessage object for this particular handler. Most NodeJS
|
|
41
|
-
* frameworks will pass the request to each handler -- sometimes (as
|
|
42
|
-
* is the case here) wrapped by another object.
|
|
43
|
-
*
|
|
44
|
-
* @param {any} shim the Webframework Shim
|
|
45
|
-
* @param {any} fn the handler function passed to buildMiddlewareSpec
|
|
46
|
-
* @param {any} fnName the handler function's name
|
|
47
|
-
* @param {any} args the arguments passed to the handler function
|
|
48
|
-
*/
|
|
49
|
-
req: getRawRequestFromFastifyRequest,
|
|
50
59
|
/**
|
|
51
60
|
* A function where we can wrap next, reply send, etc. methods
|
|
52
61
|
*
|
|
@@ -66,6 +75,12 @@ function buildMiddlewareSpecForRouteHandler(shim, path) {
|
|
|
66
75
|
* The isFinal param determines whether or not a path is appended for
|
|
67
76
|
* this particular piece of middleware. (i.e. if this is the final handler
|
|
68
77
|
* that is actually handling the request, the path is actually left on)
|
|
78
|
+
*
|
|
79
|
+
* @param shim
|
|
80
|
+
* @param fn
|
|
81
|
+
* @param fnName
|
|
82
|
+
* @param args
|
|
83
|
+
* @param bindSegment
|
|
69
84
|
*/
|
|
70
85
|
next: function wrapNext(shim, fn, fnName, args, bindSegment) {
|
|
71
86
|
const reply = args[1]
|
|
@@ -75,33 +90,28 @@ function buildMiddlewareSpecForRouteHandler(shim, path) {
|
|
|
75
90
|
const isFinal = true
|
|
76
91
|
bindSegment(reply, 'send', isFinal)
|
|
77
92
|
},
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
*
|
|
82
|
-
* @param {any} shim the Webframework Shim
|
|
83
|
-
* @param {any} fn the handler function passed to buildMiddlewareSpec
|
|
84
|
-
* @param {any} fnName the handler function's name
|
|
85
|
-
* @param {any} args the arguments passed to the handler function
|
|
86
|
-
*/
|
|
87
|
-
params: getParamsFromFastifyRequest
|
|
93
|
+
params: getParamsFromFastifyRequest,
|
|
94
|
+
req: getRequestFromFastify,
|
|
95
|
+
route: path
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
98
|
|
|
91
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Spec for all Fastify middleware(excluding route handlers)
|
|
101
|
+
*
|
|
102
|
+
* @param {WebFrameworkShim} shim
|
|
103
|
+
* @param {string} name metric name for middleware being executed
|
|
104
|
+
* @param route
|
|
105
|
+
* @returns {object} spec for Fastify middleware
|
|
106
|
+
*/
|
|
107
|
+
function buildMiddlewareSpecForMiddlewareFunction(shim, name, route) {
|
|
92
108
|
return {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
next:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
const isFinal = false
|
|
101
|
-
bindSegment(next, null, isFinal)
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
params: getParamsFromFastifyRequest
|
|
109
|
+
name,
|
|
110
|
+
route,
|
|
111
|
+
next: shim.LAST,
|
|
112
|
+
params: getParamsFromFastifyRequest,
|
|
113
|
+
req: getRequestFromFastify,
|
|
114
|
+
type: shim.MIDDLEWARE
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
117
|
|
|
@@ -4,11 +4,33 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
|
+
|
|
7
8
|
const semver = require('semver')
|
|
8
9
|
const {
|
|
9
10
|
buildMiddlewareSpecForRouteHandler,
|
|
10
11
|
buildMiddlewareSpecForMiddlewareFunction
|
|
11
12
|
} = require('./fastify/spec-builders')
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* These are the events that occur during a fastify
|
|
16
|
+
* request
|
|
17
|
+
* see: https://www.fastify.io/docs/latest/Lifecycle/
|
|
18
|
+
*
|
|
19
|
+
* Note: preSerialization and onSend happen after the route handler
|
|
20
|
+
* executes. `onResponse` does not execute until after the client
|
|
21
|
+
* sends the response so it'll never be in scope of the transaction
|
|
22
|
+
*/
|
|
23
|
+
const REQUEST_HOOKS = [
|
|
24
|
+
'onRequest',
|
|
25
|
+
'preParsing',
|
|
26
|
+
'preValidation',
|
|
27
|
+
'preHandler',
|
|
28
|
+
'preSerialization',
|
|
29
|
+
'onSend',
|
|
30
|
+
'onResponse',
|
|
31
|
+
'onError'
|
|
32
|
+
]
|
|
33
|
+
|
|
12
34
|
/**
|
|
13
35
|
* Sets up fastify route handler
|
|
14
36
|
*
|
|
@@ -20,6 +42,9 @@ const {
|
|
|
20
42
|
* those private implementations from access, and getting
|
|
21
43
|
* at them would require a lot of gymnastics and hard to
|
|
22
44
|
* maintain code
|
|
45
|
+
*
|
|
46
|
+
* @param shim
|
|
47
|
+
* @param fastify
|
|
23
48
|
*/
|
|
24
49
|
const setupRouteHandler = (shim, fastify) => {
|
|
25
50
|
fastify.addHook('onRoute', (routeOptions) => {
|
|
@@ -27,10 +52,10 @@ const setupRouteHandler = (shim, fastify) => {
|
|
|
27
52
|
return
|
|
28
53
|
}
|
|
29
54
|
/**
|
|
30
|
-
*
|
|
55
|
+
* recordMiddleware handler call
|
|
31
56
|
*
|
|
32
57
|
* The WebFramework shim treats the main route handler like any other
|
|
33
|
-
* i.e. dont be confused by the call to
|
|
58
|
+
* i.e. dont be confused by the call to recordMiddleware -- we don't
|
|
34
59
|
* have a recordRouteHandler, everything goes through recordMiddleware
|
|
35
60
|
*/
|
|
36
61
|
const newRouteHandler = shim.recordMiddleware(
|
|
@@ -40,29 +65,25 @@ const setupRouteHandler = (shim, fastify) => {
|
|
|
40
65
|
|
|
41
66
|
routeOptions.handler = newRouteHandler
|
|
42
67
|
})
|
|
43
|
-
}
|
|
44
68
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return function wrappedFastifyUser() {
|
|
69
|
+
shim.wrap(fastify, 'addHook', function addWrapHook(shim, fn) {
|
|
70
|
+
return function wrappedAddHook() {
|
|
48
71
|
const args = shim.argsToArray.apply(shim, arguments)
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
middlewareFunction
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
args[0] = newMiddlewareFunction
|
|
72
|
+
const hookName = args[0]
|
|
73
|
+
if (REQUEST_HOOKS.includes(hookName)) {
|
|
74
|
+
const middlewareFunction = args[1]
|
|
75
|
+
const name = `${hookName}/${shim.getName(middlewareFunction)}`
|
|
76
|
+
const middlewareSpec = buildMiddlewareSpecForMiddlewareFunction(shim, name)
|
|
77
|
+
const newMiddlewareFunction = shim.recordMiddleware(middlewareFunction, middlewareSpec)
|
|
56
78
|
|
|
79
|
+
args[1] = newMiddlewareFunction
|
|
80
|
+
}
|
|
57
81
|
return fn.apply(this, args)
|
|
58
82
|
}
|
|
59
83
|
})
|
|
60
84
|
}
|
|
61
85
|
|
|
62
86
|
module.exports = function initialize(agent, fastify, moduleName, shim) {
|
|
63
|
-
if (!agent.config.feature_flag.fastify_instrumentation) {
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
87
|
shim.setFramework(shim.FASTIFY)
|
|
67
88
|
|
|
68
89
|
const fastifyVersion = shim.require('./package.json').version
|
|
@@ -73,18 +94,12 @@ module.exports = function initialize(agent, fastify, moduleName, shim) {
|
|
|
73
94
|
*/
|
|
74
95
|
const wrappedExport = shim.wrapExport(fastify, function wrapFastifyModule(shim, fn) {
|
|
75
96
|
return function wrappedFastifyModule() {
|
|
76
|
-
// normalize arguments
|
|
77
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
78
|
-
|
|
79
97
|
// call original function get get fastify object (which is singleton-ish)
|
|
80
|
-
const fastifyForWrapping = fn.apply(this,
|
|
98
|
+
const fastifyForWrapping = fn.apply(this, arguments)
|
|
81
99
|
|
|
82
100
|
setupRouteHandler(shim, fastifyForWrapping)
|
|
83
101
|
|
|
84
|
-
|
|
85
|
-
if (!isv3Plus) {
|
|
86
|
-
setupMiddlewareHandlers(shim, fastifyForWrapping)
|
|
87
|
-
}
|
|
102
|
+
setupMiddlewareHandlers(shim, fastifyForWrapping, isv3Plus)
|
|
88
103
|
|
|
89
104
|
return fastifyForWrapping
|
|
90
105
|
}
|
|
@@ -95,10 +110,56 @@ module.exports = function initialize(agent, fastify, moduleName, shim) {
|
|
|
95
110
|
}
|
|
96
111
|
}
|
|
97
112
|
|
|
113
|
+
function setupMiddlewareHandlers(shim, fastify, isv3Plus) {
|
|
114
|
+
const mounterSpec = {
|
|
115
|
+
route: shim.FIRST,
|
|
116
|
+
wrapper: wrapMiddleware
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (isv3Plus) {
|
|
120
|
+
// Fastify v3+ does not ship with traditional Node.js middleware mounting.
|
|
121
|
+
// This style is accomplished leveraging decorators. Both middie (which was built-in in v2)
|
|
122
|
+
// and fastify-express mount a 'use' function for mounting middleware.
|
|
123
|
+
shim.wrap(fastify, 'decorate', function wrapDecorate(shim, fn) {
|
|
124
|
+
return function wrappedDecorate() {
|
|
125
|
+
const name = arguments[0]
|
|
126
|
+
if (name !== 'use') {
|
|
127
|
+
return fn.apply(this, arguments)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
131
|
+
args[1] = shim.wrapMiddlewareMounter(args[1], mounterSpec)
|
|
132
|
+
|
|
133
|
+
return fn.apply(this, args)
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
} else {
|
|
137
|
+
shim.wrapMiddlewareMounter(fastify, 'use', mounterSpec)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function wrapMiddleware(shim, middleware, name, route) {
|
|
142
|
+
if (shim.isWrapped(middleware)) {
|
|
143
|
+
return middleware
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// prefixing the segment name for middleware execution
|
|
147
|
+
// with the Fastify lifecycle hook
|
|
148
|
+
const segmentName = `onRequest/${name}`
|
|
149
|
+
const spec = buildMiddlewareSpecForMiddlewareFunction(shim, segmentName, route)
|
|
150
|
+
|
|
151
|
+
const newMiddlewareFunction = shim.recordMiddleware(middleware, spec)
|
|
152
|
+
|
|
153
|
+
return newMiddlewareFunction
|
|
154
|
+
}
|
|
155
|
+
|
|
98
156
|
/**
|
|
99
157
|
* module.exports = fastify
|
|
100
158
|
* module.exports.fastify = fastify
|
|
101
159
|
* module.exports.default = fastify
|
|
160
|
+
*
|
|
161
|
+
* @param original
|
|
162
|
+
* @param wrappedExport
|
|
102
163
|
*/
|
|
103
164
|
function setupExports(original, wrappedExport) {
|
|
104
165
|
wrappedExport.fastify = original.fastify
|
|
@@ -47,9 +47,11 @@ common.instrumentCollection = function instrumentCollection(shim, Collection) {
|
|
|
47
47
|
* Instruments all methods from constants.DB_OPS on
|
|
48
48
|
* the Db class.
|
|
49
49
|
*
|
|
50
|
-
* @param {
|
|
50
|
+
* @param {object} params
|
|
51
51
|
* @param {Shim} params.shim
|
|
52
52
|
* @param {Db} params.Db
|
|
53
|
+
* @param shim
|
|
54
|
+
* @param Db
|
|
53
55
|
*/
|
|
54
56
|
common.instrumentDb = function instrumentDb(shim, Db) {
|
|
55
57
|
if (Db && Db.prototype) {
|
|
@@ -62,6 +64,7 @@ common.instrumentDb = function instrumentDb(shim, Db) {
|
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
66
|
* Sets up the desc for all instrumented query methods
|
|
67
|
+
*
|
|
65
68
|
* @param {Shim} shim
|
|
66
69
|
* @param {string} methodName
|
|
67
70
|
*/
|
|
@@ -123,7 +126,7 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(shim, in
|
|
|
123
126
|
* @param {Shim} shim
|
|
124
127
|
* @param {string} connStr
|
|
125
128
|
* @param {string} db database name
|
|
126
|
-
* @param {
|
|
129
|
+
* @param {object} client mongo client instance
|
|
127
130
|
*/
|
|
128
131
|
function setHostPort(shim, connStr, db, client) {
|
|
129
132
|
const parts = connStr.split(':')
|
|
@@ -153,6 +156,9 @@ function setHostPort(shim, connStr, db, client) {
|
|
|
153
156
|
* for the query segment. v4 refactored where the toplogy is stored.
|
|
154
157
|
* You can now get the details via the client obj that's deeply nested
|
|
155
158
|
* See: https://github.com/mongodb/node-mongodb-native/pull/2594/files#diff-1d214e57ddda9095d296e5700ebce701333bfefcf417e234c584d14091b2f50dR168
|
|
159
|
+
*
|
|
160
|
+
* @param shim
|
|
161
|
+
* @param obj
|
|
156
162
|
*/
|
|
157
163
|
function getInstanceAttributeParameters(shim, obj) {
|
|
158
164
|
if (obj.s && obj.s.db && obj.s.topology) {
|
|
@@ -197,8 +203,10 @@ function getInstanceAttributeParameters(shim, obj) {
|
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
function doCapture(conf, database) {
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
// in older versions of 3.x the host/port
|
|
207
|
+
// lived directly on the topology.s.options
|
|
208
|
+
let host = conf.host
|
|
209
|
+
let port = conf.port
|
|
202
210
|
|
|
203
211
|
// servers is an array but we will always pull the first for consistency
|
|
204
212
|
if (conf.servers && conf.servers.length) {
|
|
@@ -11,28 +11,22 @@ const shimmer = require('../shimmer')
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @namespace Library.Spec
|
|
14
|
-
*
|
|
15
14
|
* @property {string} name
|
|
16
15
|
* The name of this promise library.
|
|
17
|
-
*
|
|
18
16
|
* @property {?string} constructor
|
|
19
17
|
* Optional. The name of the property that is the Promise constructor. Default
|
|
20
18
|
* is to use the library itself as the Promise constructor.
|
|
21
|
-
*
|
|
22
19
|
* @property {?bool} executor
|
|
23
20
|
* Optional. If true, the Promise constructor itself will be wrapped for the
|
|
24
21
|
* executor. If false then `_proto`, `_static`, or `_library` must have an
|
|
25
22
|
* `executor` field whose value is the name of the executor function. Default
|
|
26
23
|
* is false.
|
|
27
|
-
*
|
|
28
24
|
* @property {Library.Spec.Mapping} $proto
|
|
29
25
|
* The mapping for Promise instance method concepts (i.e. `then`). These are
|
|
30
26
|
* mapped on the Promise class' prototype.
|
|
31
|
-
*
|
|
32
27
|
* @property {Library.Spec.Mapping} $static
|
|
33
28
|
* The mapping for Promise static method concepts (i.e. `all`, `race`). These
|
|
34
29
|
* are mapped on the Promise class itself.
|
|
35
|
-
*
|
|
36
30
|
* @property {?Library.Spec.Mapping} $library
|
|
37
31
|
* The mapping for library-level static method concepts (i.e. `fcall`, `when`).
|
|
38
32
|
* These are mapped on the library containing the Promise class. NOTE: in most
|
|
@@ -42,35 +36,23 @@ const shimmer = require('../shimmer')
|
|
|
42
36
|
|
|
43
37
|
/**
|
|
44
38
|
* @namespace Library.Spec.Mapping
|
|
45
|
-
*
|
|
46
|
-
* @desc
|
|
39
|
+
* @description
|
|
47
40
|
* A mapping of promise concepts (i.e. `then`) to this library's implementation
|
|
48
41
|
* name(s) (i.e. `["then", "chain"]`). Each value can by either a single string
|
|
49
42
|
* or an array of strings if the concept exists under multiple keys. If any
|
|
50
43
|
* given concept doesn't exist in this library, it is simply skipped.
|
|
51
|
-
*
|
|
52
|
-
* @property {array} $copy
|
|
44
|
+
* @property {Array} $copy
|
|
53
45
|
* An array of properties or methods to just directly copy without wrapping.
|
|
54
46
|
* This field only matters when `Library.Spec.executor` is `true`.
|
|
55
|
-
*
|
|
56
|
-
* @property {string|
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* @property {string|
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* @property {string|array} all
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* @property {string|array} race
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* @property {string|array} resolve
|
|
47
|
+
* @property {string | Array} executor
|
|
48
|
+
* @property {string | Array} then
|
|
49
|
+
* @property {string | Array} all
|
|
50
|
+
* @property {string | Array} race
|
|
51
|
+
* @property {string | Array} resolve
|
|
69
52
|
* Indicates methods to wrap which are resolve factories. This method only
|
|
70
53
|
* requires wrapping if the library doesn't use an executor internally to
|
|
71
54
|
* implement it.
|
|
72
|
-
*
|
|
73
|
-
* @property {string|array} reject
|
|
55
|
+
* @property {string | Array} reject
|
|
74
56
|
* Indicates methods to wrap which are reject factories. Like `resolve`, this
|
|
75
57
|
* method only requires wrapping if the library doesn't use an executor
|
|
76
58
|
* internally to implement it.
|
|
@@ -80,11 +62,13 @@ const shimmer = require('../shimmer')
|
|
|
80
62
|
* Instruments a promise library.
|
|
81
63
|
*
|
|
82
64
|
* @param {Agent} agent - The New Relic APM agent.
|
|
83
|
-
* @param {
|
|
65
|
+
* @param {Function} library - The promise library.
|
|
84
66
|
* @param {?Library.Spec} spec - Spec for this promise library mapping.
|
|
85
67
|
*/
|
|
86
68
|
/* eslint-disable camelcase */
|
|
87
69
|
module.exports = function initialize(agent, library, spec) {
|
|
70
|
+
const contextManager = agent._contextManager
|
|
71
|
+
|
|
88
72
|
if (spec.useFinally == null) {
|
|
89
73
|
spec.useFinally = true
|
|
90
74
|
}
|
|
@@ -144,7 +128,7 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
144
128
|
return Promise(executor) // eslint-disable-line new-cap
|
|
145
129
|
}
|
|
146
130
|
|
|
147
|
-
const parent =
|
|
131
|
+
const parent = contextManager.getContext()
|
|
148
132
|
let promise = null
|
|
149
133
|
if (
|
|
150
134
|
!parent ||
|
|
@@ -170,15 +154,13 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
170
154
|
const segment = _createSegment(segmentName)
|
|
171
155
|
Contextualizer.link(null, promise, segment, spec.useFinally)
|
|
172
156
|
|
|
173
|
-
agent.tracer.segment = segment
|
|
174
157
|
segment.start()
|
|
175
158
|
try {
|
|
176
159
|
// Must run after promise is defined so that `__NR_wrapper` can be set.
|
|
177
|
-
|
|
160
|
+
contextManager.runInContext(segment, executor, context.self, context.args)
|
|
178
161
|
} catch (e) {
|
|
179
162
|
context.args[1](e)
|
|
180
163
|
} finally {
|
|
181
|
-
agent.tracer.segment = parent
|
|
182
164
|
segment.touch()
|
|
183
165
|
}
|
|
184
166
|
}
|
|
@@ -259,8 +241,7 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
259
241
|
* execution.
|
|
260
242
|
*
|
|
261
243
|
* @param {object} context - The object to export the execution context with.
|
|
262
|
-
*
|
|
263
|
-
* @return {function} A function which, when executed, will add its context
|
|
244
|
+
* @returns {Function} A function which, when executed, will add its context
|
|
264
245
|
* and arguments to the `context` parameter.
|
|
265
246
|
*/
|
|
266
247
|
function wrapExecutorContext(context) {
|
|
@@ -285,7 +266,9 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
285
266
|
/**
|
|
286
267
|
* Creates a wrapper for `Promise#then` that extends the transaction context.
|
|
287
268
|
*
|
|
288
|
-
* @
|
|
269
|
+
* @param then
|
|
270
|
+
* @param name
|
|
271
|
+
* @returns {Function} A wrapped version of `Promise#then`.
|
|
289
272
|
*/
|
|
290
273
|
function wrapThen(then, name) {
|
|
291
274
|
return _wrapThen(then, name, true)
|
|
@@ -294,7 +277,9 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
294
277
|
/**
|
|
295
278
|
* Creates a wrapper for `Promise#catch` that extends the transaction context.
|
|
296
279
|
*
|
|
297
|
-
* @
|
|
280
|
+
* @param cach
|
|
281
|
+
* @param name
|
|
282
|
+
* @returns {Function} A wrapped version of `Promise#catch`.
|
|
298
283
|
*/
|
|
299
284
|
function wrapCatch(cach, name) {
|
|
300
285
|
return _wrapThen(cach, name, false)
|
|
@@ -303,14 +288,13 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
303
288
|
/**
|
|
304
289
|
* Creates a wrapper for promise chain extending methods.
|
|
305
290
|
*
|
|
306
|
-
* @param {
|
|
291
|
+
* @param {Function} then
|
|
307
292
|
* The function we are to wrap as a chain extender.
|
|
308
|
-
*
|
|
293
|
+
* @param name
|
|
309
294
|
* @param {bool} useAllParams
|
|
310
295
|
* When true, all parameters which are functions will be wrapped. Otherwise,
|
|
311
296
|
* only the last parameter will be wrapped.
|
|
312
|
-
*
|
|
313
|
-
* @return {function} A wrapped version of the function.
|
|
297
|
+
* @returns {Function} A wrapped version of the function.
|
|
314
298
|
*/
|
|
315
299
|
function _wrapThen(then, name, useAllParams) {
|
|
316
300
|
// Don't wrap non-functions.
|
|
@@ -377,6 +361,9 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
377
361
|
|
|
378
362
|
/**
|
|
379
363
|
* Creates a wrapper around the static `Promise` factory method.
|
|
364
|
+
*
|
|
365
|
+
* @param cast
|
|
366
|
+
* @param name
|
|
380
367
|
*/
|
|
381
368
|
function wrapCast(cast, name) {
|
|
382
369
|
if (typeof cast !== 'function' || cast.name === '__NR_wrappedCast') {
|
|
@@ -437,8 +424,8 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
437
424
|
*
|
|
438
425
|
* @param {object} obj - The source of the methods to wrap.
|
|
439
426
|
* @param {string} name - The name of this source.
|
|
440
|
-
* @param {string|
|
|
441
|
-
* @param {
|
|
427
|
+
* @param {string | Array} methods - The names of the methods to wrap.
|
|
428
|
+
* @param {Function} wrapper - The function which wraps the methods.
|
|
442
429
|
*/
|
|
443
430
|
function _safeWrap(obj, name, methods, wrapper) {
|
|
444
431
|
if (methods && methods.length) {
|