newrelic 8.5.0 → 8.7.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 -0
- package/README.md +7 -6
- package/THIRD_PARTY_NOTICES.md +33 -2
- package/api.js +103 -136
- package/lib/agent.js +11 -2
- package/lib/config/index.js +11 -8
- 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/instrumentation/mongodb/common.js +12 -4
- package/lib/instrumentation/promise.js +28 -41
- package/lib/metrics/names.js +5 -1
- 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 +171 -11
- package/lib/transaction/tracer/index.js +22 -29
- package/package.json +7 -4
package/lib/config/index.js
CHANGED
|
@@ -229,6 +229,7 @@ Config.prototype.mergeServerConfig = mergeServerConfig
|
|
|
229
229
|
* recognized, unsupported, and unknown parameters.
|
|
230
230
|
*
|
|
231
231
|
* @param {object} json The config blob sent by New Relic.
|
|
232
|
+
* @param recursion
|
|
232
233
|
*/
|
|
233
234
|
Config.prototype.onConnect = function onConnect(json, recursion) {
|
|
234
235
|
json = json || Object.create(null)
|
|
@@ -865,7 +866,7 @@ Config.prototype.checkAsyncHookStatus = function checkAsyncHookStatus() {
|
|
|
865
866
|
* I wanted to cache the DisplayHost, but if I attached the variable to the config object,
|
|
866
867
|
* it sends the extra variable to New Relic, which is not desired.
|
|
867
868
|
*
|
|
868
|
-
* @
|
|
869
|
+
* @returns {string} display host name
|
|
869
870
|
*/
|
|
870
871
|
Config.prototype.getDisplayHost = getDisplayHost
|
|
871
872
|
|
|
@@ -903,7 +904,7 @@ function getDisplayHost() {
|
|
|
903
904
|
* I wanted to cache the Hostname, but if I attached the variable to the config object,
|
|
904
905
|
* it sends the extra variable to New Relic, which is not desired.
|
|
905
906
|
*
|
|
906
|
-
* @
|
|
907
|
+
* @returns {string} host name
|
|
907
908
|
*/
|
|
908
909
|
Config.prototype.getHostnameSafe = getHostnameSafe
|
|
909
910
|
|
|
@@ -980,6 +981,7 @@ Config.prototype.applications = function applications() {
|
|
|
980
981
|
*
|
|
981
982
|
* @param {object} external The configuration being loaded.
|
|
982
983
|
* @param {object} internal Whichever chunk of the config being overridden.
|
|
984
|
+
* @param arbitrary
|
|
983
985
|
*/
|
|
984
986
|
Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrary) {
|
|
985
987
|
if (!external) {
|
|
@@ -1065,6 +1067,8 @@ Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
|
|
|
1065
1067
|
* need to set this yourself.
|
|
1066
1068
|
* @param object data The current level of the configuration object. Should
|
|
1067
1069
|
* never need to set this yourself.
|
|
1070
|
+
* @param metadata
|
|
1071
|
+
* @param data
|
|
1068
1072
|
*/
|
|
1069
1073
|
Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
1070
1074
|
if (!metadata) {
|
|
@@ -1122,7 +1126,6 @@ Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
|
1122
1126
|
* environment variable.
|
|
1123
1127
|
*
|
|
1124
1128
|
* @param {*} inputConfig configuration passed to the Config constructor
|
|
1125
|
-
*
|
|
1126
1129
|
* @returns {boolean}
|
|
1127
1130
|
*/
|
|
1128
1131
|
Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig) {
|
|
@@ -1137,7 +1140,6 @@ Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig)
|
|
|
1137
1140
|
* file or enveironment variable
|
|
1138
1141
|
*
|
|
1139
1142
|
* @param {*} inputConfig configuration pass to the Config constructor
|
|
1140
|
-
*
|
|
1141
1143
|
* @returns {boolean}
|
|
1142
1144
|
*/
|
|
1143
1145
|
Config.prototype._nativeMetricsManuallySet = function _nativeMetricsManuallySet(inputConfig) {
|
|
@@ -1156,7 +1158,6 @@ Config.prototype._nativeMetricsManuallySet = function _nativeMetricsManuallySet(
|
|
|
1156
1158
|
* environment variable.
|
|
1157
1159
|
*
|
|
1158
1160
|
* @param {*} inputConfig configuration passed to the Config constructor
|
|
1159
|
-
*
|
|
1160
1161
|
* @returns {boolean}
|
|
1161
1162
|
*/
|
|
1162
1163
|
Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
|
|
@@ -1173,6 +1174,7 @@ Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
|
|
|
1173
1174
|
* - disables cross_application_tracer.enabled if set
|
|
1174
1175
|
* - defaults logging to disabled
|
|
1175
1176
|
* - verifies data specific to running DT is defined either in config file of env vars
|
|
1177
|
+
*
|
|
1176
1178
|
* @param {*} inputConfig configuration passed to the Config constructor
|
|
1177
1179
|
*/
|
|
1178
1180
|
Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
@@ -1282,7 +1284,7 @@ Config.prototype._canonicalize = function _canonicalize() {
|
|
|
1282
1284
|
}
|
|
1283
1285
|
|
|
1284
1286
|
const expectedCodes = this.error_collector && this.error_collector.expected_status_codes
|
|
1285
|
-
if (
|
|
1287
|
+
if (expectedCodes) {
|
|
1286
1288
|
this.error_collector.expected_status_codes = _parseCodes(expectedCodes)
|
|
1287
1289
|
}
|
|
1288
1290
|
|
|
@@ -1410,7 +1412,6 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1410
1412
|
*
|
|
1411
1413
|
* @param {Agent} agent
|
|
1412
1414
|
* @param {object} policies
|
|
1413
|
-
*
|
|
1414
1415
|
* @returns {CollectorResponse} The result of the processing, with the known
|
|
1415
1416
|
* policies as the response payload.
|
|
1416
1417
|
*/
|
|
@@ -1540,7 +1541,7 @@ function redactValue(value) {
|
|
|
1540
1541
|
* Get a JSONifiable object containing all settings we want to report to the
|
|
1541
1542
|
* collector and store in the environment_values table.
|
|
1542
1543
|
*
|
|
1543
|
-
* @
|
|
1544
|
+
* @returns Object containing simple key-value pairs of settings
|
|
1544
1545
|
*/
|
|
1545
1546
|
Config.prototype.publicSettings = function publicSettings() {
|
|
1546
1547
|
let settings = Object.create(null)
|
|
@@ -1683,6 +1684,8 @@ function initialize(config) {
|
|
|
1683
1684
|
|
|
1684
1685
|
/**
|
|
1685
1686
|
* This helper function creates an empty configuration object
|
|
1687
|
+
*
|
|
1688
|
+
* @param config
|
|
1686
1689
|
*/
|
|
1687
1690
|
function createNewConfigObject(config) {
|
|
1688
1691
|
config = new Config(Object.create(null))
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2021 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const logger = require('../logger')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Factory function to create context manager implementations used by the
|
|
12
|
+
* ContextManager class.
|
|
13
|
+
*
|
|
14
|
+
* @param {object} config New Relic config instance.
|
|
15
|
+
* @returns {*} The appropriate underlying context manager implementation based on
|
|
16
|
+
* the current configuration.
|
|
17
|
+
*/
|
|
18
|
+
function createContextManager(config) {
|
|
19
|
+
if (config.logging.diagnostics) {
|
|
20
|
+
logger.info('Using LegacyDiagnosticContextManager')
|
|
21
|
+
|
|
22
|
+
const LegacyDiagnosticContextManager = require('./diagnostics/legacy-diagnostic-context-manager')
|
|
23
|
+
return new LegacyDiagnosticContextManager(config)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
logger.info('Using LegacyContextManager')
|
|
27
|
+
|
|
28
|
+
const LegacyContextManager = require('./legacy-context-manager')
|
|
29
|
+
return new LegacyContextManager(config)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = createContextManager
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2021 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
const LegacyContextManager = require('../legacy-context-manager')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Overrides setContext to add diagnostic logging around setting and removing
|
|
12
|
+
* from context. Currently just supports the segment.probe().
|
|
13
|
+
*
|
|
14
|
+
* Exists in own class to keep default context management as minimal/efficient as possible
|
|
15
|
+
* given we wrap pretty much every functions execution.
|
|
16
|
+
*/
|
|
17
|
+
class LegacyDiagnosticContextManager extends LegacyContextManager {
|
|
18
|
+
setContext(newContext) {
|
|
19
|
+
this._logDiagnostic(this._context, 'Removed from context')
|
|
20
|
+
|
|
21
|
+
this._context = newContext
|
|
22
|
+
|
|
23
|
+
this._logDiagnostic(newContext, 'Set in context')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_logDiagnostic(context, message) {
|
|
27
|
+
// This is to currently support diagnostic logging of segments which gets attached to
|
|
28
|
+
// transactions with a stack trace. All of this is output at once at the end of a transaction
|
|
29
|
+
// when enabled for clear tracing.
|
|
30
|
+
if (context && context.probe) {
|
|
31
|
+
context.probe(message)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = LegacyDiagnosticContextManager
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2021 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Class for managing state in the agent.
|
|
10
|
+
* Keeps track of a single context instance.
|
|
11
|
+
*
|
|
12
|
+
* Given current usage with every instrumented function, the functions in this
|
|
13
|
+
* class should do as little work as possible to avoid unnecessary overhead.
|
|
14
|
+
*
|
|
15
|
+
* @class
|
|
16
|
+
*/
|
|
17
|
+
class LegacyContextManager {
|
|
18
|
+
/**
|
|
19
|
+
* @param {object} config New Relic config instance
|
|
20
|
+
*/
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this._config = config
|
|
23
|
+
this._context = null
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get the currently active context.
|
|
28
|
+
*
|
|
29
|
+
* @returns {object} The current active context.
|
|
30
|
+
*/
|
|
31
|
+
getContext() {
|
|
32
|
+
return this._context
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Set a new active context. Not bound to function execution.
|
|
37
|
+
*
|
|
38
|
+
* @param {object} newContext The context to set as active.
|
|
39
|
+
*/
|
|
40
|
+
setContext(newContext) {
|
|
41
|
+
this._context = newContext
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Run a function with the passed in context as the active context.
|
|
46
|
+
* Restores the previously active context upon completion.
|
|
47
|
+
*
|
|
48
|
+
* @param {object} context The context to set as active during callback execution.
|
|
49
|
+
* @param {Function} callback The function to execute in context.
|
|
50
|
+
* @param {Function} [cbThis] Optional `this` to apply to the callback.
|
|
51
|
+
* @param {Array<*>} [args] Optional arguments object or args array to invoke the callback with.
|
|
52
|
+
* @returns {*} Returns the value returned by the callback function.
|
|
53
|
+
*/
|
|
54
|
+
runInContext(context, callback, cbThis, args) {
|
|
55
|
+
const oldContext = this.getContext()
|
|
56
|
+
this.setContext(context)
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
return callback.apply(cbThis, args)
|
|
60
|
+
} finally {
|
|
61
|
+
this.setContext(oldContext)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = LegacyContextManager
|
|
@@ -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) {
|
package/lib/metrics/names.js
CHANGED
|
@@ -252,7 +252,11 @@ const INFINITE_TRACING = {
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
const FEATURES = {
|
|
255
|
-
CERTIFICATES: SUPPORTABILITY.FEATURES + '/Certificates'
|
|
255
|
+
CERTIFICATES: SUPPORTABILITY.FEATURES + '/Certificates',
|
|
256
|
+
INSTRUMENTATION: {
|
|
257
|
+
ON_RESOLVED: SUPPORTABILITY.FEATURES + '/Instrumentation/OnResolved',
|
|
258
|
+
ON_REQUIRE: SUPPORTABILITY.FEATURES + '/Instrumentation/OnRequire'
|
|
259
|
+
}
|
|
256
260
|
}
|
|
257
261
|
|
|
258
262
|
module.exports = {
|
|
@@ -17,6 +17,12 @@ function parseProcCPUInfo(data) {
|
|
|
17
17
|
packages: null
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// In some rare cases the OS may be locked down so that you cannot retrieve this info.
|
|
21
|
+
if (!data) {
|
|
22
|
+
logger.debug('No CPU data to parse, returning empty stats.')
|
|
23
|
+
return processorStats
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
// separate the processors
|
|
21
27
|
let splitData = data.split('\n').map(function formatAttribute(attr) {
|
|
22
28
|
return attr.split(':').map(function eliminateExtraWhitespace(s) {
|
|
@@ -34,7 +40,7 @@ function parseProcCPUInfo(data) {
|
|
|
34
40
|
|
|
35
41
|
splitData = collapseMultilineValues(splitData)
|
|
36
42
|
|
|
37
|
-
const processors =
|
|
43
|
+
const processors = separateProcessors(splitData)
|
|
38
44
|
|
|
39
45
|
processorStats = countProcessorStats(processors)
|
|
40
46
|
if (!processorStats.cores) {
|
|
@@ -73,7 +79,7 @@ function collapseMultilineValues(li) {
|
|
|
73
79
|
|
|
74
80
|
// walk through the processed list of key, value pairs and populate
|
|
75
81
|
// objects till you find a collision
|
|
76
|
-
function
|
|
82
|
+
function separateProcessors(processorData) {
|
|
77
83
|
const processors = []
|
|
78
84
|
let processor = Object.create(null)
|
|
79
85
|
for (let i = 0; i < processorData.length; ++i) {
|
|
@@ -10,6 +10,12 @@ const logger = require('./logger.js').child({ component: 'proc-meminfo' })
|
|
|
10
10
|
module.exports = parseProcMeminfo
|
|
11
11
|
|
|
12
12
|
function parseProcMeminfo(data) {
|
|
13
|
+
// In some rare cases the OS may be locked down so that you cannot retrieve this info.
|
|
14
|
+
if (!data) {
|
|
15
|
+
logger.debug('No memory data to parse.')
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
const memTotal = parseInt(data.replace(/MemTotal:\s*(\d*)\skB/, '$1'), 10)
|
|
14
20
|
|
|
15
21
|
if (memTotal) {
|
|
@@ -82,8 +82,14 @@ class AwsLambda {
|
|
|
82
82
|
// NOTE: This may be converted to holding onto a single ender function if only
|
|
83
83
|
// one invocation is executing at a time.
|
|
84
84
|
shim.wrap(process, 'emit', function wrapEmit(shim, emit) {
|
|
85
|
-
return function wrappedEmit(ev) {
|
|
86
|
-
|
|
85
|
+
return function wrappedEmit(ev, error) {
|
|
86
|
+
// need to add error as uncaughtException to be used
|
|
87
|
+
// later to add to transaction errors
|
|
88
|
+
if (ev === 'unhandledRejection') {
|
|
89
|
+
uncaughtException = error
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (['beforeExit', 'unhandledRejection'].includes(ev)) {
|
|
87
93
|
transactionEnders.forEach((ender) => {
|
|
88
94
|
ender()
|
|
89
95
|
})
|