newrelic 9.7.0 → 9.7.1
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 +40 -20
- package/THIRD_PARTY_NOTICES.md +203 -2
- package/api.js +155 -103
- package/lib/agent.js +29 -82
- package/lib/collector/api.js +234 -201
- package/lib/config/attribute-filter.js +35 -25
- package/lib/config/default.js +45 -19
- package/lib/config/index.js +260 -199
- package/lib/environment.js +16 -12
- package/lib/errors/error-collector.js +124 -55
- package/lib/errors/index.js +59 -49
- package/lib/instrumentation/@hapi/hapi.js +56 -50
- package/lib/instrumentation/@node-redis/client.js +50 -41
- package/lib/instrumentation/amqplib.js +116 -151
- package/lib/instrumentation/core/{async_hooks.js → async-hooks.js} +26 -11
- package/lib/instrumentation/core/globals.js +1 -1
- package/lib/instrumentation/core/http-outbound.js +193 -78
- package/lib/instrumentation/core/timers.js +106 -59
- package/lib/instrumentation/mongodb/common.js +87 -85
- package/lib/instrumentation/redis.js +112 -90
- package/lib/instrumentation/undici.js +204 -192
- package/lib/instrumentation/{when.js → when/constants.js} +13 -10
- package/lib/instrumentation/when/contextualizer.js +168 -0
- package/lib/instrumentation/when/index.js +354 -0
- package/lib/instrumentation/when/nr-hooks.js +15 -0
- package/lib/instrumentations.js +1 -1
- package/lib/shim/shim.js +2 -0
- package/lib/shim/webframework-shim.js +19 -0
- package/lib/symbols.js +1 -0
- package/lib/system-info.js +240 -163
- package/lib/util/async-each-limit.js +30 -0
- package/lib/util/attributes.js +159 -0
- package/lib/util/code-level-metrics.js +58 -0
- package/lib/util/deep-equal.js +11 -144
- package/package.json +5 -4
- package/lib/instrumentation/promise.js +0 -572
package/api.js
CHANGED
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
/* eslint sonarjs/cognitive-complexity: ["error", 21] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
-
|
|
10
8
|
const util = require('util')
|
|
11
9
|
const logger = require('./lib/logger').child({ component: 'api' })
|
|
12
10
|
const recordWeb = require('./lib/metrics/recorders/http')
|
|
@@ -58,7 +56,7 @@ const CUSTOM_EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/
|
|
|
58
56
|
* You do not need to directly instantiate this class, as an instance of this is
|
|
59
57
|
* the return from `require('newrelic')`.
|
|
60
58
|
*
|
|
61
|
-
* @param agent
|
|
59
|
+
* @param {object} agent Instantiation of lib/agent.js
|
|
62
60
|
* @class
|
|
63
61
|
*/
|
|
64
62
|
function API(agent) {
|
|
@@ -78,6 +76,7 @@ function API(agent) {
|
|
|
78
76
|
*
|
|
79
77
|
* @param {string} name The name you want to give the web request in the New
|
|
80
78
|
* Relic UI. Will be prefixed with 'Custom/' when sent.
|
|
79
|
+
* @returns {void}
|
|
81
80
|
*/
|
|
82
81
|
API.prototype.setTransactionName = function setTransactionName(name) {
|
|
83
82
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -143,8 +142,8 @@ API.prototype.getTransaction = function getTransaction() {
|
|
|
143
142
|
* utilization.full_hostname. If utilization.full_hostname is null or empty,
|
|
144
143
|
* this will be the hostname specified in the connect request as host.
|
|
145
144
|
*
|
|
146
|
-
* @param omitSupportability
|
|
147
|
-
* @returns {
|
|
145
|
+
* @param {boolean} omitSupportability Whether or not to log the supportability metric, true means skip
|
|
146
|
+
* @returns {object} The LinkingMetadata object with the data above
|
|
148
147
|
*/
|
|
149
148
|
API.prototype.getLinkingMetadata = function getLinkingMetadata(omitSupportability) {
|
|
150
149
|
if (omitSupportability !== true) {
|
|
@@ -207,6 +206,7 @@ API.prototype.setDispatcher = function setDispatcher(name, version) {
|
|
|
207
206
|
* sent.
|
|
208
207
|
* @param {string} action The action being invoked on the controller. Defaults
|
|
209
208
|
* to the HTTP method used for the request.
|
|
209
|
+
* @returns {void}
|
|
210
210
|
*/
|
|
211
211
|
API.prototype.setControllerName = function setControllerName(name, action) {
|
|
212
212
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -241,6 +241,7 @@ API.prototype.setControllerName = function setControllerName(name, action) {
|
|
|
241
241
|
*
|
|
242
242
|
* @param {string} key The key you want displayed in the RPM UI.
|
|
243
243
|
* @param {string} value The value you want displayed. Must be serializable.
|
|
244
|
+
* @returns {false|undefined} Retruns false when disabled/errored, otherwise undefined
|
|
244
245
|
*/
|
|
245
246
|
API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
246
247
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -296,7 +297,7 @@ API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
|
296
297
|
*
|
|
297
298
|
* newrelic.addCustomAttributes({test: 'value', test2: 'value2'});
|
|
298
299
|
*
|
|
299
|
-
* @param {object} [atts]
|
|
300
|
+
* @param {object} [atts] Attribute object
|
|
300
301
|
* @param {string} [atts.KEY] The name you want displayed in the RPM UI.
|
|
301
302
|
* @param {string} [atts.KEY.VALUE] The value you want displayed. Must be serializable.
|
|
302
303
|
*/
|
|
@@ -324,7 +325,7 @@ API.prototype.addCustomAttributes = function addCustomAttributes(atts) {
|
|
|
324
325
|
*
|
|
325
326
|
* newrelic.addCustomSpanAttribute({test: 'value', test2: 'value2'})
|
|
326
327
|
*
|
|
327
|
-
* @param {object} [atts]
|
|
328
|
+
* @param {object} [atts] Attribute object
|
|
328
329
|
* @param {string} [atts.KEY] The name you want displayed in the RPM UI.API.
|
|
329
330
|
* @param {string} [atts.KEY.VALUE] The value you want displayed. Must be serializable.
|
|
330
331
|
*/
|
|
@@ -349,6 +350,7 @@ API.prototype.addCustomSpanAttributes = function addCustomSpanAttributes(atts) {
|
|
|
349
350
|
*
|
|
350
351
|
* @param {string} key The key you want displayed in the RPM UI.
|
|
351
352
|
* @param {string} value The value you want displayed. Must be serializable.
|
|
353
|
+
* @returns {false|undefined} Retruns false when disabled/errored, otherwise undefined
|
|
352
354
|
*/
|
|
353
355
|
API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, value) {
|
|
354
356
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -388,6 +390,17 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
388
390
|
* `Error` or one of its subtypes, but the API will handle strings and objects
|
|
389
391
|
* that have an attached `.message` or `.stack` property.
|
|
390
392
|
*
|
|
393
|
+
* An example of using this function is
|
|
394
|
+
*
|
|
395
|
+
* try {
|
|
396
|
+
* performSomeTask();
|
|
397
|
+
* } catch (err) {
|
|
398
|
+
* newrelic.noticeError(
|
|
399
|
+
* err,
|
|
400
|
+
* {extraInformation: "error already handled in the application"}
|
|
401
|
+
* );
|
|
402
|
+
* }
|
|
403
|
+
*
|
|
391
404
|
* NOTE: Errors that are recorded using this method do _not_ obey the
|
|
392
405
|
* `ignore_status_codes` configuration.
|
|
393
406
|
*
|
|
@@ -395,6 +408,7 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
395
408
|
* The error to be traced.
|
|
396
409
|
* @param {object} [customAttributes]
|
|
397
410
|
* Optional. Any custom attributes to be displayed in the New Relic UI.
|
|
411
|
+
* @returns {false|undefined} Retruns false when disabled/errored, otherwise undefined
|
|
398
412
|
*/
|
|
399
413
|
API.prototype.noticeError = function noticeError(error, customAttributes) {
|
|
400
414
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/noticeError')
|
|
@@ -536,6 +550,7 @@ API.prototype.recordLogEvent = function recordLogEvent(logEvent = {}) {
|
|
|
536
550
|
*
|
|
537
551
|
* @param {RegExp} pattern The pattern to rename (with capture groups).
|
|
538
552
|
* @param {string} name The name to use for the transaction.
|
|
553
|
+
* @returns {void}
|
|
539
554
|
*/
|
|
540
555
|
API.prototype.addNamingRule = function addNamingRule(pattern, name) {
|
|
541
556
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/addNamingRule')
|
|
@@ -560,6 +575,7 @@ API.prototype.addNamingRule = function addNamingRule(pattern, name) {
|
|
|
560
575
|
* newrelic.addIgnoringRule('^/socket\\.io/')
|
|
561
576
|
*
|
|
562
577
|
* @param {RegExp} pattern The pattern to ignore.
|
|
578
|
+
* @returns {void}
|
|
563
579
|
*/
|
|
564
580
|
API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
565
581
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/addIgnoringRule')
|
|
@@ -572,6 +588,52 @@ API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
|
572
588
|
this.agent.userNormalizer.addSimple(pattern, null)
|
|
573
589
|
}
|
|
574
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Gracefully fail.
|
|
593
|
+
*
|
|
594
|
+
* Output an HTML comment and log a warning the comment is meant to be
|
|
595
|
+
* innocuous to the end user.
|
|
596
|
+
*
|
|
597
|
+
* @see RUM_ISSUES
|
|
598
|
+
* @param {number} errorCode Error code from `RUM_ISSUES`.
|
|
599
|
+
* @param {boolean} [quiet=false] Be quiet about this failure.
|
|
600
|
+
* @returns {string} HTML comment for debugging purposes with specific error code
|
|
601
|
+
*/
|
|
602
|
+
function _gracefail(errorCode, quiet) {
|
|
603
|
+
if (quiet) {
|
|
604
|
+
logger.debug(RUM_ISSUES[errorCode])
|
|
605
|
+
} else {
|
|
606
|
+
logger.warn(RUM_ISSUES[errorCode])
|
|
607
|
+
}
|
|
608
|
+
return '<!-- NREUM: (' + errorCode + ') -->'
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Function for generating a fully formed RUM header based on configuration options
|
|
613
|
+
*
|
|
614
|
+
* @param {object} options Configuration options for RUM
|
|
615
|
+
* @param {string} [options.nonce] Nonce to inject into `<script>` header.
|
|
616
|
+
* @param {boolean} [options.hasToRemoveScriptWrapper] Used to import agent script without `<script>` tag wrapper.
|
|
617
|
+
* @param {string} metadata Stringified representation of rumHash metadata
|
|
618
|
+
* @param {string} loader Agent Loader script
|
|
619
|
+
* @returns {string} fully formed RUM header
|
|
620
|
+
*/
|
|
621
|
+
function _generateRUMHeader(options = {}, metadata, loader) {
|
|
622
|
+
const formatArgs = []
|
|
623
|
+
|
|
624
|
+
if (options.hasToRemoveScriptWrapper) {
|
|
625
|
+
formatArgs.push(RUM_STUB)
|
|
626
|
+
} else if (options.nonce) {
|
|
627
|
+
formatArgs.push(RUM_STUB_SHELL_WITH_NONCE_PARAM, `nonce="${options.nonce}"`)
|
|
628
|
+
} else {
|
|
629
|
+
formatArgs.push(RUM_STUB_SHELL)
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
formatArgs.push(metadata, loader)
|
|
633
|
+
|
|
634
|
+
return util.format(...formatArgs)
|
|
635
|
+
}
|
|
636
|
+
|
|
575
637
|
/**
|
|
576
638
|
* Get the script header necessary for Browser Monitoring
|
|
577
639
|
* This script must be manually injected into your templates, as high as possible
|
|
@@ -587,9 +649,9 @@ API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
|
587
649
|
*
|
|
588
650
|
* Do *not* reuse the headers between users, or even between requests.
|
|
589
651
|
*
|
|
652
|
+
* @param {object} options configuration options
|
|
590
653
|
* @param {string} [options.nonce] - Nonce to inject into `<script>` header.
|
|
591
654
|
* @param {boolean} [options.hasToRemoveScriptWrapper] - Used to import agent script without `<script>` tag wrapper.
|
|
592
|
-
* @param options
|
|
593
655
|
* @returns {string} The script content to be injected in `<head>` or put inside `<script>` tag (depending on options)
|
|
594
656
|
*/
|
|
595
657
|
API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options) {
|
|
@@ -600,26 +662,6 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
600
662
|
|
|
601
663
|
const config = this.agent.config
|
|
602
664
|
|
|
603
|
-
/**
|
|
604
|
-
* Gracefully fail.
|
|
605
|
-
*
|
|
606
|
-
* Output an HTML comment and log a warning the comment is meant to be
|
|
607
|
-
* innocuous to the end user.
|
|
608
|
-
*
|
|
609
|
-
* @param {number} num - Error code from `RUM_ISSUES`.
|
|
610
|
-
* @param {bool} [quite=false] - Be quiet about this failure.
|
|
611
|
-
* @param quiet
|
|
612
|
-
* @see RUM_ISSUES
|
|
613
|
-
*/
|
|
614
|
-
function _gracefail(num, quiet) {
|
|
615
|
-
if (quiet) {
|
|
616
|
-
logger.debug(RUM_ISSUES[num])
|
|
617
|
-
} else {
|
|
618
|
-
logger.warn(RUM_ISSUES[num])
|
|
619
|
-
}
|
|
620
|
-
return '<!-- NREUM: (' + num + ') -->'
|
|
621
|
-
}
|
|
622
|
-
|
|
623
665
|
const browserMonitoring = config.browser_monitoring
|
|
624
666
|
|
|
625
667
|
// config.browser_monitoring should always exist, but we don't want the agent
|
|
@@ -738,17 +780,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
738
780
|
const json = JSON.stringify(rumHash, null, tabs)
|
|
739
781
|
|
|
740
782
|
// the complete header to be written to the browser
|
|
741
|
-
const out =
|
|
742
|
-
options && options.hasToRemoveScriptWrapper
|
|
743
|
-
? util.format(RUM_STUB, json, jsAgentLoader)
|
|
744
|
-
: options && options.nonce
|
|
745
|
-
? util.format(
|
|
746
|
-
RUM_STUB_SHELL_WITH_NONCE_PARAM,
|
|
747
|
-
'nonce="' + options.nonce + '"',
|
|
748
|
-
json,
|
|
749
|
-
jsAgentLoader
|
|
750
|
-
)
|
|
751
|
-
: util.format(RUM_STUB_SHELL, json, jsAgentLoader)
|
|
783
|
+
const out = _generateRUMHeader(options, json, jsAgentLoader)
|
|
752
784
|
|
|
753
785
|
logger.trace('generating RUM header', out)
|
|
754
786
|
|
|
@@ -773,7 +805,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
773
805
|
* })
|
|
774
806
|
* @param {string} name
|
|
775
807
|
* The name to give the new segment. This will also be the name of the metric.
|
|
776
|
-
* @param {
|
|
808
|
+
* @param {boolean} record
|
|
777
809
|
* Indicates if the segment should be recorded as a metric. Metrics will show
|
|
778
810
|
* up on the transaction breakdown table and server breakdown graph. Segments
|
|
779
811
|
* just show up in transaction traces.
|
|
@@ -845,6 +877,7 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
845
877
|
* so it should be a generic name and not iclude any variable parameters.
|
|
846
878
|
* @param {Function} handle
|
|
847
879
|
* Function that represents the transaction work.
|
|
880
|
+
* @returns {null|*} Returns null if handle is not a function, otherwise the return value of handle
|
|
848
881
|
*/
|
|
849
882
|
API.prototype.startWebTransaction = function startWebTransaction(url, handle) {
|
|
850
883
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -935,7 +968,8 @@ API.prototype.startBackgroundTransaction = startBackgroundTransaction
|
|
|
935
968
|
* https://docs.newrelic.com/docs/apm/applications-menu/monitoring/transactions-page#txn-type-dropdown
|
|
936
969
|
* @param {Function} handle
|
|
937
970
|
* Function that represents the background work.
|
|
938
|
-
* @
|
|
971
|
+
* @memberof API#
|
|
972
|
+
* @returns {null|*} Returns null if handle is not a function, otherwise the return value of handle
|
|
939
973
|
*/
|
|
940
974
|
function startBackgroundTransaction(name, group, handle) {
|
|
941
975
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1040,7 +1074,7 @@ API.prototype.endTransaction = function endTransaction() {
|
|
|
1040
1074
|
* of these keys match the names of the keys used by the platform API.
|
|
1041
1075
|
*
|
|
1042
1076
|
* @param {string} name The name of the metric.
|
|
1043
|
-
* @param {number|object} value
|
|
1077
|
+
* @param {number|object} value The value of the metric to record
|
|
1044
1078
|
*/
|
|
1045
1079
|
API.prototype.recordMetric = function recordMetric(name, value) {
|
|
1046
1080
|
const supportMetric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1128,6 +1162,7 @@ API.prototype.incrementMetric = function incrementMetric(name, value) {
|
|
|
1128
1162
|
* @param {object} attributes Object of key and value pairs. The keys must be shorter
|
|
1129
1163
|
* than 255 characters, and the values must be string, number,
|
|
1130
1164
|
* or boolean.
|
|
1165
|
+
* @returns {false|undefined} Returns false explicitly if failed/disabled, otherwise undefined
|
|
1131
1166
|
*/
|
|
1132
1167
|
API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attributes) {
|
|
1133
1168
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1210,15 +1245,13 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1210
1245
|
* - `newrelic.instrument(moduleName, onRequire [,onError])`
|
|
1211
1246
|
* - `newrelic.instrument(options)`
|
|
1212
1247
|
*
|
|
1213
|
-
* @param {object}
|
|
1214
|
-
* @param {string}
|
|
1215
|
-
* @param {Function}
|
|
1216
|
-
* @param {Function}
|
|
1217
|
-
* @param {Function} [
|
|
1218
|
-
*
|
|
1219
|
-
* @param
|
|
1220
|
-
* @param onRequire
|
|
1221
|
-
* @param onError
|
|
1248
|
+
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1249
|
+
* @param {string} moduleName.moduleName The module name given to require to load the module
|
|
1250
|
+
* @param {Function} moduleName.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1251
|
+
* @param {Function} moduleName.onRequire The function to call when the module has been loaded
|
|
1252
|
+
* @param {Function} [moduleName.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1253
|
+
* @param {Function} onRequire The function to call when the module has been loaded
|
|
1254
|
+
* @param {Function} onError If provided, should `onRequire` throw an error, the error will be passed to this function.
|
|
1222
1255
|
*/
|
|
1223
1256
|
API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
1224
1257
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/instrument')
|
|
@@ -1243,15 +1276,13 @@ API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
|
1243
1276
|
* - `newrelic.instrumentConglomerate(moduleName, onRequire [, onError])`
|
|
1244
1277
|
* - `newrelic.isntrumentConglomerate(options)`
|
|
1245
1278
|
*
|
|
1246
|
-
* @param {object}
|
|
1247
|
-
* @param {string}
|
|
1248
|
-
* @param {Function}
|
|
1249
|
-
* @param {Function}
|
|
1250
|
-
* @param {Function} [
|
|
1251
|
-
*
|
|
1252
|
-
* @param
|
|
1253
|
-
* @param onRequire
|
|
1254
|
-
* @param onError
|
|
1279
|
+
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1280
|
+
* @param {string} moduleName.moduleName The module name given to require to load the module
|
|
1281
|
+
* @param {Function} moduleName.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1282
|
+
* @param {Function} moduleName.onRequire The function to call when the module has been loaded
|
|
1283
|
+
* @param {Function} [moduleName.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1284
|
+
* @param {Function} onRequire The function to call when the module has been loaded
|
|
1285
|
+
* @param {Function} onError If provided, should `onRequire` throw an error, the error will be passed to this function.
|
|
1255
1286
|
*/
|
|
1256
1287
|
API.prototype.instrumentConglomerate = function instrumentConglomerate(
|
|
1257
1288
|
moduleName,
|
|
@@ -1277,15 +1308,13 @@ API.prototype.instrumentConglomerate = function instrumentConglomerate(
|
|
|
1277
1308
|
* - `newrelic.instrumentDatastore(moduleName, onRequire [,onError])`
|
|
1278
1309
|
* - `newrelic.instrumentDatastore(options)`
|
|
1279
1310
|
*
|
|
1280
|
-
* @param {object}
|
|
1281
|
-
* @param {string}
|
|
1282
|
-
* @param {Function}
|
|
1283
|
-
* @param {Function}
|
|
1284
|
-
* @param {Function} [
|
|
1285
|
-
*
|
|
1286
|
-
* @param
|
|
1287
|
-
* @param onRequire
|
|
1288
|
-
* @param onError
|
|
1311
|
+
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1312
|
+
* @param {string} moduleName.moduleName The module name given to require to load the module
|
|
1313
|
+
* @param {Function} moduleName.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1314
|
+
* @param {Function} moduleName.onRequire The function to call when the module has been loaded
|
|
1315
|
+
* @param {Function} [moduleName.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1316
|
+
* @param {Function} onRequire The function to call when the module has been loaded
|
|
1317
|
+
* @param {Function} onError If provided, should `onRequire` throw an error, the error will be passed to this function.
|
|
1289
1318
|
*/
|
|
1290
1319
|
API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onRequire, onError) {
|
|
1291
1320
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1312,15 +1341,13 @@ API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onR
|
|
|
1312
1341
|
* - `newrelic.instrumentWebframework(moduleName, onRequire [,onError])`
|
|
1313
1342
|
* - `newrelic.instrumentWebframework(options)`
|
|
1314
1343
|
*
|
|
1315
|
-
* @param {object}
|
|
1316
|
-
* @param {string}
|
|
1317
|
-
* @param {Function}
|
|
1318
|
-
* @param {Function}
|
|
1319
|
-
* @param {Function} [
|
|
1320
|
-
*
|
|
1321
|
-
* @param
|
|
1322
|
-
* @param onRequire
|
|
1323
|
-
* @param onError
|
|
1344
|
+
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1345
|
+
* @param {string} moduleName.moduleName The module name given to require to load the module
|
|
1346
|
+
* @param {Function} moduleName.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1347
|
+
* @param {Function} moduleName.onRequire The function to call when the module has been loaded
|
|
1348
|
+
* @param {Function} [moduleName.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1349
|
+
* @param {Function} onRequire The function to call when the module has been loaded
|
|
1350
|
+
* @param {Function} onError If provided, should `onRequire` throw an error, the error will be passed to this function.
|
|
1324
1351
|
*/
|
|
1325
1352
|
API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
1326
1353
|
moduleName,
|
|
@@ -1351,15 +1378,13 @@ API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
|
1351
1378
|
* - `newrelic.instrumentMessages(moduleName, onRequire [,onError])`
|
|
1352
1379
|
* - `newrelic.instrumentMessages(options)`
|
|
1353
1380
|
*
|
|
1354
|
-
* @param {object}
|
|
1355
|
-
* @param {string}
|
|
1356
|
-
* @param {Function}
|
|
1357
|
-
* @param {Function}
|
|
1358
|
-
* @param {Function} [
|
|
1359
|
-
*
|
|
1360
|
-
* @param
|
|
1361
|
-
* @param onRequire
|
|
1362
|
-
* @param onError
|
|
1381
|
+
* @param {string|object} moduleName The module name given to require to load the module, or the instrumentation specification
|
|
1382
|
+
* @param {string} moduleName.moduleName The module name given to require to load the module
|
|
1383
|
+
* @param {Function} moduleName.onResolved The function to call prior to module load after the filepath has been resolved
|
|
1384
|
+
* @param {Function} moduleName.onRequire The function to call when the module has been loaded
|
|
1385
|
+
* @param {Function} [moduleName.onError] If provided, should `onRequire` throw an error, the error will be passed to
|
|
1386
|
+
* @param {Function} onRequire The function to call when the module has been loaded
|
|
1387
|
+
* @param {Function} onError If provided, should `onRequire` throw an error, the error will be passed to this function.
|
|
1363
1388
|
*/
|
|
1364
1389
|
API.prototype.instrumentMessages = function instrumentMessages(moduleName, onRequire, onError) {
|
|
1365
1390
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1398,6 +1423,7 @@ API.prototype.instrumentMessages = function instrumentMessages(moduleName, onReq
|
|
|
1398
1423
|
* into an instrumentation key.
|
|
1399
1424
|
* @param {object} module
|
|
1400
1425
|
* The actual module object or function we're instrumenting
|
|
1426
|
+
* @returns {boolean} Whether or not the module was successfully instrumented
|
|
1401
1427
|
*/
|
|
1402
1428
|
API.prototype.instrumentLoadedModule = function instrumentLoadedModule(moduleName, module) {
|
|
1403
1429
|
const metric = this.agent.metrics.getOrCreateMetric(
|
|
@@ -1458,9 +1484,8 @@ API.prototype.getTraceMetadata = function getTraceMetadata() {
|
|
|
1458
1484
|
* Time in milliseconds to wait before shutting down.
|
|
1459
1485
|
* @param {boolean} [options.waitForIdle=false]
|
|
1460
1486
|
* If true, the agent will not shut down until there are no active transactions.
|
|
1461
|
-
* @param {Function} [
|
|
1487
|
+
* @param {Function} [cb]
|
|
1462
1488
|
* Callback function that runs when agent stops.
|
|
1463
|
-
* @param cb
|
|
1464
1489
|
*/
|
|
1465
1490
|
API.prototype.shutdown = function shutdown(options, cb) {
|
|
1466
1491
|
this.agent.metrics.getOrCreateMetric(`${NAMES.SUPPORTABILITY.API}/shutdown`).incrementCallCount()
|
|
@@ -1483,9 +1508,31 @@ API.prototype.shutdown = function shutdown(options, cb) {
|
|
|
1483
1508
|
}
|
|
1484
1509
|
|
|
1485
1510
|
/**
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
* @param
|
|
1511
|
+
* Helper function for logging if an error occurs, and where
|
|
1512
|
+
*
|
|
1513
|
+
* @param {Error} error If defined, the error that occurred
|
|
1514
|
+
* @param {string} phase Where in the process the error happened
|
|
1515
|
+
* @returns {void}
|
|
1516
|
+
*/
|
|
1517
|
+
function _logErrorCallback(error, phase) {
|
|
1518
|
+
if (error) {
|
|
1519
|
+
logger.error(error, `An error occurred during ${phase}`)
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Function for handling the graceful shutdown process, including processing of data and handling errors
|
|
1525
|
+
*
|
|
1526
|
+
* @param {object} api instantiation of this file
|
|
1527
|
+
* @param {object} options shutdown options object
|
|
1528
|
+
* @param {boolean} [options.collectPendingData=false]
|
|
1529
|
+
* If true, the agent will send any pending data to the collector before
|
|
1530
|
+
* shutting down.
|
|
1531
|
+
* @param {number} [options.timeout=0]
|
|
1532
|
+
* Time in milliseconds to wait before shutting down.
|
|
1533
|
+
* @param {boolean} [options.waitForIdle=false]
|
|
1534
|
+
* If true, the agent will not shut down until there are no active transactions.
|
|
1535
|
+
* @param {Function} callback callback function to execute after shutdown process is complete (successful or not)
|
|
1489
1536
|
*/
|
|
1490
1537
|
function _doShutdown(api, options, callback) {
|
|
1491
1538
|
const agent = api.agent
|
|
@@ -1503,12 +1550,12 @@ function _doShutdown(api, options, callback) {
|
|
|
1503
1550
|
}
|
|
1504
1551
|
|
|
1505
1552
|
/**
|
|
1506
|
-
*
|
|
1553
|
+
* Callback function for after harvest cycles happen as part of shutdown process
|
|
1554
|
+
*
|
|
1555
|
+
* @param {Error} error If defined, the error that occurred during harvest
|
|
1507
1556
|
*/
|
|
1508
1557
|
function afterHarvest(error) {
|
|
1509
|
-
|
|
1510
|
-
logger.error(error, 'An error occurred while running last harvest before shutdown.')
|
|
1511
|
-
}
|
|
1558
|
+
_logErrorCallback(error, 'last harvest before shutdown')
|
|
1512
1559
|
agent.stop(callback)
|
|
1513
1560
|
}
|
|
1514
1561
|
|
|
@@ -1526,10 +1573,8 @@ function _doShutdown(api, options, callback) {
|
|
|
1526
1573
|
})
|
|
1527
1574
|
|
|
1528
1575
|
agent.on('errored', function logShutdownError(error) {
|
|
1576
|
+
_logErrorCallback(error, 'after shutdown')
|
|
1529
1577
|
agent.stop(callback)
|
|
1530
|
-
if (error) {
|
|
1531
|
-
logger.error(error, 'The agent encountered an error after calling shutdown.')
|
|
1532
|
-
}
|
|
1533
1578
|
})
|
|
1534
1579
|
} else if (options.collectPendingData) {
|
|
1535
1580
|
agent.forceHarvestAll(afterHarvest)
|
|
@@ -1539,8 +1584,12 @@ function _doShutdown(api, options, callback) {
|
|
|
1539
1584
|
}
|
|
1540
1585
|
|
|
1541
1586
|
/**
|
|
1542
|
-
*
|
|
1543
|
-
*
|
|
1587
|
+
* Validates that all keys in a given object have values that are less than or equal to a given length
|
|
1588
|
+
* Assumes all values have .length property (string/array)
|
|
1589
|
+
*
|
|
1590
|
+
* @param {object} object The object to validate
|
|
1591
|
+
* @param {number} maxLength The max allowed length
|
|
1592
|
+
* @returns {boolean} Whether or not the object passes validation
|
|
1544
1593
|
*/
|
|
1545
1594
|
function _checkKeyLength(object, maxLength) {
|
|
1546
1595
|
const keys = Object.keys(object)
|
|
@@ -1571,8 +1620,11 @@ API.prototype.setLambdaHandler = function setLambdaHandler(handler) {
|
|
|
1571
1620
|
}
|
|
1572
1621
|
|
|
1573
1622
|
/**
|
|
1574
|
-
*
|
|
1575
|
-
*
|
|
1623
|
+
* Function for removing invalid attribute key/value pairs from an object
|
|
1624
|
+
*
|
|
1625
|
+
* @param {object} attributes The attribute object
|
|
1626
|
+
* @param {string} name Caller name, used for debugging/logging purposes only
|
|
1627
|
+
* @returns {object} Attribute object containing only valid key/value pairs
|
|
1576
1628
|
*/
|
|
1577
1629
|
function _filterAttributes(attributes, name) {
|
|
1578
1630
|
const filteredAttributes = Object.create(null)
|