newrelic 12.8.2 → 12.10.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 (108) hide show
  1. package/NEWS.md +45 -0
  2. package/THIRD_PARTY_NOTICES.md +47 -243
  3. package/api.js +14 -13
  4. package/bin/test-naming-rules.js +2 -3
  5. package/index.js +0 -4
  6. package/lib/agent.js +2 -1
  7. package/lib/aggregators/base-aggregator.js +2 -2
  8. package/lib/aggregators/trace-aggregator.js +1 -5
  9. package/lib/attributes.js +5 -5
  10. package/lib/collector/api.js +1 -3
  11. package/lib/collector/facts.js +2 -2
  12. package/lib/collector/http-agents.js +2 -2
  13. package/lib/collector/remote-method.js +4 -4
  14. package/lib/config/attribute-filter.js +1 -1
  15. package/lib/config/default.js +2 -2
  16. package/lib/config/harvest-config-validator.js +2 -2
  17. package/lib/config/index.js +12 -12
  18. package/lib/config/merge-server-config.js +1 -2
  19. package/lib/custom-events/custom-event-aggregator.js +0 -1
  20. package/lib/db/query-parsers/sql.js +2 -0
  21. package/lib/db/slow-query.js +1 -0
  22. package/lib/db/statement-matcher.js +3 -2
  23. package/lib/db/utils.js +4 -0
  24. package/lib/environment.js +2 -2
  25. package/lib/errors/error-collector.js +2 -2
  26. package/lib/errors/error-event-aggregator.js +1 -0
  27. package/lib/errors/helper.js +4 -4
  28. package/lib/errors/index.js +5 -6
  29. package/lib/grpc/connection.js +1 -1
  30. package/lib/header-attributes.js +21 -20
  31. package/lib/instrumentation/@elastic/elasticsearch.js +2 -2
  32. package/lib/instrumentation/@opensearch-project/opensearch.js +161 -0
  33. package/lib/instrumentation/@prisma/client.js +4 -3
  34. package/lib/instrumentation/amqplib/utils.js +1 -1
  35. package/lib/instrumentation/aws-sdk/v3/common.js +4 -7
  36. package/lib/instrumentation/aws-sdk/v3/lambda.js +56 -0
  37. package/lib/instrumentation/aws-sdk/v3/smithy-client.js +2 -0
  38. package/lib/instrumentation/bluebird.js +1 -0
  39. package/lib/instrumentation/connect.js +1 -1
  40. package/lib/instrumentation/core/http-outbound.js +1 -2
  41. package/lib/instrumentation/core/http.js +2 -2
  42. package/lib/instrumentation/core/timers.js +0 -1
  43. package/lib/instrumentation/express.js +1 -1
  44. package/lib/instrumentation/kafkajs/consumer.js +1 -1
  45. package/lib/instrumentation/mysql/mysql.js +2 -2
  46. package/lib/instrumentation/openai.js +1 -2
  47. package/lib/instrumentation/undici.js +2 -1
  48. package/lib/instrumentation/when/contextualizer.js +2 -1
  49. package/lib/instrumentation/when/index.js +3 -1
  50. package/lib/instrumentations.js +27 -26
  51. package/lib/llm-events/aws-bedrock/bedrock-response.js +0 -2
  52. package/lib/llm-events/aws-bedrock/chat-completion-summary.js +1 -0
  53. package/lib/llm-events/aws-bedrock/embedding.js +1 -0
  54. package/lib/llm-events/aws-bedrock/event.js +1 -1
  55. package/lib/llm-events/aws-bedrock/stream-handler.js +6 -6
  56. package/lib/llm-events/event.js +1 -0
  57. package/lib/llm-events/langchain/chat-completion-summary.js +2 -2
  58. package/lib/llm-events/langchain/event.js +1 -0
  59. package/lib/llm-events/langchain/vector-search.js +2 -2
  60. package/lib/logger.js +0 -2
  61. package/lib/metrics/index.js +0 -1
  62. package/lib/metrics/mapper.js +2 -2
  63. package/lib/metrics/names.js +1 -1
  64. package/lib/metrics/normalizer/rule.js +2 -1
  65. package/lib/metrics/normalizer/tx_segment.js +4 -2
  66. package/lib/metrics/normalizer.js +5 -5
  67. package/lib/prioritized-attributes.js +3 -2
  68. package/lib/priority-queue.js +1 -1
  69. package/lib/reservoir.js +1 -1
  70. package/lib/sampler.js +5 -5
  71. package/lib/serverless/api-gateway.js +13 -79
  72. package/lib/serverless/aws-lambda.js +5 -3
  73. package/lib/shim/conglomerate-shim.js +5 -0
  74. package/lib/shim/datastore-shim.js +2 -1
  75. package/lib/shim/message-shim/consume.js +2 -1
  76. package/lib/shim/message-shim/index.js +1 -1
  77. package/lib/shim/message-shim/subscribe-consume.js +10 -12
  78. package/lib/shim/promise-shim.js +8 -8
  79. package/lib/shim/shim.js +10 -12
  80. package/lib/shim/webframework-shim/index.js +1 -1
  81. package/lib/shim/webframework-shim/middleware.js +1 -1
  82. package/lib/shimmer.js +2 -3
  83. package/lib/spans/base-span-streamer.js +1 -1
  84. package/lib/spans/map-to-streaming-type.js +0 -3
  85. package/lib/spans/span-event-aggregator.js +1 -1
  86. package/lib/spans/span-streamer.js +0 -4
  87. package/lib/spans/streaming-span-event-aggregator.js +1 -3
  88. package/lib/system-info.js +1 -2
  89. package/lib/timer.js +0 -1
  90. package/lib/transaction/index.js +9 -6
  91. package/lib/transaction/name-state.js +6 -5
  92. package/lib/transaction/trace/exclusive-time-calculator.js +1 -1
  93. package/lib/transaction/trace/segment.js +0 -1
  94. package/lib/transaction/tracecontext.js +3 -3
  95. package/lib/util/cat.js +3 -3
  96. package/lib/util/copy.js +1 -1
  97. package/lib/util/deep-equal.js +1 -1
  98. package/lib/util/hashes.js +2 -0
  99. package/lib/util/label-parser.js +1 -0
  100. package/lib/util/logger.js +2 -4
  101. package/lib/util/sql/obfuscate.js +7 -4
  102. package/lib/util/urltils.js +3 -3
  103. package/lib/utilization/aws-info.js +1 -0
  104. package/lib/utilization/azure-info.js +1 -0
  105. package/lib/utilization/docker-info.js +4 -4
  106. package/lib/utilization/index.js +1 -1
  107. package/package.json +10 -12
  108. package/stub_api.js +1 -2
package/lib/attributes.js CHANGED
@@ -22,7 +22,7 @@ class Attributes {
22
22
  * @param {string} scope
23
23
  * The scope of the attributes this will collect. Must be `transaction` or
24
24
  * `segment`.
25
- * @param {number} [limit=Infinity]
25
+ * @param {number} [limit]
26
26
  * The maximum number of attributes to retrieve for each destination.
27
27
  */
28
28
  constructor(scope, limit = Infinity) {
@@ -64,9 +64,9 @@ class Attributes {
64
64
  */
65
65
  get(dest) {
66
66
  const attrs = Object.create(null)
67
- // eslint-disable-next-line guard-for-in
68
67
  for (const key in this.attributes) {
69
68
  const attr = this.attributes[key]
69
+ // eslint-disable-next-line sonarjs/bitwise-operators
70
70
  if (!(attr.destinations & dest)) {
71
71
  continue
72
72
  }
@@ -104,7 +104,7 @@ class Attributes {
104
104
  * @param {DESTINATIONS} destinations - The default destinations for this key.
105
105
  * @param {string} key - The attribute name.
106
106
  * @param {string} value - The attribute value.
107
- * @param {boolean} [truncateExempt=false] - Flag marking value exempt from truncation
107
+ * @param {boolean} [truncateExempt] - Flag marking value exempt from truncation
108
108
  */
109
109
  addAttribute(destinations, key, value, truncateExempt = false) {
110
110
  if (this.attributeCount + 1 > this.limit) {
@@ -180,6 +180,6 @@ function makeFilter(scope) {
180
180
  }
181
181
 
182
182
  module.exports = {
183
- Attributes: Attributes,
184
- MAXIMUM_CUSTOM_ATTRIBUTES: MAXIMUM_CUSTOM_ATTRIBUTES
183
+ Attributes,
184
+ MAXIMUM_CUSTOM_ATTRIBUTES
185
185
  }
@@ -5,7 +5,6 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const http = require('http')
9
8
  const CollectorResponse = require('./response')
10
9
  const facts = require('./facts')
11
10
  const logger = require('../logger').child({ component: 'collector_api' })
@@ -341,7 +340,7 @@ CollectorAPI.prototype._handlePreConnectResponse = function _handlePreConnectRes
341
340
 
342
341
  const [host, port] = parts
343
342
  const newEndpoint = {
344
- host: host,
343
+ host,
345
344
  port: port || DEFAULT_PORT
346
345
  }
347
346
 
@@ -614,7 +613,6 @@ CollectorAPI.prototype._handleResponseCode = _handleResponseCode
614
613
  function _handleResponseCode(response, endpoint, cb) {
615
614
  const code = response.status
616
615
 
617
- /* eslint-disable padded-blocks */
618
616
  if (SUCCESS.has(code)) {
619
617
  // The request was a success!
620
618
  setImmediate(cb, null, CollectorResponse.success(response.payload))
@@ -37,7 +37,7 @@ async function facts(agent, callback, { logger = defaultLogger } = {}) {
37
37
  metadata_version: 5,
38
38
  logical_processors: systemInfo.logicalProcessors || null,
39
39
  total_ram_mib: systemInfo.memory || null,
40
- hostname: hostname
40
+ hostname
41
41
  },
42
42
  pid: process.pid,
43
43
  host: hostname,
@@ -45,7 +45,7 @@ async function facts(agent, callback, { logger = defaultLogger } = {}) {
45
45
  language: 'nodejs',
46
46
  app_name: agent.config.applications(),
47
47
  agent_version: agent.version,
48
- environment: environment,
48
+ environment,
49
49
  settings: agent.config.publicSettings(),
50
50
  high_security: agent.config.high_security,
51
51
  labels: agent.config.parsedLabels,
@@ -27,7 +27,7 @@ exports.keepAliveAgent = function keepAliveAgent(config) {
27
27
  // always return the same agent instance, which
28
28
  // ensures all requests share the same http
29
29
  // connection
30
- if (null !== agentKeepAlive) {
30
+ if (agentKeepAlive !== null) {
31
31
  return agentKeepAlive
32
32
  }
33
33
 
@@ -48,7 +48,7 @@ exports.keepAliveAgent = function keepAliveAgent(config) {
48
48
  * @param config
49
49
  */
50
50
  exports.proxyAgent = function proxyAgent(config) {
51
- if (null !== agentProxyWithKeepAlive) {
51
+ if (agentProxyWithKeepAlive !== null) {
52
52
  return agentProxyWithKeepAlive
53
53
  }
54
54
  const proxyUrl = proxyOptions(config)
@@ -92,7 +92,7 @@ RemoteMethod.prototype._reportDataUsage = function reportDataUsage(sent, receive
92
92
  * you're doing it wrong.
93
93
  *
94
94
  * @param {object} payload Serializable payload.
95
- * @param {object} [nrHeaders=null] NR request headers from connect response.
95
+ * @param {object} [nrHeaders] NR request headers from connect response.
96
96
  * @param {Function} callback What to do next. Gets passed any error.
97
97
  */
98
98
  RemoteMethod.prototype.invoke = function invoke(payload, nrHeaders, callback) {
@@ -359,7 +359,7 @@ RemoteMethod.prototype._path = function _path({ redactLicenseKey } = {}) {
359
359
 
360
360
  return url.format({
361
361
  pathname: RAW_METHOD_PATH,
362
- query: query
362
+ query
363
363
  })
364
364
  }
365
365
 
@@ -374,9 +374,9 @@ RemoteMethod.prototype._headers = function _headers(options) {
374
374
 
375
375
  const headers = {
376
376
  // select the virtual host on the server end
377
- 'Host': this.endpoint.host,
377
+ Host: this.endpoint.host,
378
378
  'User-Agent': agent,
379
- 'Connection': 'Keep-Alive',
379
+ Connection: 'Keep-Alive',
380
380
  'Content-Length': byteLength(options.body),
381
381
  'Content-Type': 'application/json'
382
382
  }
@@ -347,7 +347,7 @@ function _convertRulesToRegex(rules) {
347
347
  // 'fizz.bang' => ['fizz', 'bang']
348
348
  // '*' => ['\\*']
349
349
  return rule
350
- .replace(/([.*+?|\\^$()\[\]])/g, function cleaner(m) {
350
+ .replace(/([.*+?|\\^$()[\]])/g, function cleaner(m) {
351
351
  return '\\' + m
352
352
  })
353
353
  .split('.')
@@ -33,7 +33,7 @@ defaultConfig.definition = () => ({
33
33
  */
34
34
  app_name: {
35
35
  formatter(val) {
36
- return val.split(/;|,/).map((k) => k.trim())
36
+ return val.split(/[;,]/).map((k) => k.trim())
37
37
  },
38
38
  default: []
39
39
  },
@@ -1589,7 +1589,7 @@ function buildConfig(definition, config, paths = [], objectKeys = 1) {
1589
1589
  if (type === 'string') {
1590
1590
  assignConfigValue({ config: conf, key, value, paths })
1591
1591
  } else if (type === 'object') {
1592
- if (value.hasOwnProperty('default')) {
1592
+ if (Object.prototype.hasOwnProperty.call(value, 'default')) {
1593
1593
  assignConfigValue({ config: conf, key, value: value.default, paths })
1594
1594
  } else {
1595
1595
  // add the current leaf node key to the paths and recurse through function again
@@ -24,6 +24,6 @@ function isValidHarvestValue(value) {
24
24
  }
25
25
 
26
26
  module.exports = {
27
- isValidHarvestConfig: isValidHarvestConfig,
28
- isValidHarvestValue: isValidHarvestValue
27
+ isValidHarvestConfig,
28
+ isValidHarvestValue
29
29
  }
@@ -45,7 +45,9 @@ let logger = null // Lazy-loaded in `initialize`.
45
45
  let _configInstance = null
46
46
 
47
47
  const getConfigFileNames = () =>
48
- [process.env.NEW_RELIC_CONFIG_FILENAME, 'newrelic.js', 'newrelic.cjs'].filter(Boolean)
48
+ [process.env.NEW_RELIC_CONFIG_FILENAME, 'newrelic.js', 'newrelic.cjs', 'newrelic.mjs'].filter(
49
+ Boolean
50
+ )
49
51
 
50
52
  const getConfigFileLocations = () =>
51
53
  [
@@ -591,7 +593,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
591
593
  case 'rum.load_episodes_file':
592
594
  // Ensure the most secure setting is applied to the settings below
593
595
  // when enabling them.
594
- case 'attributes.include_enabled':
596
+ case 'attributes.include_enabled': // eslint-disable-line no-fallthrough
595
597
  case 'strip_exception_messages.enabled':
596
598
  case 'transaction_tracer.record_sql':
597
599
  this.logUnsupported(params, key)
@@ -693,7 +695,7 @@ function _validateThenUpdateStatusCodes(remote, local, remoteKey, localKey) {
693
695
 
694
696
  let valid = true
695
697
  valueToTest.forEach(function validateArray(thingToTest) {
696
- if (!('string' === typeof thingToTest || 'number' === typeof thingToTest)) {
698
+ if (!(typeof thingToTest === 'string' || typeof thingToTest === 'number')) {
697
699
  logger.warn(
698
700
  'Saw SSC (ignore|expect)_status_code that is not a number or string,' +
699
701
  'will not merge: %s',
@@ -738,7 +740,7 @@ function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
738
740
  let valid = true
739
741
  Object.keys(valueToTest).forEach(function validateArray(key) {
740
742
  const thingToTest = valueToTest[key]
741
- if ('string' !== typeof thingToTest) {
743
+ if (typeof thingToTest !== 'string') {
742
744
  logger.warn(
743
745
  'Saw SSC (ignore|expect)_class that is not a string, will not merge: %s',
744
746
  thingToTest
@@ -781,7 +783,7 @@ function _validateThenUpdateErrorMessages(remote, local, remoteKey, localKey) {
781
783
  return
782
784
  }
783
785
 
784
- if ('object' !== typeof valueToTest) {
786
+ if (typeof valueToTest !== 'object') {
785
787
  logger.warn(
786
788
  'Saw SSC (ignore|expect)_message that is primitive/scaler, will not merge: %s',
787
789
  valueToTest
@@ -984,7 +986,7 @@ function getHostnameSafe() {
984
986
  _hostname = os.hostname()
985
987
  }
986
988
  return _hostname
987
- } catch (e) {
989
+ } catch {
988
990
  const addresses = this.getIPAddresses()
989
991
 
990
992
  if (this.process_host.ipv_preference === '6' && addresses.ipv6) {
@@ -1052,7 +1054,7 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
1052
1054
  let node = null
1053
1055
  try {
1054
1056
  node = external[key]
1055
- } catch (err) {
1057
+ } catch {
1056
1058
  logger.warn('Error thrown on access of user config for key: %s', key)
1057
1059
  return
1058
1060
  }
@@ -1158,7 +1160,7 @@ Config.prototype._fromEnvironment = function _fromEnvironment(
1158
1160
  const envVar = deriveEnvVar(key, paths)
1159
1161
  setFromEnv({ config, key, envVar, paths })
1160
1162
  } else if (type === 'object') {
1161
- if (value.hasOwnProperty('env')) {
1163
+ if (Object.prototype.hasOwnProperty.call(value, 'env')) {
1162
1164
  setFromEnv({
1163
1165
  config,
1164
1166
  key,
@@ -1166,7 +1168,7 @@ Config.prototype._fromEnvironment = function _fromEnvironment(
1166
1168
  paths,
1167
1169
  formatter: value.formatter
1168
1170
  })
1169
- } else if (value.hasOwnProperty('default')) {
1171
+ } else if (Object.prototype.hasOwnProperty.call(value, 'default')) {
1170
1172
  const envVar = deriveEnvVar(key, paths)
1171
1173
  setFromEnv({ config, key, envVar, formatter: value.formatter, paths })
1172
1174
  } else {
@@ -1657,7 +1659,7 @@ Config.prototype.publicSettings = function publicSettings() {
1657
1659
  let settings = Object.create(null)
1658
1660
 
1659
1661
  for (const key in this) {
1660
- if (this.hasOwnProperty(key) && !REMOVE_BEFORE_SEND.has(key)) {
1662
+ if (Object.prototype.hasOwnProperty.call(this, key) && !REMOVE_BEFORE_SEND.has(key)) {
1661
1663
  if (HSM.REDACT_BEFORE_SEND.has(key)) {
1662
1664
  const value = this[key]
1663
1665
  settings[key] = redactValue(value)
@@ -1823,10 +1825,8 @@ function getOrCreateInstance() {
1823
1825
  try {
1824
1826
  _configInstance = initialize()
1825
1827
  } catch (err) {
1826
- /* eslint-disable no-console */
1827
1828
  console.error('New Relic for Node.js is disabled due to an error:')
1828
1829
  console.error(err.stack)
1829
- /* eslint-enable no-console */
1830
1830
 
1831
1831
  // Config construction has potential to throw due to invalid settings.
1832
1832
  // This allows the agent to return a stub api without crashing the process.
@@ -8,7 +8,6 @@
8
8
  const { isSimpleObject } = require('../util/objects')
9
9
 
10
10
  class MergeServerConfig {
11
- // eslint-disable-next-line max-params
12
11
  updateNestedIfChanged(config, remote, local, remoteKey, localKey, logger) {
13
12
  const value = remote[remoteKey]
14
13
 
@@ -46,7 +45,7 @@ class MergeServerConfig {
46
45
  if (Array.isArray(local[localKey][element]) && Array.isArray(value[element])) {
47
46
  // if both key-values are arrays, push the remote value onto the local array
48
47
  value[element].forEach((elementValue) => {
49
- if (-1 === local[localKey][element].indexOf(elementValue)) {
48
+ if (local[localKey][element].indexOf(elementValue) === -1) {
50
49
  local[localKey][element].push(elementValue)
51
50
  }
52
51
  })
@@ -12,7 +12,6 @@ class CustomEventAggregator extends EventAggregator {
12
12
  constructor(opts, agent) {
13
13
  opts = opts || {}
14
14
  opts.method = opts.method || 'custom_event_data'
15
- opts.metricNames = opts.metricNames
16
15
 
17
16
  super(opts, agent)
18
17
  }
@@ -9,6 +9,7 @@ const logger = require('../../logger').child({ component: 'sql_query_parser' })
9
9
  const StatementMatcher = require('../statement-matcher')
10
10
  const stringify = require('json-stringify-safe')
11
11
 
12
+ /* eslint-disable no-useless-escape, sonarjs/slow-regex, sonarjs/duplicates-in-character-class */
12
13
  const OPERATIONS = [
13
14
  new StatementMatcher(
14
15
  'select',
@@ -22,6 +23,7 @@ const OPERATIONS = [
22
23
  new StatementMatcher('delete', /^[^\S]*?delete[^\S]+?from[^\S]+([^\s\n\r,(;]+)/gim)
23
24
  ]
24
25
  const COMMENT_PATTERN = /\/\\*.*?\\*\//g
26
+ /* eslint-enable no-useless-escape, sonarjs/slow-regex, sonarjs/duplicates-in-character-class */
25
27
 
26
28
  // This must be called synchronously after the initial db call for backtraces to
27
29
  // work correctly
@@ -23,6 +23,7 @@ function SlowQuery(segment, type, query, trace) {
23
23
 
24
24
  function normalizedHash(value) {
25
25
  // We leverage the last 15 hex digits which will fit in a signed long
26
+ // eslint-disable-next-line sonarjs/hashing
26
27
  return parseInt(crypto.createHash('sha1').update(value).digest('hex').slice(-15), 16)
27
28
  }
28
29
 
@@ -6,6 +6,7 @@
6
6
  'use strict'
7
7
 
8
8
  // ( ` database` . ` table ` )
9
+ // eslint-disable-next-line sonarjs/slow-regex
9
10
  const CLEANER = /^\(?(?:([`'"]?)(.*?)\1\.)?([`'"]?)(.*?)\3\)?$/
10
11
 
11
12
  function StatementMatcher(operation, operationPattern) {
@@ -42,8 +43,8 @@ StatementMatcher.prototype.getParsedStatement = function getParsedStatement(sql)
42
43
  // be used for datastore attributes.
43
44
  return {
44
45
  operation: this.operation,
45
- database: database,
46
- collection: collection,
46
+ database,
47
+ collection,
47
48
  query: sql
48
49
  }
49
50
  }
package/lib/db/utils.js CHANGED
@@ -10,6 +10,10 @@ module.exports.extractDatabaseChangeFromUse = extractDatabaseChangeFromUse
10
10
  function extractDatabaseChangeFromUse(sql) {
11
11
  // The character ranges for this were pulled from
12
12
  // http://dev.mysql.com/doc/refman/5.7/en/identifiers.html
13
+
14
+ // Suppressing a warning on this regex because it is not obvious what this
15
+ // regex does, and we don't want to break anything.
16
+ // eslint-disable-next-line sonarjs/slow-regex, sonarjs/duplicates-in-character-class
13
17
  const match = /^\s*use[^\w`]+([\w$_\u0080-\uFFFF]+|`[^`]+`)[\s;]*$/i.exec(sql)
14
18
  return (match && match[1]) || null
15
19
  }
@@ -67,7 +67,7 @@ function clearSetting(name) {
67
67
  * the provided root.
68
68
  *
69
69
  * @param {string} root - Path to start listing packages from.
70
- * @param {Array} [packages=[]] - Array to append found packages to.
70
+ * @param {Array} [packages] - Array to append found packages to.
71
71
  */
72
72
  async function listPackages(root, packages = []) {
73
73
  _log('Listing packages in %s', root)
@@ -496,7 +496,7 @@ async function getJSON() {
496
496
  _log('Getting environment JSON')
497
497
  try {
498
498
  await refresh()
499
- } catch (err) {
499
+ } catch {
500
500
  // swallow error
501
501
  }
502
502
 
@@ -10,7 +10,6 @@ const errorsModule = require('./index')
10
10
  const logger = require('../logger').child({ component: 'error_tracer' })
11
11
  const urltils = require('../util/urltils')
12
12
  const Exception = require('../errors').Exception
13
- const Transaction = require('../transaction')
14
13
  const errorHelper = require('./helper')
15
14
  const createError = errorsModule.createError
16
15
  const createEvent = errorsModule.createEvent
@@ -312,6 +311,7 @@ class ErrorCollector {
312
311
  }
313
312
 
314
313
  if (this.config.error_collector.capture_events === true) {
314
+ // eslint-disable-next-line sonarjs/pseudo-random
315
315
  const priority = (transaction && transaction.priority) || Math.random()
316
316
  const event = createEvent(transaction, errorTrace, exception.timestamp, this.config)
317
317
  this.eventAggregator.add(event, priority)
@@ -360,7 +360,7 @@ class ErrorCollector {
360
360
  * @param {Transaction} transaction the transaction associated with the trace
361
361
  */
362
362
  _maybeRecordErrorMetrics(errorTrace, transaction) {
363
- const isExpectedError = true === errorTrace[4].intrinsics['error.expected']
363
+ const isExpectedError = errorTrace[4].intrinsics['error.expected'] === true
364
364
 
365
365
  if (isExpectedError) {
366
366
  this.metrics.getOrCreateMetric(NAMES.ERRORS.EXPECTED).incrementCallCount()
@@ -36,6 +36,7 @@ class ErrorEventAggregator extends EventAggregator {
36
36
 
37
37
  return [this.runId, metrics, eventData]
38
38
  }
39
+
39
40
  reconfigure(config) {
40
41
  super.reconfigure(config)
41
42
  if (!this.enabled) {
@@ -90,9 +90,9 @@ module.exports = {
90
90
  }
91
91
 
92
92
  return {
93
- name: name,
94
- message: message,
95
- type: type
93
+ name,
94
+ message,
95
+ type
96
96
  }
97
97
  },
98
98
 
@@ -119,7 +119,7 @@ module.exports = {
119
119
  return false
120
120
  }
121
121
 
122
- return -1 !== config.error_collector.ignore_classes.indexOf(errorInfo.type)
122
+ return config.error_collector.ignore_classes.indexOf(errorInfo.type) !== -1
123
123
  },
124
124
 
125
125
  shouldIgnoreErrorMessage: function shouldIgnoreErrorMessage(errorInfo, config) {
@@ -16,7 +16,6 @@ const {
16
16
  maybeAddDatabaseAttributes
17
17
  } = require('../util/attributes')
18
18
  const synthetics = require('../synthetics')
19
- const Transaction = require('../transaction')
20
19
  const ERROR_EXPECTED_PATH = 'error.expected'
21
20
 
22
21
  class Exception {
@@ -121,8 +120,8 @@ function isValidErrorGroupOutput(output) {
121
120
  function maybeAddAgentAttributes(attributes, exception) {
122
121
  if (exception.errorGroupCallback) {
123
122
  const callbackInput = {
124
- 'error': exception.error,
125
- 'customAttributes': Object.assign({}, attributes.userAttributes),
123
+ error: exception.error,
124
+ customAttributes: Object.assign({}, attributes.userAttributes),
126
125
  'request.uri': attributes.agentAttributes['request.uri'],
127
126
  'http.statusCode': attributes.agentAttributes['http.statusCode'],
128
127
  'http.method': attributes.agentAttributes['request.method'],
@@ -153,6 +152,7 @@ function maybeAddUserAttributes(userAttributes, exception, config) {
153
152
  for (const key in customAttributes) {
154
153
  if (props.hasOwn(customAttributes, key)) {
155
154
  const dest = config.attributeFilter.filterTransaction(DESTINATIONS.ERROR_EVENT, key)
155
+ // eslint-disable-next-line sonarjs/bitwise-operators
156
156
  if (dest & DESTINATIONS.ERROR_EVENT) {
157
157
  userAttributes[key] = customAttributes[key]
158
158
  }
@@ -208,7 +208,6 @@ function createEvent(transaction, error, timestamp, config) {
208
208
  return [intrinsicAttributes, userAttributes, agentAttributes]
209
209
  }
210
210
 
211
- // eslint-disable-next-line max-params
212
211
  function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, expected, timestamp, conf) {
213
212
  // the server expects seconds instead of milliseconds
214
213
  if (timestamp) {
@@ -216,10 +215,10 @@ function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, expected
216
215
  }
217
216
 
218
217
  const attributes = {
219
- 'type': 'TransactionError',
218
+ type: 'TransactionError',
220
219
  'error.class': errorClass,
221
220
  'error.message': conf.high_security ? '' : message,
222
- 'timestamp': timestamp,
221
+ timestamp,
223
222
  'error.expected': expected
224
223
  }
225
224
 
@@ -43,7 +43,7 @@ class GrpcConnection extends EventEmitter {
43
43
  *
44
44
  * @param {object} infiniteTracingConfig config item config.infinite_tracing
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] number of milliseconds to wait before reconnecting
47
47
  * for error states that require a reconnect delay.
48
48
  */
49
49
  constructor(infiniteTracingConfig, metrics, reconnectDelayMs = DEFAULT_RECONNECT_DELAY_MS) {
@@ -17,42 +17,42 @@ const COLLECTED_REQUEST_HEADERS = [
17
17
  ]
18
18
 
19
19
  const HEADER_ATTR_NAMES = {
20
- 'accept': 'accept',
20
+ accept: 'accept',
21
21
  'accept-charset': 'acceptCharset',
22
22
  'accept-encoding': 'acceptEncoding',
23
23
  'access-control-allow-headers': 'accessControlAllowHeaders',
24
24
  'access-control-allow-methods': 'accessControlAllowMethods',
25
25
  'access-control-allow-origin': 'accessControlAllowOrigin',
26
- 'age': 'age',
27
- 'allow': 'allow',
28
- 'authorization': 'authorization',
26
+ age: 'age',
27
+ allow: 'allow',
28
+ authorization: 'authorization',
29
29
  'cache-control': 'cacheControl',
30
- 'connection': 'connection',
31
- 'cookie': 'cookie',
30
+ connection: 'connection',
31
+ cookie: 'cookie',
32
32
  'content-encoding': 'contentEncoding',
33
33
  'content-length': 'contentLength',
34
34
  'content-type': 'contentType',
35
- 'date': 'date',
36
- 'etag': 'eTag',
37
- 'expect': 'expect',
38
- 'expires': 'expires',
39
- 'forwarded': 'forwarded',
40
- 'host': 'host',
35
+ date: 'date',
36
+ etag: 'eTag',
37
+ expect: 'expect',
38
+ expires: 'expires',
39
+ forwarded: 'forwarded',
40
+ host: 'host',
41
41
  'if-match': 'ifMatch',
42
42
  'if-modified-since': 'ifModifiedSince',
43
43
  'last-modified': 'lastModified',
44
- 'location': 'location',
45
- 'newrelic': 'newrelic',
46
- 'origin': 'origin',
44
+ location: 'location',
45
+ newrelic: 'newrelic',
46
+ origin: 'origin',
47
47
  'proxy-authorization': 'proxyAuthorization',
48
- 'referer': 'referer',
49
- 'refresh': 'refresh',
50
- 'server': 'server',
48
+ referer: 'referer',
49
+ refresh: 'refresh',
50
+ server: 'server',
51
51
  'set-cookie': 'setCookie',
52
52
  'transfer-encoding': 'transferEncoding',
53
53
  'user-agent': 'userAgent',
54
- 'upgrade': 'upgrade',
55
- 'vary': 'vary',
54
+ upgrade: 'upgrade',
55
+ vary: 'vary',
56
56
  'x-correlation-id': 'xCorrelationId',
57
57
  'x-csrf-token': 'xCsrfToken',
58
58
  'x-forwarded-for': 'xForwardedFor',
@@ -95,6 +95,7 @@ function _headerToCamelCase(header) {
95
95
  const newHeader = header.charAt(0).toLowerCase() + header.slice(1)
96
96
 
97
97
  // Converts headers in the form 'header-name' to be in the form 'headerName'
98
+ // eslint-disable-next-line sonarjs/slow-regex
98
99
  return newHeader.replace(/[\W_]+(\w)/g, function capitalize(m, $1) {
99
100
  return $1.toUpperCase()
100
101
  })
@@ -108,7 +108,7 @@ function parsePath(pathString, method) {
108
108
  const path = pathString.split('/')
109
109
  if (method === 'PUT' && path.length === 2) {
110
110
  collection = path?.[1] || defaultCollection
111
- operation = `index.create`
111
+ operation = 'index.create'
112
112
  return { collection, operation }
113
113
  }
114
114
  path.forEach((segment, idx) => {
@@ -116,7 +116,7 @@ function parsePath(pathString, method) {
116
116
  let opname
117
117
  if (segment === '_search') {
118
118
  collection = path?.[prev] || defaultCollection
119
- operation = `search`
119
+ operation = 'search'
120
120
  } else if (segment[0] === '_') {
121
121
  opname = segment.substring(1)
122
122
  collection = path?.[prev] || defaultCollection