newrelic 9.4.0 → 9.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 +18 -0
- package/README.md +8 -6
- package/index.js +6 -5
- package/lib/collector/remote-method.js +2 -1
- package/lib/config/default.js +528 -287
- package/lib/config/formatters.js +108 -0
- package/lib/config/index.js +69 -91
- package/lib/instrumentation/@hapi/hapi.js +229 -1
- package/lib/instrumentation/{vision.js → @hapi/vision.js} +0 -0
- package/lib/instrumentation/core/async_hooks.js +1 -4
- package/lib/instrumentation/core/globals.js +2 -3
- package/lib/instrumentation/core/http-outbound.js +3 -5
- package/lib/instrumentation/core/http.js +6 -19
- package/lib/instrumentation/core/timers.js +3 -1
- package/lib/instrumentation/mysql/mysql.js +6 -5
- package/lib/instrumentation/promise.js +16 -15
- package/lib/instrumentation/undici.js +10 -15
- package/lib/instrumentations.js +1 -1
- package/lib/shim/constants.js +1 -16
- package/lib/shim/datastore-shim.js +2 -1
- package/lib/shim/promise-shim.js +18 -17
- package/lib/shim/shim.js +37 -82
- package/lib/shim/transaction-shim.js +1 -1
- package/lib/shim/webframework-shim.js +2 -8
- package/lib/shimmer.js +29 -23
- package/lib/symbols.js +26 -0
- package/lib/system-info.js +1 -2
- package/lib/transaction/tracer/index.js +12 -18
- package/lib/util/arity.js +4 -9
- package/lib/util/properties.js +0 -46
- package/package.json +3 -3
- package/lib/config/env.js +0 -294
- package/lib/instrumentation/hapi/hapi.js +0 -207
- package/lib/instrumentation/hapi/shared.js +0 -28
- package/lib/instrumentation/hapi.js +0 -254
package/lib/shim/shim.js
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const arity = require('../util/arity')
|
|
9
|
-
const constants = require('./constants')
|
|
10
9
|
const hasOwnProperty = require('../util/properties').hasOwn
|
|
11
10
|
const logger = require('../logger').child({ component: 'Shim' })
|
|
12
11
|
const path = require('path')
|
|
13
12
|
const specs = require('./specs')
|
|
14
13
|
const util = require('util')
|
|
14
|
+
const symbols = require('../symbols')
|
|
15
15
|
|
|
16
16
|
// Some modules do terrible things, like change the prototype of functions. To
|
|
17
17
|
// avoid crashing things we'll use a cached copy of apply everywhere.
|
|
@@ -52,14 +52,14 @@ module.exports = Shim
|
|
|
52
52
|
Shim.defineProperty = defineProperty
|
|
53
53
|
Shim.defineProperties = defineProperties
|
|
54
54
|
|
|
55
|
+
// This is for backwards compat for external libraries like aws-sdk that expect the symbol to be defined here
|
|
56
|
+
defineProperty(Shim, 'DISABLE_DT', symbols.disableDT)
|
|
57
|
+
defineProperty(Shim.prototype, 'DISABLE_DT', symbols.disableDT)
|
|
58
|
+
|
|
55
59
|
// Copy the argument index enumeration onto the shim.
|
|
56
60
|
Shim.prototype.ARG_INDEXES = specs.ARG_INDEXES
|
|
57
61
|
defineProperties(Shim.prototype, specs.ARG_INDEXES)
|
|
58
62
|
|
|
59
|
-
// Copy symbols to the shim as well.
|
|
60
|
-
defineProperties(Shim, constants.SYMBOLS)
|
|
61
|
-
defineProperties(Shim.prototype, constants.SYMBOLS)
|
|
62
|
-
|
|
63
63
|
// Define other miscellaneous properties of the shim.
|
|
64
64
|
defineProperties(Shim.prototype, {
|
|
65
65
|
/**
|
|
@@ -130,8 +130,6 @@ Shim.prototype.argsToArray = argsToArray
|
|
|
130
130
|
Shim.prototype.normalizeIndex = normalizeIndex
|
|
131
131
|
Shim.prototype.once = once
|
|
132
132
|
|
|
133
|
-
Shim.prototype.setInternalProperty = setInternalProperty
|
|
134
|
-
|
|
135
133
|
Shim.prototype.defineProperty = defineProperty
|
|
136
134
|
Shim.prototype.defineProperties = defineProperties
|
|
137
135
|
Shim.prototype.setDefaults = setDefaults
|
|
@@ -144,7 +142,7 @@ Shim.prototype.fixArity = arity.fixArity
|
|
|
144
142
|
// Internal methods.
|
|
145
143
|
Shim.prototype.getExport = getExport
|
|
146
144
|
Shim.prototype.enableDebug = enableDebug
|
|
147
|
-
Shim.prototype.
|
|
145
|
+
Shim.prototype[symbols.unwrap] = unwrapAll
|
|
148
146
|
|
|
149
147
|
// -------------------------------------------------------------------------- //
|
|
150
148
|
|
|
@@ -291,10 +289,10 @@ Shim.prototype.__NR_unwrap = unwrapAll
|
|
|
291
289
|
* `true`. Good for preventing double wrapping of prototype methods.
|
|
292
290
|
*
|
|
293
291
|
* ```js
|
|
294
|
-
* if (spec.$once && spec.
|
|
292
|
+
* if (spec.$once && spec[symbols.onceExecuted]) {
|
|
295
293
|
* return context
|
|
296
294
|
* }
|
|
297
|
-
* spec.
|
|
295
|
+
* spec[symbols.onceExecuted] = true
|
|
298
296
|
* ```
|
|
299
297
|
* @property {ArgumentsFunction} $arguments
|
|
300
298
|
* Executes the function with all of the arguments passed in. The arguments can
|
|
@@ -522,7 +520,7 @@ function wrap(nodule, properties, spec, args) {
|
|
|
522
520
|
}
|
|
523
521
|
}
|
|
524
522
|
|
|
525
|
-
// TODO: Add option for omitting
|
|
523
|
+
// TODO: Add option for omitting symbols.original; unwrappable: false
|
|
526
524
|
spec = this.setDefaults(spec, { matchArity: false })
|
|
527
525
|
|
|
528
526
|
// If we're just wrapping one thing, just wrap it and return.
|
|
@@ -553,10 +551,10 @@ function wrap(nodule, properties, spec, args) {
|
|
|
553
551
|
this.logger.trace('Replacing "%s" with wrapped version', prop)
|
|
554
552
|
|
|
555
553
|
nodule[prop] = wrapped
|
|
556
|
-
|
|
554
|
+
wrapped[symbols.unwrap] = function unwrapWrap() {
|
|
557
555
|
nodule[prop] = original
|
|
558
556
|
return original
|
|
559
|
-
}
|
|
557
|
+
}
|
|
560
558
|
}
|
|
561
559
|
}, this)
|
|
562
560
|
return nodule
|
|
@@ -614,17 +612,17 @@ function wrapReturn(nodule, properties, spec, args) {
|
|
|
614
612
|
const handler = {
|
|
615
613
|
get: function getTrap(target, prop) {
|
|
616
614
|
// Allow for look up of the target
|
|
617
|
-
if (prop ===
|
|
615
|
+
if (prop === symbols.original) {
|
|
618
616
|
return target
|
|
619
617
|
}
|
|
620
|
-
if (prop ===
|
|
618
|
+
if (prop === symbols.unwrap) {
|
|
621
619
|
return unwrapReference
|
|
622
620
|
}
|
|
623
621
|
|
|
624
622
|
return target[prop]
|
|
625
623
|
},
|
|
626
624
|
defineProperty: function definePropertyTrap(target, key, descriptor) {
|
|
627
|
-
if (key ===
|
|
625
|
+
if (key === symbols.unwrap) {
|
|
628
626
|
unwrapReference = descriptor.value
|
|
629
627
|
} else {
|
|
630
628
|
Object.defineProperty(target, key, descriptor)
|
|
@@ -632,7 +630,7 @@ function wrapReturn(nodule, properties, spec, args) {
|
|
|
632
630
|
return true
|
|
633
631
|
},
|
|
634
632
|
set: function setTrap(target, key, val) {
|
|
635
|
-
if (key ===
|
|
633
|
+
if (key === symbols.unwrap) {
|
|
636
634
|
unwrapReference = val
|
|
637
635
|
} else {
|
|
638
636
|
target[key] = val
|
|
@@ -784,9 +782,9 @@ function getExport(defaultExport) {
|
|
|
784
782
|
*/
|
|
785
783
|
function isWrapped(nodule, property) {
|
|
786
784
|
if (property) {
|
|
787
|
-
return !!(nodule && nodule[property] && nodule[property].
|
|
785
|
+
return !!(nodule && nodule[property] && nodule[property][symbols.original])
|
|
788
786
|
}
|
|
789
|
-
return !!(nodule && nodule.
|
|
787
|
+
return !!(nodule && nodule[symbols.original])
|
|
790
788
|
}
|
|
791
789
|
|
|
792
790
|
/**
|
|
@@ -991,10 +989,10 @@ function unwrap(nodule, properties) {
|
|
|
991
989
|
|
|
992
990
|
this.logger.trace('Unwrapping %s', properties || '<nodule>')
|
|
993
991
|
let original = properties ? nodule[properties] : nodule
|
|
994
|
-
while (original && original.
|
|
995
|
-
original = this.isFunction(original.
|
|
996
|
-
? original.
|
|
997
|
-
: original.
|
|
992
|
+
while (original && original[symbols.original]) {
|
|
993
|
+
original = this.isFunction(original[symbols.unwrap])
|
|
994
|
+
? original[symbols.unwrap]()
|
|
995
|
+
: original[symbols.original]
|
|
998
996
|
}
|
|
999
997
|
return original
|
|
1000
998
|
}
|
|
@@ -1030,10 +1028,10 @@ function unwrapOnce(nodule, properties) {
|
|
|
1030
1028
|
|
|
1031
1029
|
this.logger.trace('Unwrapping %s', properties || '<nodule>')
|
|
1032
1030
|
let original = properties ? nodule[properties] : nodule
|
|
1033
|
-
if (original && original.
|
|
1034
|
-
original = this.isFunction(original.
|
|
1035
|
-
? original.
|
|
1036
|
-
: original.
|
|
1031
|
+
if (original && original[symbols.original]) {
|
|
1032
|
+
original = this.isFunction(original[symbols.unwrap])
|
|
1033
|
+
? original[symbols.unwrap]()
|
|
1034
|
+
: original[symbols.original]
|
|
1037
1035
|
}
|
|
1038
1036
|
return original
|
|
1039
1037
|
}
|
|
@@ -1057,8 +1055,8 @@ function getOriginal(nodule, property) {
|
|
|
1057
1055
|
}
|
|
1058
1056
|
|
|
1059
1057
|
let original = property ? nodule[property] : nodule
|
|
1060
|
-
while (original && original.
|
|
1061
|
-
original = original.
|
|
1058
|
+
while (original && original[symbols.original]) {
|
|
1059
|
+
original = original[symbols.original]
|
|
1062
1060
|
}
|
|
1063
1061
|
return original
|
|
1064
1062
|
}
|
|
@@ -1206,8 +1204,8 @@ function bindCallbackSegment(args, cbIdx, parentSegment) {
|
|
|
1206
1204
|
* with the object.
|
|
1207
1205
|
*/
|
|
1208
1206
|
function getSegment(obj) {
|
|
1209
|
-
if (obj && obj.
|
|
1210
|
-
return obj.
|
|
1207
|
+
if (obj && obj[symbols.segment]) {
|
|
1208
|
+
return obj[symbols.segment]
|
|
1211
1209
|
}
|
|
1212
1210
|
|
|
1213
1211
|
return this._contextManager.getContext()
|
|
@@ -1264,7 +1262,9 @@ function setActiveSegment(segment) {
|
|
|
1264
1262
|
* @param {TraceSegment} [segment] - The segment to link the object to.
|
|
1265
1263
|
*/
|
|
1266
1264
|
function storeSegment(obj, segment) {
|
|
1267
|
-
|
|
1265
|
+
if (obj) {
|
|
1266
|
+
obj[symbols.segment] = segment || this.getSegment()
|
|
1267
|
+
}
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
1270
|
/* eslint-disable max-params */
|
|
@@ -1313,7 +1313,7 @@ function applySegment(func, segment, full, context, args, inContextCB) {
|
|
|
1313
1313
|
return fnApply.call(func, context, args)
|
|
1314
1314
|
} catch (error) {
|
|
1315
1315
|
if (prevSegment === null && process.domain != null) {
|
|
1316
|
-
process.domain.
|
|
1316
|
+
process.domain[symbols.segment] = contextManager.getContext()
|
|
1317
1317
|
}
|
|
1318
1318
|
|
|
1319
1319
|
throw error // Re-throwing application error, this is not an agent error.
|
|
@@ -1571,51 +1571,6 @@ function once(fn) {
|
|
|
1571
1571
|
}
|
|
1572
1572
|
}
|
|
1573
1573
|
|
|
1574
|
-
/**
|
|
1575
|
-
* Sets a property to the given value. If the property doesn't exist yet it will
|
|
1576
|
-
* be made writable and non-enumerable.
|
|
1577
|
-
*
|
|
1578
|
-
* @memberof Shim.prototype
|
|
1579
|
-
* @param {!object} obj - The object to add the property to.
|
|
1580
|
-
* @param {!string} name - The name for this property.
|
|
1581
|
-
* @param {*} val - The value to set the property as.
|
|
1582
|
-
* @returns {object} The `obj` value.
|
|
1583
|
-
*/
|
|
1584
|
-
function setInternalProperty(obj, name, val) {
|
|
1585
|
-
if (!obj || !name) {
|
|
1586
|
-
this.logger.debug('Not setting property; object or name is missing.')
|
|
1587
|
-
return obj
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
try {
|
|
1591
|
-
if (this.agent.config.transaction_tracer.hide_internals) {
|
|
1592
|
-
_slowSetInternalProperty(obj, name, val)
|
|
1593
|
-
} else {
|
|
1594
|
-
obj[name] = val
|
|
1595
|
-
}
|
|
1596
|
-
} catch (err) {
|
|
1597
|
-
this.logger.debug(err, 'Failed to set property "%s" to %j', name, val)
|
|
1598
|
-
}
|
|
1599
|
-
return obj
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
/**
|
|
1603
|
-
* @param obj
|
|
1604
|
-
* @param name
|
|
1605
|
-
* @param val
|
|
1606
|
-
*/
|
|
1607
|
-
function _slowSetInternalProperty(obj, name, val) {
|
|
1608
|
-
if (!hasOwnProperty(obj, name)) {
|
|
1609
|
-
Object.defineProperty(obj, name, {
|
|
1610
|
-
enumerable: false,
|
|
1611
|
-
writable: true,
|
|
1612
|
-
value: val
|
|
1613
|
-
})
|
|
1614
|
-
} else {
|
|
1615
|
-
obj[name] = val
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
1574
|
/**
|
|
1620
1575
|
* Defines a read-only property on the given object.
|
|
1621
1576
|
*
|
|
@@ -1805,7 +1760,7 @@ function enableDebug() {
|
|
|
1805
1760
|
* enabled first.
|
|
1806
1761
|
*
|
|
1807
1762
|
* @private
|
|
1808
|
-
* @member Shim.prototype.
|
|
1763
|
+
* @member Shim.prototype.unwrap
|
|
1809
1764
|
*/
|
|
1810
1765
|
function unwrapAll() {
|
|
1811
1766
|
if (this._wrapped) {
|
|
@@ -1870,9 +1825,9 @@ function _wrap(shim, original, name, spec, args) {
|
|
|
1870
1825
|
|
|
1871
1826
|
// TODO: Once all wrapping is converted to proxies, we won't need to
|
|
1872
1827
|
// set this property as the trap on 'get' will return the original for
|
|
1873
|
-
//
|
|
1874
|
-
if (!wrapped.
|
|
1875
|
-
|
|
1828
|
+
// symbols.original. For now, we have to prevent setting this on original.
|
|
1829
|
+
if (!wrapped[symbols.original]) {
|
|
1830
|
+
wrapped[symbols.original] = original
|
|
1876
1831
|
}
|
|
1877
1832
|
|
|
1878
1833
|
if (shim._debug) {
|
|
@@ -295,7 +295,7 @@ function insertCATRequestHeaders(headers, useAlternateHeaderNames) {
|
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
if (distributedTracingEnabled) {
|
|
298
|
-
// TODO: Should probably honor
|
|
298
|
+
// TODO: Should probably honor symbols.disableDT.
|
|
299
299
|
// TODO: Official testing and support.
|
|
300
300
|
tx.insertDistributedTraceHeaders(headers)
|
|
301
301
|
} else {
|
|
@@ -13,6 +13,7 @@ const Shim = require('./shim')
|
|
|
13
13
|
const specs = require('./specs')
|
|
14
14
|
const urltils = require('../util/urltils')
|
|
15
15
|
const util = require('util')
|
|
16
|
+
const symbols = require('../symbols')
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* An enumeration of well-known web frameworks so that new instrumentations can
|
|
@@ -54,13 +55,6 @@ const MIDDLEWARE_TYPE_NAMES = {
|
|
|
54
55
|
ROUTER: 'ROUTER'
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
/**
|
|
58
|
-
* Name of the key used to store transaction information on `req` and `res`.
|
|
59
|
-
*
|
|
60
|
-
* @private
|
|
61
|
-
*/
|
|
62
|
-
const TRANSACTION_INFO_KEY = '__NR_transactionInfo'
|
|
63
|
-
|
|
64
58
|
/**
|
|
65
59
|
* Constructs a shim associated with the given agent instance, specialized for
|
|
66
60
|
* instrumenting web frameworks.
|
|
@@ -1036,7 +1030,7 @@ function _makeNextBinder(nextDetails, txInfo) {
|
|
|
1036
1030
|
*/
|
|
1037
1031
|
function _getTransactionInfo(shim, req) {
|
|
1038
1032
|
try {
|
|
1039
|
-
return req[
|
|
1033
|
+
return req[symbols.transactionInfo] || null
|
|
1040
1034
|
} catch (e) {
|
|
1041
1035
|
shim.logger.debug(e, 'Failed to fetch transaction info from req')
|
|
1042
1036
|
return null
|
package/lib/shimmer.js
CHANGED
|
@@ -14,6 +14,7 @@ const properties = require('./util/properties')
|
|
|
14
14
|
const shims = require('./shim')
|
|
15
15
|
|
|
16
16
|
const NAMES = require('./metrics/names')
|
|
17
|
+
const symbols = require('./symbols')
|
|
17
18
|
|
|
18
19
|
const MODULE_TYPE = shims.constants.MODULE_TYPE
|
|
19
20
|
|
|
@@ -97,7 +98,7 @@ const shimmer = (module.exports = {
|
|
|
97
98
|
* @returns {bool} True if `fn` exists and has an attached original, else false.
|
|
98
99
|
*/
|
|
99
100
|
isWrapped: function isWrapped(fn) {
|
|
100
|
-
return !!(fn && fn.
|
|
101
|
+
return !!(fn && fn[symbols.original])
|
|
101
102
|
},
|
|
102
103
|
|
|
103
104
|
/**
|
|
@@ -118,7 +119,8 @@ const shimmer = (module.exports = {
|
|
|
118
119
|
*/
|
|
119
120
|
wrapMethod: function wrapMethod(nodule, noduleName, methods, wrapper) {
|
|
120
121
|
if (!methods) {
|
|
121
|
-
|
|
122
|
+
logger.warn(new Error(), 'Must include a method name to wrap. Called from:')
|
|
123
|
+
return
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
if (!noduleName) {
|
|
@@ -132,29 +134,33 @@ const shimmer = (module.exports = {
|
|
|
132
134
|
const fqmn = noduleName + '.' + method
|
|
133
135
|
|
|
134
136
|
if (!nodule) {
|
|
135
|
-
|
|
137
|
+
logger.debug("Can't wrap %s from nonexistent object.", fqmn)
|
|
138
|
+
return
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
if (!wrapper) {
|
|
139
|
-
|
|
142
|
+
logger.debug("Can't wrap %s without a wrapper generator.", fqmn)
|
|
143
|
+
return
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
const original = nodule[method]
|
|
143
147
|
|
|
144
148
|
if (!original) {
|
|
145
|
-
|
|
149
|
+
logger.trace('%s not defined, so not wrapping.', fqmn)
|
|
150
|
+
return
|
|
146
151
|
}
|
|
147
|
-
if (original.
|
|
148
|
-
|
|
152
|
+
if (original[symbols.unwrap]) {
|
|
153
|
+
logger.debug('%s already wrapped by agent.', fqmn)
|
|
154
|
+
return
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
const wrapped = wrapper(original, method)
|
|
152
158
|
Object.keys(original).forEach((key) => {
|
|
153
159
|
wrapped[key] = original[key]
|
|
154
160
|
})
|
|
155
|
-
wrapped.
|
|
161
|
+
wrapped[symbols.original] = original
|
|
156
162
|
// eslint-disable-next-line camelcase
|
|
157
|
-
wrapped.
|
|
163
|
+
wrapped[symbols.unwrap] = function unwrap() {
|
|
158
164
|
nodule[method] = original
|
|
159
165
|
logger.trace('Removed instrumentation from %s.', fqmn)
|
|
160
166
|
}
|
|
@@ -221,7 +227,7 @@ const shimmer = (module.exports = {
|
|
|
221
227
|
|
|
222
228
|
if (shimmer.debug) {
|
|
223
229
|
instrumented.push({
|
|
224
|
-
|
|
230
|
+
[symbols.unwrap]: function unwrapDeprecated() {
|
|
225
231
|
delete nodule[property]
|
|
226
232
|
nodule[property] = original
|
|
227
233
|
}
|
|
@@ -259,16 +265,16 @@ const shimmer = (module.exports = {
|
|
|
259
265
|
if (!wrapped) {
|
|
260
266
|
return logger.debug('%s not defined, so not unwrapping.', fqmn)
|
|
261
267
|
}
|
|
262
|
-
if (!wrapped.
|
|
268
|
+
if (!wrapped[symbols.unwrap]) {
|
|
263
269
|
return logger.debug("%s isn't unwrappable.", fqmn)
|
|
264
270
|
}
|
|
265
271
|
|
|
266
|
-
wrapped.
|
|
272
|
+
wrapped[symbols.unwrap]()
|
|
267
273
|
},
|
|
268
274
|
|
|
269
275
|
unwrapAll: function unwrapAll() {
|
|
270
276
|
instrumented.forEach((wrapper) => {
|
|
271
|
-
wrapper.
|
|
277
|
+
wrapper[symbols.unwrap]()
|
|
272
278
|
})
|
|
273
279
|
instrumented = []
|
|
274
280
|
},
|
|
@@ -472,7 +478,7 @@ const shimmer = (module.exports = {
|
|
|
472
478
|
// This is to not break the public API
|
|
473
479
|
// previously it would just call instrumentation
|
|
474
480
|
// and not check the result
|
|
475
|
-
return returnModule ? result : !!result.
|
|
481
|
+
return returnModule ? result : !!result[symbols.instrumented]
|
|
476
482
|
}
|
|
477
483
|
})
|
|
478
484
|
|
|
@@ -481,13 +487,13 @@ function applyDebugState(shim, nodule) {
|
|
|
481
487
|
shim.enableDebug()
|
|
482
488
|
instrumented.push(shim)
|
|
483
489
|
instrumented.push({
|
|
484
|
-
|
|
485
|
-
delete nodule.
|
|
486
|
-
delete nodule.
|
|
487
|
-
delete nodule.
|
|
490
|
+
[symbols.unwrap]: function unwrapNodule() {
|
|
491
|
+
delete nodule[symbols.instrumentedErrored]
|
|
492
|
+
delete nodule[symbols.instrumented]
|
|
493
|
+
delete nodule[symbols.shim]
|
|
488
494
|
}
|
|
489
495
|
})
|
|
490
|
-
nodule.
|
|
496
|
+
nodule[symbols.shim] = shim
|
|
491
497
|
}
|
|
492
498
|
}
|
|
493
499
|
|
|
@@ -504,8 +510,8 @@ function applyDebugState(shim, nodule) {
|
|
|
504
510
|
function instrumentPostLoad(agent, nodule, moduleName, resolvedName) {
|
|
505
511
|
const instrumentation = shimmer.registeredInstrumentations[moduleName]
|
|
506
512
|
if (
|
|
507
|
-
properties.hasOwn(nodule,
|
|
508
|
-
properties.hasOwn(nodule,
|
|
513
|
+
properties.hasOwn(nodule, symbols.instrumented) ||
|
|
514
|
+
properties.hasOwn(nodule, symbols.instrumentedErrored)
|
|
509
515
|
) {
|
|
510
516
|
logger.trace(
|
|
511
517
|
'Already instrumented or failed to instrument %s, skipping redundant instrumentation',
|
|
@@ -527,10 +533,10 @@ function instrumentPostLoad(agent, nodule, moduleName, resolvedName) {
|
|
|
527
533
|
try {
|
|
528
534
|
if (instrumentation.onRequire(shim, nodule, moduleName) !== false) {
|
|
529
535
|
nodule = shim.getExport(nodule)
|
|
530
|
-
nodule.
|
|
536
|
+
nodule[symbols.instrumented] = true
|
|
531
537
|
}
|
|
532
538
|
} catch (instrumentationError) {
|
|
533
|
-
nodule.
|
|
539
|
+
nodule[symbols.instrumentedErrored] = true
|
|
534
540
|
if (instrumentation.onError) {
|
|
535
541
|
try {
|
|
536
542
|
instrumentation.onError(instrumentationError)
|
package/lib/symbols.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
cache: Symbol('cache'),
|
|
10
|
+
context: Symbol('context'),
|
|
11
|
+
databaseName: Symbol('databaseName'),
|
|
12
|
+
disableDT: Symbol('Disable distributed tracing'), // description for backwards compatibility
|
|
13
|
+
executorContext: Symbol('executorContext'),
|
|
14
|
+
instrumented: Symbol('instrumented'),
|
|
15
|
+
instrumentedErrored: Symbol('instrumentedErrored'),
|
|
16
|
+
name: Symbol('name'),
|
|
17
|
+
onceExecuted: Symbol('onceExecuted'),
|
|
18
|
+
offTheRecord: Symbol('offTheRecord'),
|
|
19
|
+
original: Symbol('original'),
|
|
20
|
+
segment: Symbol('segment'),
|
|
21
|
+
shim: Symbol('shim'),
|
|
22
|
+
storeDatabase: Symbol('storeDatabase'),
|
|
23
|
+
transaction: Symbol('transaction'),
|
|
24
|
+
transactionInfo: Symbol('transactionInfo'),
|
|
25
|
+
unwrap: Symbol('unwrap')
|
|
26
|
+
}
|
package/lib/system-info.js
CHANGED
|
@@ -21,7 +21,7 @@ function isInteger(i) {
|
|
|
21
21
|
return i === parseInt(i, 10)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function fetchSystemInfo(agent, callback) {
|
|
24
|
+
function fetchSystemInfo(agent, callback, numTasks = 5) {
|
|
25
25
|
const config = agent.config
|
|
26
26
|
const systemInfo = {
|
|
27
27
|
processorArch: os.arch()
|
|
@@ -74,7 +74,6 @@ function fetchSystemInfo(agent, callback) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
let tasksDone = 0
|
|
77
|
-
const numTasks = 5
|
|
78
77
|
function finishedResponse() {
|
|
79
78
|
if (++tasksDone === numTasks) {
|
|
80
79
|
callback(null, systemInfo)
|
|
@@ -7,12 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const Transaction = require('../index.js')
|
|
9
9
|
const logger = require('../../logger').child({ component: 'tracer' })
|
|
10
|
-
|
|
11
|
-
/*
|
|
12
|
-
* CONSTANTS
|
|
13
|
-
*/
|
|
14
|
-
const ORIGINAL = '__NR_original'
|
|
15
|
-
const SEGMENT = '__NR_segment'
|
|
10
|
+
const symbols = require('../../symbols')
|
|
16
11
|
|
|
17
12
|
module.exports = Tracer
|
|
18
13
|
|
|
@@ -35,7 +30,6 @@ Tracer.prototype.transactionNestProxy = transactionNestProxy
|
|
|
35
30
|
Tracer.prototype.bindFunction = bindFunction
|
|
36
31
|
Tracer.prototype.bindEmitter = bindEmitter
|
|
37
32
|
Tracer.prototype.getOriginal = getOriginal
|
|
38
|
-
Tracer.prototype.getSegmentFromWrapped = getSegmentFromWrapped
|
|
39
33
|
Tracer.prototype.slice = argSlice
|
|
40
34
|
Tracer.prototype.wrapFunctionNoSegment = wrapFunctionNoSegment
|
|
41
35
|
Tracer.prototype.wrapFunctionFirstNoSegment = wrapFunctionFirstNoSegment
|
|
@@ -124,7 +118,7 @@ function transactionProxy(handler) {
|
|
|
124
118
|
return tracer.bindFunction(handler, transaction.trace.root, true).apply(this, arguments)
|
|
125
119
|
}
|
|
126
120
|
|
|
127
|
-
wrapped[
|
|
121
|
+
wrapped[symbols.original] = handler
|
|
128
122
|
|
|
129
123
|
return wrapped
|
|
130
124
|
}
|
|
@@ -175,7 +169,7 @@ function transactionNestProxy(type, handler) {
|
|
|
175
169
|
return tracer.bindFunction(handler, segment).apply(this, arguments)
|
|
176
170
|
}
|
|
177
171
|
|
|
178
|
-
wrapped[
|
|
172
|
+
wrapped[symbols.original] = handler
|
|
179
173
|
|
|
180
174
|
return wrapped
|
|
181
175
|
}
|
|
@@ -188,8 +182,8 @@ function bindFunction(handler, segment, full) {
|
|
|
188
182
|
return _makeWrapped(this, handler, segment || this.getSegment(), !!full)
|
|
189
183
|
}
|
|
190
184
|
function _makeWrapped(tracer, handler, active, full) {
|
|
191
|
-
wrapped[
|
|
192
|
-
wrapped[
|
|
185
|
+
wrapped[symbols.original] = getOriginal(handler)
|
|
186
|
+
wrapped[symbols.segment] = active
|
|
193
187
|
|
|
194
188
|
return wrapped
|
|
195
189
|
|
|
@@ -206,7 +200,7 @@ function _makeWrapped(tracer, handler, active, full) {
|
|
|
206
200
|
logger.trace(err, 'Error from wrapped function:')
|
|
207
201
|
|
|
208
202
|
if (prev === null && process.domain != null) {
|
|
209
|
-
process.domain.
|
|
203
|
+
process.domain[symbols.segment] = tracer.getSegment()
|
|
210
204
|
}
|
|
211
205
|
|
|
212
206
|
throw err // Re-throwing application error, this is not an agent error.
|
|
@@ -219,11 +213,11 @@ function _makeWrapped(tracer, handler, active, full) {
|
|
|
219
213
|
}
|
|
220
214
|
|
|
221
215
|
function getOriginal(fn) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return fn
|
|
216
|
+
const original = fn[symbols.original]
|
|
217
|
+
if (original) {
|
|
218
|
+
return original
|
|
219
|
+
}
|
|
220
|
+
return fn
|
|
227
221
|
}
|
|
228
222
|
|
|
229
223
|
function bindEmitter(emitter, segment) {
|
|
@@ -473,7 +467,7 @@ function wrapCallback(original, segment, wrapped) {
|
|
|
473
467
|
return tracer.bindFunction(
|
|
474
468
|
function wrappedCallback() {
|
|
475
469
|
if (wrapped) {
|
|
476
|
-
wrapped[
|
|
470
|
+
wrapped[symbols.original] = original
|
|
477
471
|
}
|
|
478
472
|
|
|
479
473
|
const child = tracer.createSegment(
|
package/lib/util/arity.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const hasOwnProperty = require('./properties').hasOwn
|
|
9
|
+
const symbols = require('../symbols')
|
|
9
10
|
|
|
10
11
|
// Starting in what we believe to be Node v4 you can set the name and length of
|
|
11
12
|
// a function as properties. This is more ideal than wrapping a function.
|
|
@@ -16,17 +17,11 @@ function fixArity(original, wrapper) {
|
|
|
16
17
|
name: { value: original.name },
|
|
17
18
|
length: { value: original.length }
|
|
18
19
|
}
|
|
20
|
+
Object.defineProperties(wrapper, toDefine)
|
|
19
21
|
|
|
20
|
-
if (!hasOwnProperty(wrapper,
|
|
21
|
-
|
|
22
|
-
configurable: false,
|
|
23
|
-
enumerable: false,
|
|
24
|
-
writable: false,
|
|
25
|
-
value: wrapper.name
|
|
26
|
-
}
|
|
22
|
+
if (!hasOwnProperty(wrapper, symbols.name)) {
|
|
23
|
+
wrapper[symbols.name] = wrapper.name
|
|
27
24
|
}
|
|
28
25
|
|
|
29
|
-
Object.defineProperties(wrapper, toDefine)
|
|
30
|
-
|
|
31
26
|
return wrapper
|
|
32
27
|
}
|
package/lib/util/properties.js
CHANGED
|
@@ -7,16 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
const hasOwnProperty = Object.hasOwnProperty
|
|
9
9
|
|
|
10
|
-
// The logger needs to be lazy-loaded to get around ordering issues with config.
|
|
11
|
-
let _logger = null
|
|
12
|
-
let getLogger = function makeLogger() {
|
|
13
|
-
_logger = require('../logger').child({ component: 'util-properties' })
|
|
14
|
-
getLogger = function reallyGetLogger() {
|
|
15
|
-
return _logger
|
|
16
|
-
}
|
|
17
|
-
return _logger
|
|
18
|
-
}
|
|
19
|
-
|
|
20
10
|
/**
|
|
21
11
|
* Checks if an object has its own property with the given key.
|
|
22
12
|
*
|
|
@@ -53,39 +43,3 @@ exports.isEmpty = function isEmpty(obj) {
|
|
|
53
43
|
}
|
|
54
44
|
return true
|
|
55
45
|
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Sets a non-enumerable property on an object with the given value.
|
|
59
|
-
*
|
|
60
|
-
* XXX: This process is very slow, so use only when necessary. Check the
|
|
61
|
-
* configuration `transaction_tracer.hide_internals` before calling this.
|
|
62
|
-
*
|
|
63
|
-
* @private
|
|
64
|
-
*
|
|
65
|
-
* @param {*} obj - The item to add the hidden property to.
|
|
66
|
-
* @param {string} name - The name of the property to add.
|
|
67
|
-
* @param {*} val - The value to set the property to.
|
|
68
|
-
*
|
|
69
|
-
* @return {*} The `obj` argument.
|
|
70
|
-
*/
|
|
71
|
-
exports.setInternal = function setInternalProperty(obj, name, val) {
|
|
72
|
-
if (!obj || !name) {
|
|
73
|
-
getLogger().debug('Not setting property; object or name is missing.')
|
|
74
|
-
return obj
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
if (!exports.hasOwn(obj, name)) {
|
|
79
|
-
Object.defineProperty(obj, name, {
|
|
80
|
-
enumerable: false,
|
|
81
|
-
writable: true,
|
|
82
|
-
value: val
|
|
83
|
-
})
|
|
84
|
-
} else {
|
|
85
|
-
obj[name] = val
|
|
86
|
-
}
|
|
87
|
-
} catch (err) {
|
|
88
|
-
getLogger().debug(err, 'Failed to set property "%s" to %j', name, val)
|
|
89
|
-
}
|
|
90
|
-
return obj
|
|
91
|
-
}
|