newrelic 9.5.0 → 9.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.
Files changed (104) hide show
  1. package/NEWS.md +14 -0
  2. package/api.js +2 -0
  3. package/bin/test-naming-rules.js +1 -1
  4. package/esm-loader.mjs +1 -3
  5. package/index.js +6 -5
  6. package/lib/adaptive-sampler.js +1 -2
  7. package/lib/agent.js +2 -0
  8. package/lib/aggregators/event-aggregator.js +2 -2
  9. package/lib/attributes.js +2 -4
  10. package/lib/collector/api.js +20 -12
  11. package/lib/collector/facts.js +1 -3
  12. package/lib/collector/parse-response.js +3 -1
  13. package/lib/collector/remote-method.js +10 -10
  14. package/lib/config/attribute-filter.js +14 -16
  15. package/lib/config/default.js +544 -286
  16. package/lib/config/formatters.js +108 -0
  17. package/lib/config/harvest-config-validator.js +3 -5
  18. package/lib/config/index.js +74 -93
  19. package/lib/environment.js +6 -5
  20. package/lib/errors/error-collector.js +6 -3
  21. package/lib/errors/helper.js +10 -18
  22. package/lib/errors/index.js +12 -6
  23. package/lib/grpc/connection.js +12 -5
  24. package/lib/header-attributes.js +4 -2
  25. package/lib/header-processing.js +2 -2
  26. package/lib/instrumentation/@hapi/hapi.js +231 -1
  27. package/lib/instrumentation/{vision.js → @hapi/vision.js} +0 -0
  28. package/lib/instrumentation/@node-redis/client.js +2 -0
  29. package/lib/instrumentation/amqplib.js +2 -0
  30. package/lib/instrumentation/core/async_hooks.js +3 -4
  31. package/lib/instrumentation/core/globals.js +12 -10
  32. package/lib/instrumentation/core/http-outbound.js +17 -17
  33. package/lib/instrumentation/core/http.js +16 -27
  34. package/lib/instrumentation/core/timers.js +5 -1
  35. package/lib/instrumentation/fastify.js +1 -3
  36. package/lib/instrumentation/grpc-js/grpc.js +14 -3
  37. package/lib/instrumentation/memcached.js +5 -0
  38. package/lib/instrumentation/mongodb/common.js +3 -0
  39. package/lib/instrumentation/mongodb/v2-mongo.js +6 -3
  40. package/lib/instrumentation/mongodb.js +1 -1
  41. package/lib/instrumentation/mysql/mysql.js +6 -5
  42. package/lib/instrumentation/nr-winston-transport.js +3 -4
  43. package/lib/instrumentation/promise.js +22 -18
  44. package/lib/instrumentation/redis.js +2 -0
  45. package/lib/instrumentation/undici.js +12 -15
  46. package/lib/instrumentations.js +1 -1
  47. package/lib/metrics/mapper.js +2 -3
  48. package/lib/metrics/metric-aggregator.js +1 -3
  49. package/lib/metrics/names.js +19 -15
  50. package/lib/metrics/normalizer/rule.js +6 -7
  51. package/lib/metrics/normalizer/tx_segment.js +3 -2
  52. package/lib/metrics/normalizer.js +5 -3
  53. package/lib/parse-proc-cpuinfo.js +11 -6
  54. package/lib/serverless/api-gateway.js +3 -4
  55. package/lib/serverless/aws-lambda.js +3 -3
  56. package/lib/shim/conglomerate-shim.js +2 -3
  57. package/lib/shim/constants.js +1 -16
  58. package/lib/shim/datastore-shim.js +24 -105
  59. package/lib/shim/index.js +7 -0
  60. package/lib/shim/message-shim.js +2 -0
  61. package/lib/shim/promise-shim.js +66 -59
  62. package/lib/shim/shim.js +44 -89
  63. package/lib/shim/transaction-shim.js +1 -1
  64. package/lib/shim/webframework-shim.js +4 -8
  65. package/lib/shimmer.js +29 -23
  66. package/lib/spans/map-to-streaming-type.js +0 -2
  67. package/lib/spans/span-context.js +2 -0
  68. package/lib/spans/span-event-aggregator.js +2 -2
  69. package/lib/spans/span-event.js +2 -2
  70. package/lib/spans/span-streamer.js +4 -0
  71. package/lib/spans/streaming-span-event-aggregator.js +2 -4
  72. package/lib/spans/streaming-span-event.js +3 -2
  73. package/lib/symbols.js +26 -0
  74. package/lib/system-info.js +4 -7
  75. package/lib/timer.js +8 -6
  76. package/lib/transaction/dt-payload.js +4 -3
  77. package/lib/transaction/handle.js +12 -2
  78. package/lib/transaction/index.js +19 -18
  79. package/lib/transaction/name-state.js +17 -2
  80. package/lib/transaction/trace/aggregator.js +4 -12
  81. package/lib/transaction/trace/index.js +7 -5
  82. package/lib/transaction/trace/segment.js +6 -11
  83. package/lib/transaction/tracecontext.js +10 -6
  84. package/lib/transaction/tracer/index.js +35 -43
  85. package/lib/transaction/transaction-event-aggregator.js +1 -3
  86. package/lib/util/arity.js +4 -9
  87. package/lib/util/attribute-types.js +1 -2
  88. package/lib/util/byte-limit.js +1 -3
  89. package/lib/util/cat.js +16 -13
  90. package/lib/util/codec.js +0 -2
  91. package/lib/util/copy.js +1 -2
  92. package/lib/util/deep-equal.js +7 -0
  93. package/lib/util/flatten.js +4 -6
  94. package/lib/util/hashes.js +1 -3
  95. package/lib/util/process-version.js +2 -3
  96. package/lib/util/properties.js +2 -51
  97. package/lib/util/stream-sink.js +2 -0
  98. package/lib/util/urltils.js +4 -10
  99. package/newrelic.js +1 -1
  100. package/package.json +2 -1
  101. package/lib/config/env.js +0 -294
  102. package/lib/instrumentation/hapi/hapi.js +0 -207
  103. package/lib/instrumentation/hapi/shared.js +0 -28
  104. package/lib/instrumentation/hapi.js +0 -254
@@ -0,0 +1,108 @@
1
+ /*
2
+ * Copyright 2022 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+ const formatters = module.exports
8
+
9
+ /**
10
+ * Splits a string by a ',' and trims whitespace
11
+ *
12
+ * @param {string} val config setting
13
+ * @param {Array}
14
+ */
15
+ formatters.array = function array(val) {
16
+ return val.split(',').map((k) => k.trim())
17
+ }
18
+
19
+ /**
20
+ * Parses a config setting as an int
21
+ *
22
+ * @param {string} val config setting
23
+ * @returns {int}
24
+ */
25
+ formatters.int = function int(val) {
26
+ return parseInt(val, 10)
27
+ }
28
+
29
+ /**
30
+ * Parses a config setting as a float
31
+ *
32
+ * @param {string} val config setting
33
+ * @returns {float}
34
+ */
35
+ formatters.float = function float(val) {
36
+ return parseFloat(val, 10)
37
+ }
38
+
39
+ /**
40
+ * Parses a config setting as a boolean
41
+ *
42
+ * @param {string} val config setting
43
+ * @param setting
44
+ * @returns {boolean}
45
+ */
46
+ formatters.boolean = function boolean(setting) {
47
+ if (setting == null) {
48
+ return false
49
+ }
50
+
51
+ const normalized = setting.toString().toLowerCase()
52
+ switch (normalized) {
53
+ case 'false':
54
+ case 'f':
55
+ case 'no':
56
+ case 'n':
57
+ case 'disabled':
58
+ case '0':
59
+ return false
60
+
61
+ default:
62
+ return true
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Parses a config setting as an object
68
+ *
69
+ * @param {string} val config setting
70
+ * @param {logger} logger agent logger instance
71
+ * @returns {object}
72
+ */
73
+ formatters.object = function object(val, logger) {
74
+ try {
75
+ return JSON.parse(val)
76
+ } catch (error) {
77
+ logger.error('New Relic configurator could not deserialize object:')
78
+ logger.error(error.stack)
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Parse a config setting as a collection with 1 object
84
+ *
85
+ * @param {string} val config setting
86
+ * @param {logger} logger agent logger instance
87
+ * @returns {Array}
88
+ */
89
+ formatters.objectList = function objectList(val, logger) {
90
+ try {
91
+ return JSON.parse('[' + val + ']')
92
+ } catch (error) {
93
+ logger.error('New Relic configurator could not deserialize object list:')
94
+ logger.error(error.stack)
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Checks if a value is within an allow list. If not it assigns
100
+ * the first element in allow list as default
101
+ *
102
+ * @param {Array} list allowable values
103
+ * @param {string} val config setting
104
+ * @returns {string}
105
+ */
106
+ formatters.allowList = function allowList(list, val) {
107
+ return list.includes(val) ? val : list[0]
108
+ }
@@ -12,17 +12,15 @@ function isValidHarvestConfig(harvestConfig) {
12
12
 
13
13
  const harvestLimits = harvestConfig.harvest_limits
14
14
 
15
- const isValid =
15
+ return (
16
16
  isValidHarvestValue(harvestConfig.report_period_ms) &&
17
17
  harvestLimits != null &&
18
18
  Object.keys(harvestLimits).length > 0
19
-
20
- return isValid
19
+ )
21
20
  }
22
21
 
23
22
  function isValidHarvestValue(value) {
24
- const isValid = value != null && value >= 0
25
- return !!isValid
23
+ return !!(value != null && value >= 0)
26
24
  }
27
25
 
28
26
  module.exports = {
@@ -5,10 +5,13 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 29] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+ /* eslint sonarjs/max-switch-cases: ["error", 36] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
10
+
8
11
  const AttributeFilter = require('./attribute-filter')
9
12
  const CollectorResponse = require('../collector/response')
10
13
  const copy = require('../util/copy')
11
- const defaultConfig = require('./default').config
14
+ const { config: defaultConfig, definition, setNestedKey } = require('./default')
12
15
  const EventEmitter = require('events').EventEmitter
13
16
  const featureFlag = require('../feature_flags')
14
17
  const flatten = require('../util/flatten')
@@ -22,6 +25,8 @@ const util = require('util')
22
25
  const MergeServerConfig = require('./merge-server-config')
23
26
  const harvestConfigValidator = require('./harvest-config-validator')
24
27
  const mergeServerConfig = new MergeServerConfig()
28
+ const { boolean: isTruthular } = require('./formatters')
29
+ const configDefinition = definition()
25
30
 
26
31
  /**
27
32
  * CONSTANTS -- we gotta lotta 'em
@@ -33,11 +38,11 @@ const BASE_CONFIG_PATH = require.resolve('../../newrelic')
33
38
  const HAS_ARBITRARY_KEYS = new Set(['ignore_messages', 'expected_messages', 'labels'])
34
39
 
35
40
  const LASP_MAP = require('./lasp').LASP_MAP
36
- const ENV = require('./env')
37
41
  const HSM = require('./hsm')
38
42
  const REMOVE_BEFORE_SEND = new Set(['attributeFilter'])
43
+ const SSL_WARNING = 'SSL config key can no longer be disabled, not updating.'
39
44
 
40
- const exists = fs.existsSync || path.existsSync
45
+ const exists = fs.existsSync
41
46
  let logger = null // Lazy-loaded in `initialize`.
42
47
  let _configInstance = null
43
48
 
@@ -56,35 +61,6 @@ const getConfigFileLocations = () =>
56
61
  : undefined
57
62
  ].filter(Boolean)
58
63
 
59
- function isTruthular(setting) {
60
- if (setting == null) {
61
- return false
62
- }
63
-
64
- const normalized = setting.toString().toLowerCase()
65
- switch (normalized) {
66
- case 'false':
67
- case 'f':
68
- case 'no':
69
- case 'n':
70
- case 'disabled':
71
- case '0':
72
- return false
73
-
74
- default:
75
- return true
76
- }
77
- }
78
-
79
- function fromObjectList(setting) {
80
- try {
81
- return JSON.parse('[' + setting + ']')
82
- } catch (error) {
83
- logger.error('New Relic configurator could not deserialize object list:')
84
- logger.error(error.stack)
85
- }
86
- }
87
-
88
64
  function _findConfigFile() {
89
65
  const configFileCandidates = getConfigFileLocations().reduce((files, configPath) => {
90
66
  const configFiles = getConfigFileNames().map((filename) =>
@@ -145,11 +121,6 @@ function Config(config) {
145
121
  this.collect_errors = true
146
122
  this.collect_span_events = true
147
123
 
148
- // override options for utilization stats
149
- this.utilization.logical_processors = null
150
- this.utilization.total_ram_mib = null
151
- this.utilization.billing_hostname = null
152
-
153
124
  this.browser_monitoring.loader = 'rum'
154
125
  this.browser_monitoring.loader_version = ''
155
126
 
@@ -338,7 +309,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
338
309
 
339
310
  case 'ssl':
340
311
  if (!isTruthular(params.ssl)) {
341
- logger.warn('SSL config key can no longer be disabled, not updating.')
312
+ logger.warn(SSL_WARNING)
342
313
  }
343
314
  break
344
315
 
@@ -996,7 +967,7 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
996
967
  }
997
968
 
998
969
  if (key === 'ssl' && !isTruthular(external.ssl)) {
999
- logger.warn('SSL config key can no longer be disabled, not updating.')
970
+ logger.warn(SSL_WARNING)
1000
971
  return
1001
972
  }
1002
973
 
@@ -1057,66 +1028,76 @@ Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
1057
1028
  }
1058
1029
 
1059
1030
  /**
1060
- * Recursively visit the nodes of the constant containing the mapping between
1061
- * environment variable names, overriding any configuration values that are
1062
- * found in the environment. Operates purely via side effects.
1031
+ * Creates an env var mapper from the configuration path value
1063
1032
  *
1064
- * @param object metadata The current level of the mapping object. Should never
1065
- * need to set this yourself.
1066
- * @param object data The current level of the configuration object. Should
1067
- * never need to set this yourself.
1068
- * @param metadata
1069
- * @param data
1033
+ * @param {string} key of configuration value
1034
+ * @param {Array} paths list of leaf nodes leading to configuration value
1035
+ * @returns {string} formatted env var name
1070
1036
  */
1071
- Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
1072
- if (!metadata) {
1073
- metadata = ENV.ENV_MAPPING
1074
- }
1075
- if (!data) {
1076
- data = this
1077
- }
1037
+ function deriveEnvVar(key, paths) {
1038
+ let path = paths.join('_')
1039
+ path = path ? `${path}_` : path
1040
+ return `NEW_RELIC_${path.toUpperCase()}${key.toUpperCase()}`
1041
+ }
1078
1042
 
1079
- Object.keys(metadata).forEach(function applyEnvDefault(value) {
1080
- // if it's not in the config, it doesn't exist
1081
- if (data[value] === undefined) {
1082
- return
1083
- }
1043
+ /**
1044
+ * Assigns the value of an env var to its corresponding configuration path
1045
+ *
1046
+ * @param {object} params
1047
+ * @param {object} params.config agent config
1048
+ * @param {string} params.key key to assign value
1049
+ * @param {string} params.envVar name of env var
1050
+ * @param {Function} params.formatter function to coerce env var as they are all strings
1051
+ * @param {Array} params.paths list of leaf nodes leading to the configuration value
1052
+ */
1053
+ function setFromEnv({ config, key, envVar, formatter, paths }) {
1054
+ const setting = process.env[envVar]
1055
+ if (setting) {
1056
+ const formattedSetting = formatter ? formatter(setting, logger) : setting
1057
+ setNestedKey(config, [...paths, key], formattedSetting)
1058
+ }
1059
+ }
1084
1060
 
1085
- const node = metadata[value]
1086
- if (typeof node === 'string') {
1087
- const setting = process.env[node]
1088
- if (setting) {
1089
- logger.debug(`${node} environment variable set.`)
1090
-
1091
- if (ENV.LIST_VARS.has(node)) {
1092
- const split = ENV.LIST_VARS_CUSTOM_DELIMITERS[node] || /,/
1093
- data[value] = setting.split(split).map(function trimVal(k) {
1094
- return k.trim()
1095
- })
1096
- } else if (ENV.OBJECT_LIST_VARS.has(node)) {
1097
- data[value] = fromObjectList(setting)
1098
- } else if (ENV.BOOLEAN_VARS.has(node)) {
1099
- if (value === 'ssl' && !isTruthular(setting)) {
1100
- logger.warn('SSL config key can no longer be disabled, not updating.')
1101
- return
1102
- }
1103
- data[value] = isTruthular(setting)
1104
- } else if (ENV.FLOAT_VARS.has(node)) {
1105
- data[value] = parseFloat(setting, 10)
1106
- } else if (ENV.INT_VARS.has(node)) {
1107
- data[value] = parseInt(setting, 10)
1108
- } else {
1109
- data[value] = setting
1110
- }
1111
- }
1112
- } else {
1113
- // don't crash if the mapping has config keys the current config doesn't.
1114
- if (!data[value]) {
1115
- data[value] = Object.create(null)
1061
+ /**
1062
+ * Recursively visit the nodes of the config definition and look for environment variable names, overriding any configuration values that are found.
1063
+ *
1064
+ * @param {object} [config=this] The current level of the configuration object.
1065
+ * @param {object} [data=configDefinition] The current level of the config definition object.
1066
+ * @param {Array} [paths=[]] keeps track of the nested path to properly derive the env var
1067
+ * @param {int} [objectKeys=1] indicator of how many keys exist in current node to know when to remove current node after all keys are processed
1068
+ */
1069
+ Config.prototype._fromEnvironment = function _fromEnvironment(
1070
+ config = this,
1071
+ data = configDefinition,
1072
+ paths = [],
1073
+ objectKeys = 1
1074
+ ) {
1075
+ let keysSeen = 0
1076
+ Object.entries(data).forEach(([key, value]) => {
1077
+ const type = typeof value
1078
+ keysSeen++
1079
+ if (type === 'string') {
1080
+ const envVar = deriveEnvVar(key, paths)
1081
+ setFromEnv({ config, key, envVar, paths })
1082
+ } else if (type === 'object') {
1083
+ if (value.hasOwnProperty('env')) {
1084
+ setFromEnv({ config, key, envVar: value.env, paths, formatter: value.formatter })
1085
+ } else if (value.hasOwnProperty('default')) {
1086
+ const envVar = deriveEnvVar(key, paths)
1087
+ setFromEnv({ config, key, envVar, formatter: value.formatter, paths })
1088
+ } else {
1089
+ paths.push(key)
1090
+ const { length } = Object.keys(value)
1091
+ this._fromEnvironment(config, value, paths, length)
1116
1092
  }
1117
- this._fromEnvironment(node, data[value])
1118
1093
  }
1119
- }, this)
1094
+ })
1095
+
1096
+ // we have traversed every key in current object leaf node, remove wrapping key
1097
+ // to properly derive env vars of future leaf nodes
1098
+ if (keysSeen === objectKeys) {
1099
+ paths.pop()
1100
+ }
1120
1101
  }
1121
1102
 
1122
1103
  /**
@@ -10,6 +10,7 @@ const { fsPromises } = require('./util/unwrapped-core')
10
10
  const os = require('os')
11
11
  const logger = require('./logger').child({ component: 'environment' })
12
12
  const stringify = require('json-stringify-safe')
13
+ const DISPATCHER_VERSION = 'Dispatcher Version'
13
14
 
14
15
  // As of 1.7.0 you can no longer dynamically link v8
15
16
  // https://github.com/nodejs/io.js/commit/d726a177ed
@@ -418,7 +419,7 @@ function refreshSyncOnly() {
418
419
  // gather persisted settings
419
420
  const framework = getSetting('Framework')
420
421
  const dispatcher = getSetting('Dispatcher')
421
- const dispatcherVersion = getSetting('Dispatcher Version')
422
+ const dispatcherVersion = getSetting(DISPATCHER_VERSION)
422
423
 
423
424
  // clearing and rebuilding a global variable
424
425
  settings = Object.create(null)
@@ -437,7 +438,7 @@ function refreshSyncOnly() {
437
438
 
438
439
  if (dispatcherVersion.length) {
439
440
  dispatcher.forEach(function addDispatchers(d) {
440
- addSetting('Dispatcher Version', d)
441
+ addSetting(DISPATCHER_VERSION, d)
441
442
  })
442
443
  }
443
444
 
@@ -503,12 +504,12 @@ module.exports = {
503
504
  }
504
505
 
505
506
  userSetDispatcher = !!userSet
506
- clearSetting('Dispatcher Version')
507
+ clearSetting(DISPATCHER_VERSION)
507
508
  clearSetting('Dispatcher')
508
509
 
509
510
  // TODO: Decide if this should only happen once for internals as well.
510
511
  if (version) {
511
- addSetting('Dispatcher Version', version)
512
+ addSetting(DISPATCHER_VERSION, version)
512
513
  }
513
514
 
514
515
  addSetting('Dispatcher', dispatcher)
@@ -520,7 +521,7 @@ module.exports = {
520
521
  // This method is only used for tests.
521
522
  userSetDispatcher = false
522
523
  clearSetting('Dispatcher')
523
- clearSetting('Dispatcher Version')
524
+ clearSetting(DISPATCHER_VERSION)
524
525
  },
525
526
  listPackages,
526
527
  getJSON,
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 25] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const errorsModule = require('./index')
9
11
 
10
12
  const logger = require('../logger').child({ component: 'error_tracer' })
@@ -112,8 +114,7 @@ class ErrorCollector {
112
114
  * possible.
113
115
  *
114
116
  * @param {Transaction} transaction
115
- *
116
- * @return {number} The number of unexpected errors
117
+ * @returns {number} The number of unexpected errors
117
118
  */
118
119
  onTransactionFinished(transaction) {
119
120
  if (!transaction) {
@@ -226,6 +227,8 @@ class ErrorCollector {
226
227
  *
227
228
  * @param {?Transaction} transaction Transaction associated with the error.
228
229
  * @param {Exception} exception The Exception to be traced.
230
+ * @param error
231
+ * @param customAttributes
229
232
  */
230
233
  addUserError(transaction, error, customAttributes) {
231
234
  if (!error) {
@@ -260,7 +263,7 @@ class ErrorCollector {
260
263
  *
261
264
  * @param {?Transaction} transaction Transaction associated with the error.
262
265
  * @param {?Exception} exception The Exception object to be traced.
263
- * @return {bool} True if the error was collected.
266
+ * @returns {bool} True if the error was collected.
264
267
  */
265
268
  collect(transaction, exception) {
266
269
  if (!exception) {
@@ -21,20 +21,17 @@ module.exports = {
21
21
  if (!config.error_collector.expected_messages[type]) {
22
22
  return false
23
23
  }
24
- if (config.error_collector.expected_messages[type].length > 0) {
25
- if (-1 !== config.error_collector.expected_messages[type].indexOf(message)) {
26
- return true
27
- }
28
- }
29
- return false
24
+
25
+ return (
26
+ config.error_collector.expected_messages[type].length > 0 &&
27
+ config.error_collector.expected_messages[type].indexOf(message) !== -1
28
+ )
30
29
  },
31
30
  isExpectedErrorClass: function isExpectedErrorClass(config, className) {
32
- if (config.error_collector.expected_classes.length > 0) {
33
- if (-1 !== config.error_collector.expected_classes.indexOf(className)) {
34
- return true
35
- }
36
- }
37
- return false
31
+ return (
32
+ config.error_collector.expected_classes.length > 0 &&
33
+ config.error_collector.expected_classes.indexOf(className) !== -1
34
+ )
38
35
  },
39
36
  isExpectedException: function isExpectedException(transaction, exception, config, urltils) {
40
37
  const { type, message } = this.extractErrorInformation(transaction, exception, config, urltils)
@@ -123,11 +120,6 @@ module.exports = {
123
120
  return false
124
121
  }
125
122
 
126
- if (configIgnoreMessages.length > 0) {
127
- if (-1 !== configIgnoreMessages.indexOf(errorInfo.message)) {
128
- return true
129
- }
130
- }
131
- return false
123
+ return configIgnoreMessages.length > 0 && configIgnoreMessages.indexOf(errorInfo.message) !== -1
132
124
  }
133
125
  }
@@ -5,11 +5,14 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ /* eslint sonarjs/cognitive-complexity: ["error", 22] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
9
+
8
10
  const DESTINATIONS = require('../config/attribute-filter').DESTINATIONS
9
11
  const NAMES = require('../metrics/names')
10
12
  const props = require('../util/properties')
11
13
  const urltils = require('../util/urltils')
12
14
  const errorHelper = require('../errors/helper')
15
+ const ERROR_EXPECTED_PATH = 'error.expected'
13
16
 
14
17
  class Exception {
15
18
  constructor({ error, timestamp, customAttributes, agentAttributes }) {
@@ -101,9 +104,9 @@ function createError(transaction, exception, config) {
101
104
  }
102
105
  }
103
106
 
104
- params.intrinsics['error.expected'] = false
107
+ params.intrinsics[ERROR_EXPECTED_PATH] = false
105
108
  if (errorHelper.isExpected(type, message, transaction, config, urltils)) {
106
- params.intrinsics['error.expected'] = true
109
+ params.intrinsics[ERROR_EXPECTED_PATH] = true
107
110
  }
108
111
 
109
112
  const res = [0, name, message, type, params]
@@ -116,6 +119,11 @@ function createError(transaction, exception, config) {
116
119
  /**
117
120
  * Creates a structure for error event that is sent to the collector.
118
121
  * The error parameter is an output of the createError() function for a given exception.
122
+ *
123
+ * @param transaction
124
+ * @param error
125
+ * @param timestamp
126
+ * @param config
119
127
  */
120
128
  function createEvent(transaction, error, timestamp, config) {
121
129
  const message = error[2]
@@ -126,7 +134,7 @@ function createEvent(transaction, error, timestamp, config) {
126
134
  transaction,
127
135
  errorClass,
128
136
  message,
129
- errorParams.intrinsics['error.expected'],
137
+ errorParams.intrinsics[ERROR_EXPECTED_PATH],
130
138
  timestamp,
131
139
  config
132
140
  )
@@ -136,9 +144,7 @@ function createEvent(transaction, error, timestamp, config) {
136
144
  const userAttributes = Object.assign(Object.create(null), errorParams.userAttributes)
137
145
  const agentAttributes = Object.assign(Object.create(null), errorParams.agentAttributes)
138
146
 
139
- const errorEvent = [intrinsicAttributes, userAttributes, agentAttributes]
140
-
141
- return errorEvent
147
+ return [intrinsicAttributes, userAttributes, agentAttributes]
142
148
  }
143
149
 
144
150
  // eslint-disable-next-line max-params
@@ -41,9 +41,9 @@ class GrpcConnection extends EventEmitter {
41
41
  * Standard property setting/initialization, and sets an initial
42
42
  * connection state of disconnected
43
43
  *
44
- * @param {Object} traceObserverConfig config item config.infinite_tracing.trace_observer
44
+ * @param {object} traceObserverConfig config item config.infinite_tracing.trace_observer
45
45
  * @param {MetricAggregator} metrics metric aggregator, for supportability metrics
46
- * @param {Number} [reconnectDelayMs=15000] number of milliseconds to wait before reconnecting
46
+ * @param {number} [reconnectDelayMs=15000] number of milliseconds to wait before reconnecting
47
47
  * for error states that require a reconnect delay.
48
48
  */
49
49
  constructor(traceObserverConfig, metrics, reconnectDelayMs) {
@@ -97,6 +97,7 @@ class GrpcConnection extends EventEmitter {
97
97
  *
98
98
  * @param {int} state The connection state (See connectionStates above)
99
99
  * @param {ClientDuplexStreamImpl} state The GRPC stream, when defined
100
+ * @param stream
100
101
  */
101
102
  _setState(state, stream = null) {
102
103
  this._state = state
@@ -146,6 +147,8 @@ class GrpcConnection extends EventEmitter {
146
147
  *
147
148
  * @param {string} licenseKey
148
149
  * @param {string} runId
150
+ * @param requestHeadersMap
151
+ * @param env
149
152
  */
150
153
  _getMetadata(licenseKey, runId, requestHeadersMap, env) {
151
154
  const metadata = new grpc.Metadata()
@@ -170,6 +173,7 @@ class GrpcConnection extends EventEmitter {
170
173
  * when appropriate env vars are set
171
174
  *
172
175
  * @param {Metadata} metadata
176
+ * @param env
173
177
  */
174
178
  _setTestMetadata(metadata, env) {
175
179
  for (const [key, envVar] of Object.entries(GRPC_TEST_META)) {
@@ -183,6 +187,7 @@ class GrpcConnection extends EventEmitter {
183
187
 
184
188
  /**
185
189
  * Disconnects from gRPC endpoint and schedules establishing a new connection.
190
+ *
186
191
  * @param {number} reconnectDelayMs number of milliseconds to wait before reconnecting.
187
192
  */
188
193
  _reconnect(reconnectDelayMs = 0) {
@@ -291,6 +296,8 @@ class GrpcConnection extends EventEmitter {
291
296
 
292
297
  /**
293
298
  * Creates the GRPC credentials needed
299
+ *
300
+ * @param grpcApi
294
301
  */
295
302
  _generateCredentials(grpcApi) {
296
303
  let certBuffer = null
@@ -349,6 +356,8 @@ class GrpcConnection extends EventEmitter {
349
356
  * ChannelImplementation and related objects will stay in memory even after
350
357
  * the stream is closed and we do not have a handle to the client. Currently
351
358
  * impacting grpc-js@1.2.11 and several earlier versions.
359
+ *
360
+ * @param endpoint
352
361
  */
353
362
  _createClient(endpoint) {
354
363
  logger.trace('Creating gRPC client for: ', endpoint)
@@ -360,9 +369,7 @@ class GrpcConnection extends EventEmitter {
360
369
  const traceApi = protoDescriptor.com.newrelic.trace.v1
361
370
 
362
371
  const credentials = this._generateCredentials(grpc)
363
- const client = new traceApi.IngestService(endpoint, credentials)
364
-
365
- return client
372
+ return new traceApi.IngestService(endpoint, credentials)
366
373
  }
367
374
  }
368
375
 
@@ -139,7 +139,8 @@ function _collectHeaders(headers, nameMap, prefix, transaction) {
139
139
 
140
140
  /**
141
141
  * Adds request headers as request.headers.* attributes to the given transaction.
142
- * @param {Object.<string, string>} headers - Request headers to add attributes for.
142
+ *
143
+ * @param {Object<string, string>} headers - Request headers to add attributes for.
143
144
  * @param {Transaction} transaction - Transaction to add header attributes to.
144
145
  */
145
146
  function collectRequestHeaders(headers, transaction) {
@@ -148,7 +149,8 @@ function collectRequestHeaders(headers, transaction) {
148
149
 
149
150
  /**
150
151
  * Adds response headers as response.headers.* attributes to the given transaction.
151
- * @param {Object.<string, string>} headers - Response headers to add attributes for.
152
+ *
153
+ * @param {Object<string, string>} headers - Response headers to add attributes for.
152
154
  * @param {Transaction} transaction - Transaction to add header attributes to.
153
155
  */
154
156
  function collectResponseHeaders(headers, transaction) {
@@ -14,6 +14,7 @@ const CONTENT_LENGTH_REGEX = /^Content-Length$/i
14
14
  *
15
15
  * Queue time is provided by certain providers by stamping the request
16
16
  * header with the time the request arrived at the router.
17
+ *
17
18
  * @param {*} logger
18
19
  * @param {*} requestHeaders
19
20
  */
@@ -37,8 +38,7 @@ function getQueueTime(logger, requestHeaders) {
37
38
  return null
38
39
  }
39
40
 
40
- const convertedQueueTime = convertUnit(parsedQueueTime)
41
- return convertedQueueTime
41
+ return convertUnit(parsedQueueTime)
42
42
  }
43
43
 
44
44
  function convertUnit(time) {