newrelic 8.3.0 → 8.5.2

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 (134) hide show
  1. package/NEWS.md +76 -0
  2. package/README.md +7 -6
  3. package/THIRD_PARTY_NOTICES.md +95 -35
  4. package/api.js +74 -68
  5. package/bin/test-naming-rules.js +22 -22
  6. package/lib/agent.js +4 -4
  7. package/lib/attributes.js +2 -2
  8. package/lib/collector/api.js +12 -12
  9. package/lib/collector/facts.js +1 -1
  10. package/lib/collector/http-agents.js +12 -11
  11. package/lib/collector/key-parser.js +1 -1
  12. package/lib/collector/remote-method.js +27 -26
  13. package/lib/config/attribute-filter.js +23 -23
  14. package/lib/config/default.js +12 -10
  15. package/lib/config/hsm.js +1 -1
  16. package/lib/config/index.js +82 -66
  17. package/lib/config/lasp.js +3 -3
  18. package/lib/config/merge-server-config.js +1 -1
  19. package/lib/db/parse-sql.js +8 -8
  20. package/lib/db/parsed-statement.js +9 -8
  21. package/lib/db/query-parsers/sql.js +7 -7
  22. package/lib/db/query-sample.js +9 -9
  23. package/lib/db/query-trace-aggregator.js +4 -4
  24. package/lib/db/statement-matcher.js +5 -5
  25. package/lib/db/utils.js +1 -1
  26. package/lib/environment.js +43 -43
  27. package/lib/errors/error-collector.js +2 -2
  28. package/lib/errors/error-trace-aggregator.js +1 -1
  29. package/lib/errors/helper.js +3 -3
  30. package/lib/errors/index.js +17 -17
  31. package/lib/feature_flags.js +7 -5
  32. package/lib/header-attributes.js +6 -6
  33. package/lib/header-processing.js +1 -1
  34. package/lib/instrumentation/amqplib.js +26 -26
  35. package/lib/instrumentation/bluebird.js +3 -3
  36. package/lib/instrumentation/cassandra-driver.js +7 -3
  37. package/lib/instrumentation/connect.js +4 -4
  38. package/lib/instrumentation/core/async_hooks.js +6 -6
  39. package/lib/instrumentation/core/domain.js +2 -2
  40. package/lib/instrumentation/core/globals.js +1 -1
  41. package/lib/instrumentation/core/http-outbound.js +15 -84
  42. package/lib/instrumentation/core/http.js +34 -67
  43. package/lib/instrumentation/core/inspector.js +2 -2
  44. package/lib/instrumentation/core/timers.js +7 -7
  45. package/lib/instrumentation/core/zlib.js +2 -2
  46. package/lib/instrumentation/director.js +4 -4
  47. package/lib/instrumentation/express.js +8 -8
  48. package/lib/instrumentation/fastify/spec-builders.js +57 -47
  49. package/lib/instrumentation/fastify.js +85 -24
  50. package/lib/instrumentation/generic-pool.js +1 -1
  51. package/lib/instrumentation/hapi/hapi-17.js +11 -11
  52. package/lib/instrumentation/hapi/shared.js +1 -1
  53. package/lib/instrumentation/hapi.js +22 -22
  54. package/lib/instrumentation/ioredis.js +7 -7
  55. package/lib/instrumentation/memcached.js +7 -7
  56. package/lib/instrumentation/mongodb/common.js +16 -5
  57. package/lib/instrumentation/mysql.js +19 -19
  58. package/lib/instrumentation/oracle.js +15 -15
  59. package/lib/instrumentation/pg.js +4 -4
  60. package/lib/instrumentation/promise.js +46 -46
  61. package/lib/instrumentation/q.js +2 -2
  62. package/lib/instrumentation/redis.js +11 -11
  63. package/lib/instrumentation/restify.js +1 -1
  64. package/lib/instrumentation/undici.js +242 -0
  65. package/lib/instrumentation/vision.js +4 -4
  66. package/lib/instrumentation/when.js +3 -3
  67. package/lib/instrumentations.js +2 -1
  68. package/lib/logger.js +5 -5
  69. package/lib/metrics/index.js +15 -15
  70. package/lib/metrics/mapper.js +7 -7
  71. package/lib/metrics/normalizer/rule.js +9 -9
  72. package/lib/metrics/normalizer/tx_segment.js +17 -17
  73. package/lib/metrics/normalizer.js +22 -22
  74. package/lib/metrics/recorders/custom.js +5 -5
  75. package/lib/metrics/recorders/generic.js +3 -3
  76. package/lib/metrics/recorders/http.js +7 -7
  77. package/lib/metrics/recorders/http_external.js +7 -7
  78. package/lib/metrics/recorders/message-transaction.js +5 -6
  79. package/lib/metrics/recorders/other.js +5 -5
  80. package/lib/parse-proc-cpuinfo.js +25 -19
  81. package/lib/parse-proc-meminfo.js +8 -2
  82. package/lib/prioritized-attributes.js +2 -2
  83. package/lib/priority-queue.js +10 -10
  84. package/lib/reservoir.js +3 -3
  85. package/lib/sampler.js +26 -26
  86. package/lib/serverless/aws-lambda.js +8 -2
  87. package/lib/shim/datastore-shim.js +35 -32
  88. package/lib/shim/index.js +2 -2
  89. package/lib/shim/message-shim.js +47 -47
  90. package/lib/shim/promise-shim.js +1 -1
  91. package/lib/shim/shim.js +61 -61
  92. package/lib/shim/specs/index.js +3 -3
  93. package/lib/shim/transaction-shim.js +44 -192
  94. package/lib/shim/webframework-shim.js +52 -52
  95. package/lib/spans/span-event.js +1 -1
  96. package/lib/spans/streaming-span-attributes.js +1 -1
  97. package/lib/stats/apdex.js +2 -2
  98. package/lib/stats/index.js +2 -2
  99. package/lib/system-info.js +23 -23
  100. package/lib/timer.js +5 -5
  101. package/lib/transaction/dt-payload.js +1 -1
  102. package/lib/transaction/index.js +40 -40
  103. package/lib/transaction/name-state.js +14 -14
  104. package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
  105. package/lib/transaction/trace/index.js +14 -14
  106. package/lib/transaction/trace/segment.js +18 -18
  107. package/lib/transaction/tracecontext.js +1 -1
  108. package/lib/transaction/tracer/index.js +53 -49
  109. package/lib/uninstrumented.js +7 -7
  110. package/lib/util/arity.js +2 -2
  111. package/lib/util/byte-limit.js +4 -4
  112. package/lib/util/cat.js +269 -24
  113. package/lib/util/codec.js +2 -2
  114. package/lib/util/copy.js +2 -2
  115. package/lib/util/deep-equal.js +10 -10
  116. package/lib/util/flatten.js +4 -4
  117. package/lib/util/hashes.js +14 -14
  118. package/lib/util/label-parser.js +17 -17
  119. package/lib/util/logger.js +24 -24
  120. package/lib/util/process-version.js +2 -2
  121. package/lib/util/properties.js +4 -4
  122. package/lib/util/sql/obfuscate.js +15 -15
  123. package/lib/util/stream-sink.js +3 -3
  124. package/lib/util/unwrapped-core.js +2 -2
  125. package/lib/util/urltils.js +16 -16
  126. package/lib/utilization/aws-info.js +7 -7
  127. package/lib/utilization/azure-info.js +6 -6
  128. package/lib/utilization/common.js +13 -13
  129. package/lib/utilization/docker-info.js +11 -11
  130. package/lib/utilization/gcp-info.js +4 -4
  131. package/lib/utilization/index.js +5 -5
  132. package/lib/utilization/pcf-info.js +9 -9
  133. package/package.json +13 -6
  134. package/stub_api.js +8 -8
@@ -6,10 +6,14 @@
6
6
  'use strict'
7
7
 
8
8
  module.exports = function initialize(agent, cassandra, moduleName, shim) {
9
- var proto = cassandra.Client.prototype
9
+ const proto = cassandra.Client.prototype
10
10
  shim.setDatastore(shim.CASSANDRA)
11
11
  shim.recordOperation(proto, ['connect', 'shutdown'], { callback: shim.LAST })
12
- shim.recordQuery(proto, '_innerExecute', { query: shim.FIRST, callback: shim.LAST })
12
+ if (proto._innerExecute) {
13
+ shim.recordQuery(proto, '_innerExecute', { query: shim.FIRST, callback: shim.LAST })
14
+ } else {
15
+ shim.recordQuery(proto, '_execute', { query: shim.FIRST, callback: shim.LAST })
16
+ }
13
17
  shim.recordBatchQuery(proto, 'batch', {
14
18
  query: findBatchQueryArg,
15
19
  callback: shim.LAST
@@ -23,6 +27,6 @@ module.exports = function initialize(agent, cassandra, moduleName, shim) {
23
27
  * @return {string} The query for this batch request.
24
28
  */
25
29
  function findBatchQueryArg(shim, batch, fnName, args) {
26
- var sql = (args[0] && args[0][0]) || ''
30
+ const sql = (args[0] && args[0][0]) || ''
27
31
  return sql.query || sql
28
32
  }
@@ -17,7 +17,7 @@ module.exports = function initialize(agent, connect, moduleName, shim) {
17
17
  return route
18
18
  })
19
19
 
20
- var proto =
20
+ const proto =
21
21
  (connect && connect.HTTPServer && connect.HTTPServer.prototype) || // v1
22
22
  (connect && connect.proto) // v2
23
23
 
@@ -31,7 +31,7 @@ module.exports = function initialize(agent, connect, moduleName, shim) {
31
31
  }
32
32
 
33
33
  function wrapMiddleware(shim, middleware, name, route) {
34
- var spec = {
34
+ const spec = {
35
35
  matchArity: true,
36
36
  route: route,
37
37
  type: shim.MIDDLEWARE,
@@ -56,9 +56,9 @@ function wrapMiddleware(shim, middleware, name, route) {
56
56
 
57
57
  function wrapConnectExport(shim, connect, v3) {
58
58
  shim.wrapExport(connect, function wrapExport(shim, fn) {
59
- var wrapper = shim.wrap(fn, function wrapConnect(shim, _fn) {
59
+ const wrapper = shim.wrap(fn, function wrapConnect(shim, _fn) {
60
60
  return function wrappedConnect() {
61
- var res = _fn.apply(this, arguments)
61
+ const res = _fn.apply(this, arguments)
62
62
  if (v3) {
63
63
  shim.wrapMiddlewareMounter(res, 'use', {
64
64
  route: shim.FIRST,
@@ -5,16 +5,16 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var logger = require('../../logger').child({ component: 'async_hooks' })
9
- var promInit = require('../promise')
8
+ const logger = require('../../logger').child({ component: 'async_hooks' })
9
+ const promInit = require('../promise')
10
10
 
11
11
  module.exports = initialize
12
12
 
13
13
  /**
14
14
  * The spec for the native `Promise` class.
15
15
  */
16
- var STATIC_PROMISE_METHODS = ['accept', 'all', 'defer', 'race', 'reject', 'resolve']
17
- var NATIVE_PROMISE_SPEC = {
16
+ const STATIC_PROMISE_METHODS = ['accept', 'all', 'defer', 'race', 'reject', 'resolve']
17
+ const NATIVE_PROMISE_SPEC = {
18
18
  name: 'global',
19
19
  constructor: 'Promise',
20
20
  executor: true,
@@ -30,7 +30,7 @@ var NATIVE_PROMISE_SPEC = {
30
30
  }
31
31
 
32
32
  function initialize(agent, shim) {
33
- var enableHooks = agent.config.checkAsyncHookStatus()
33
+ const enableHooks = agent.config.checkAsyncHookStatus()
34
34
  if (enableHooks && tryAsyncHooks(agent, shim)) {
35
35
  logger.debug('Using async_hooks.')
36
36
  } else {
@@ -134,7 +134,7 @@ function getPromiseResolveStyleHooks(segmentMap, agent, shim) {
134
134
  return
135
135
  }
136
136
 
137
- let parentSegment = segmentMap.get(triggerId)
137
+ const parentSegment = segmentMap.get(triggerId)
138
138
 
139
139
  if (parentSegment && !parentSegment.transaction.isActive()) {
140
140
  // Stop propagating if the transaction was ended.
@@ -8,12 +8,12 @@
8
8
  module.exports = initialize
9
9
 
10
10
  function initialize(agent, domain, name, shim) {
11
- var proto = domain.Domain.prototype
11
+ const proto = domain.Domain.prototype
12
12
  shim.wrap(proto, 'emit', wrapEmit)
13
13
 
14
14
  function wrapEmit(shim, original) {
15
15
  return function wrappedEmit(ev) {
16
- var shouldRestoreContext =
16
+ const shouldRestoreContext =
17
17
  ev === 'error' && shim.getActiveSegment() === null && shim.getSegment(this)
18
18
 
19
19
  if (!shouldRestoreContext) {
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var asyncHooks = require('./async_hooks')
8
+ const asyncHooks = require('./async_hooks')
9
9
 
10
10
  module.exports = initialize
11
11
 
@@ -5,13 +5,13 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var recordExternal = require('../../metrics/recorders/http_external')
9
- var urltils = require('../../util/urltils')
10
- var hashes = require('../../util/hashes')
11
- var logger = require('../../logger').child({ component: 'outbound' })
12
- var shimmer = require('../../shimmer')
13
- var url = require('url')
14
- var copy = require('../../util/copy')
8
+ const recordExternal = require('../../metrics/recorders/http_external')
9
+ const cat = require('../../util/cat')
10
+ const urltils = require('../../util/urltils')
11
+ const logger = require('../../logger').child({ component: 'outbound' })
12
+ const shimmer = require('../../shimmer')
13
+ const url = require('url')
14
+ const copy = require('../../util/copy')
15
15
 
16
16
  const NAMES = require('../../metrics/names')
17
17
  const SHIM_SYMBOLS = require('../../shim/constants').SYMBOLS
@@ -20,8 +20,6 @@ const DEFAULT_HOST = 'localhost'
20
20
  const DEFAULT_PORT = 80
21
21
  const DEFAULT_SSL_PORT = 443
22
22
 
23
- const NEWRELIC_ID_HEADER = 'x-newrelic-id'
24
- const NEWRELIC_TRANSACTION_HEADER = 'x-newrelic-transaction'
25
23
  const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
26
24
 
27
25
  /**
@@ -96,13 +94,9 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
96
94
  transaction.insertDistributedTraceHeaders(outboundHeaders)
97
95
  }
98
96
  } else if (agent.config.cross_application_tracer.enabled) {
99
- if (agent.config.encoding_key) {
100
- _addCATHeaders(agent, transaction, outboundHeaders)
101
- } else {
102
- logger.trace('No encoding key found, not adding CAT headers')
103
- }
97
+ cat.addCatHeaders(agent.config, transaction, outboundHeaders)
104
98
  } else {
105
- logger.trace('CAT disabled, not adding headers!')
99
+ logger.trace('Both DT and CAT are disabled, not adding headers!')
106
100
  }
107
101
 
108
102
  if (Array.isArray(opts.headers)) {
@@ -129,7 +123,7 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
129
123
  if (parsed.parameters) {
130
124
  // Scrub and parse returns on object with a null prototype.
131
125
  // eslint-disable-next-line guard-for-in
132
- for (let key in parsed.parameters) {
126
+ for (const key in parsed.parameters) {
133
127
  segment.addSpanAttribute(`request.parameters.${key}`, parsed.parameters[key])
134
128
  }
135
129
  }
@@ -196,12 +190,14 @@ function handleResponse(segment, hostname, req, res) {
196
190
  // If CAT is enabled, grab those headers!
197
191
  const agent = segment.transaction.agent
198
192
  if (agent.config.cross_application_tracer.enabled && !agent.config.distributed_tracing.enabled) {
199
- pullCatHeaders(agent.config, segment, hostname, res.headers['x-newrelic-app-data'])
193
+ const { appData } = cat.extractCatHeaders(res.headers)
194
+ const decodedAppData = cat.parseAppData(agent.config, appData)
195
+ cat.assignCatToSegment(decodedAppData, segment, hostname)
200
196
  }
201
197
 
202
198
  // Again a custom emit wrapper because we want to watch for the `end` event.
203
199
  shimmer.wrapMethod(res, 'response', 'emit', function wrapEmit(emit) {
204
- var boundEmit = agent.tracer.bindFunction(emit, segment)
200
+ const boundEmit = agent.tracer.bindFunction(emit, segment)
205
201
  return function wrappedResponseEmit(evnt) {
206
202
  if (evnt === 'end') {
207
203
  segment.end()
@@ -212,77 +208,12 @@ function handleResponse(segment, hostname, req, res) {
212
208
  _makeNonEnumerable(res, 'emit')
213
209
  }
214
210
 
215
- function pullCatHeaders(config, segment, host, obfAppData) {
216
- if (!config.encoding_key) {
217
- logger.trace('config.encoding_key is not set - not parsing response CAT headers')
218
- return
219
- }
220
-
221
- if (!config.trusted_account_ids) {
222
- logger.trace('config.trusted_account_ids is not set - not parsing response CAT headers')
223
- return
224
- }
225
-
226
- // is our downstream request CAT-aware?
227
- if (!obfAppData) {
228
- logger.trace('Got no CAT app data in response header x-newrelic-app-data')
229
- } else {
230
- var appData = null
231
- try {
232
- appData = JSON.parse(hashes.deobfuscateNameUsingKey(obfAppData, config.encoding_key))
233
- } catch (e) {
234
- logger.warn('Got an unparsable CAT header x-newrelic-app-data: %s', obfAppData)
235
- return
236
- }
237
- // Make sure it is a trusted account
238
- if (appData.length && typeof appData[0] === 'string') {
239
- var accountId = appData[0].split('#')[0]
240
- accountId = parseInt(accountId, 10)
241
- if (config.trusted_account_ids.indexOf(accountId) === -1) {
242
- logger.trace('Response from untrusted CAT header account id: %s', accountId)
243
- } else {
244
- segment.catId = appData[0]
245
- segment.catTransaction = appData[1]
246
- segment.name =
247
- NAMES.EXTERNAL.TRANSACTION + host + '/' + segment.catId + '/' + segment.catTransaction
248
- if (appData.length >= 6) {
249
- segment.addAttribute('transaction_guid', appData[5])
250
- }
251
- logger.trace('Got inbound response CAT headers in transaction %s', segment.transaction.id)
252
- }
253
- }
254
- }
255
- }
256
-
257
211
  function _makeNonEnumerable(obj, prop) {
258
212
  try {
259
- var desc = Object.getOwnPropertyDescriptor(obj, prop)
213
+ const desc = Object.getOwnPropertyDescriptor(obj, prop)
260
214
  desc.enumerable = false
261
215
  Object.defineProperty(obj, prop, desc)
262
216
  } catch (e) {
263
217
  logger.debug(e, 'Failed to make %s non enumerable.', prop)
264
218
  }
265
219
  }
266
-
267
- function _addCATHeaders(agent, tx, outboundHeaders) {
268
- if (agent.config.obfuscatedId) {
269
- outboundHeaders[NEWRELIC_ID_HEADER] = agent.config.obfuscatedId
270
- }
271
-
272
- var pathHash = hashes.calculatePathHash(
273
- agent.config.applications()[0],
274
- tx.getFullName() || '',
275
- tx.referringPathHash
276
- )
277
- tx.pushPathHash(pathHash)
278
-
279
- try {
280
- let txData = JSON.stringify([tx.id, false, tx.tripId || tx.id, pathHash])
281
- txData = hashes.obfuscateNameUsingKey(txData, agent.config.encoding_key)
282
- outboundHeaders[NEWRELIC_TRANSACTION_HEADER] = txData
283
-
284
- logger.trace('Added outbound request CAT headers in transaction %s', tx.id)
285
- } catch (err) {
286
- logger.trace(err, 'Failed to create CAT payload')
287
- }
288
- }
@@ -26,9 +26,6 @@ const DESTS = require('../../config/attribute-filter').DESTINATIONS
26
26
  *
27
27
  */
28
28
  const NR_CONNECTION_PROP = '__NR__connection'
29
- const NEWRELIC_ID_HEADER = 'x-newrelic-id'
30
- const NEWRELIC_APP_DATA_HEADER = 'x-newrelic-app-data'
31
- const NEWRELIC_TRANSACTION_HEADER = 'x-newrelic-transaction'
32
29
  const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
33
30
  const TRANSACTION_INFO_KEY = '__NR_transactionInfo'
34
31
 
@@ -47,7 +44,7 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
47
44
  let serverPort = null
48
45
 
49
46
  return tracer.transactionProxy(function wrappedHandler(evnt, request, response) {
50
- var transaction = tracer.getTransaction()
47
+ const transaction = tracer.getTransaction()
51
48
  if (!transaction) {
52
49
  return emit.apply(this, arguments)
53
50
  }
@@ -108,7 +105,7 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
108
105
 
109
106
  // store the port on which this transaction runs
110
107
  if (this.address instanceof Function) {
111
- var address = this.address()
108
+ const address = this.address()
112
109
  if (address) {
113
110
  serverPort = address.port
114
111
  }
@@ -142,15 +139,13 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
142
139
  // Node http headers are automatically lowercase
143
140
  transaction.acceptDistributedTraceHeaders(transport, request.headers)
144
141
  } else if (agent.config.cross_application_tracer.enabled) {
145
- const incomingCatId = request.headers[NEWRELIC_ID_HEADER]
146
- const obfTransaction = request.headers[NEWRELIC_TRANSACTION_HEADER]
147
-
148
- if (agent.config.encoding_key) {
149
- cat.handleCatHeaders(incomingCatId, obfTransaction, agent.config.encoding_key, transaction)
150
- if (transaction.incomingCatId) {
151
- logger.trace('Got inbound request CAT headers in transaction %s', transaction.id)
152
- }
153
- }
142
+ const { id, transactionId } = cat.extractCatHeaders(request.headers)
143
+ const { externalId, externalTransaction } = cat.parseCatData(
144
+ id,
145
+ transactionId,
146
+ agent.config.encoding_key
147
+ )
148
+ cat.assignCatToTransaction(externalId, externalTransaction, transaction)
154
149
  }
155
150
 
156
151
  function instrumentedFinish() {
@@ -164,7 +159,7 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
164
159
 
165
160
  if (response) {
166
161
  if (response.statusCode != null) {
167
- var responseCode = String(response.statusCode)
162
+ const responseCode = String(response.statusCode)
168
163
 
169
164
  if (/^\d+$/.test(responseCode)) {
170
165
  transaction.trace.attributes.addAttribute(
@@ -187,7 +182,7 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
187
182
  segment.addSpanAttribute('http.statusText', response.statusMessage)
188
183
  }
189
184
 
190
- var headers = response.getHeaders()
185
+ const headers = response.getHeaders()
191
186
  if (headers) {
192
187
  headerAttributes.collectResponseHeaders(headers, transaction)
193
188
  }
@@ -209,9 +204,9 @@ function storeTxInfo(transaction, request, response) {
209
204
  logger.debug('Missing request or response object! Not storing transaction info.')
210
205
  return
211
206
  }
212
- var hideInternal = transaction.agent.config.transaction_tracer.hide_internals
207
+ const hideInternal = transaction.agent.config.transaction_tracer.hide_internals
213
208
 
214
- var txInfo = {
209
+ const txInfo = {
215
210
  transaction: transaction,
216
211
  segmentStack: [],
217
212
  errorHandled: false,
@@ -239,7 +234,7 @@ function initializeRequest(transaction, request) {
239
234
  }
240
235
 
241
236
  function wrapResponseEnd(agent, proto) {
242
- var tracer = agent.tracer
237
+ const tracer = agent.tracer
243
238
 
244
239
  // On end, we must freeze the current name state to maintain the route that
245
240
  // responded and also end the current segment (otherwise it may become truncated).
@@ -250,7 +245,7 @@ function wrapResponseEnd(agent, proto) {
250
245
  }
251
246
 
252
247
  return function wrappedResEnd() {
253
- var txInfo = this && this[TRANSACTION_INFO_KEY]
248
+ const txInfo = this && this[TRANSACTION_INFO_KEY]
254
249
  if (!txInfo) {
255
250
  return end.apply(this, arguments)
256
251
  }
@@ -268,10 +263,10 @@ function wrapResponseEnd(agent, proto) {
268
263
  }
269
264
 
270
265
  // End all the segments leading up to and including this one.
271
- for (var i = txInfo.segmentStack.length - 1; i >= 0; --i) {
266
+ for (let i = txInfo.segmentStack.length - 1; i >= 0; --i) {
272
267
  txInfo.segmentStack[i].end()
273
268
  }
274
- var segment = tracer.getSegment()
269
+ const segment = tracer.getSegment()
275
270
  if (segment) {
276
271
  segment.end()
277
272
  }
@@ -288,7 +283,7 @@ function wrapResponseEnd(agent, proto) {
288
283
  // the shimmer stuff if you'd like to verify.
289
284
  function wrapWriteHead(agent, writeHead) {
290
285
  return function wrappedWriteHead() {
291
- var transaction = agent.tracer.getTransaction()
286
+ const transaction = agent.tracer.getTransaction()
292
287
  if (!transaction) {
293
288
  logger.trace('No transaction - not adding response CAT headers')
294
289
  return writeHead.apply(this, arguments)
@@ -307,13 +302,7 @@ function wrapWriteHead(agent, writeHead) {
307
302
  return writeHead.apply(this, arguments)
308
303
  }
309
304
 
310
- var accountId = transaction.incomingCatId.split('#')[0]
311
- accountId = parseInt(accountId, 10)
312
- if (agent.config.trusted_account_ids.indexOf(accountId) === -1) {
313
- logger.trace(
314
- 'Request from untrusted account id: %s - not adding response CAT headers',
315
- accountId
316
- )
305
+ if (!cat.isTrustedAccountId(transaction.incomingCatId, agent.config.trusted_account_ids)) {
317
306
  return writeHead.apply(this, arguments)
318
307
  }
319
308
 
@@ -332,8 +321,8 @@ function wrapWriteHead(agent, writeHead) {
332
321
 
333
322
  // -1 means no content length header was sent. We should only send this
334
323
  // value in the appData if the header is set.
335
- var contentLength = -1
336
- var newHeaders = arguments[arguments.length - 1]
324
+ let contentLength = -1
325
+ const newHeaders = arguments[arguments.length - 1]
337
326
 
338
327
  if (typeof newHeaders === 'object') {
339
328
  contentLength = headerProcessing.getContentLengthFromHeaders(newHeaders)
@@ -347,33 +336,11 @@ function wrapWriteHead(agent, writeHead) {
347
336
  // actual duration.
348
337
  transaction.catResponseTime = transaction.timer.getDurationInMillis()
349
338
 
350
- var appData = null
351
- var txName = transaction.getFullName() || ''
352
-
353
- try {
354
- appData = JSON.stringify([
355
- agent.config.cross_process_id, // cross_process_id
356
- txName, // transaction name
357
- transaction.queueTime / 1000, // queue time (s)
358
- transaction.catResponseTime / 1000, // response time (s)
359
- contentLength, // content length (if content-length header is also being sent)
360
- transaction.id, // TransactionGuid
361
- false // force a transaction trace to be recorded
362
- ])
363
- } catch (err) {
364
- logger.trace(
365
- err,
366
- 'Failed to serialize transaction: %s - not adding CAT response headers',
367
- txName
368
- )
369
- return writeHead.apply(this, arguments)
339
+ const { key, data } = cat.encodeAppData(agent.config, transaction, contentLength)
340
+ if (key && data) {
341
+ this.setHeader(key, data)
342
+ logger.trace('Added outbound response CAT headers in transaction %s', transaction.id)
370
343
  }
371
-
372
- var encKey = agent.config.encoding_key
373
- var obfAppData = hashes.obfuscateNameUsingKey(appData, encKey)
374
- this.setHeader(NEWRELIC_APP_DATA_HEADER, obfAppData)
375
- logger.trace('Added outbound response CAT headers in transaction %s', transaction.id)
376
-
377
344
  return writeHead.apply(this, arguments)
378
345
  }
379
346
  }
@@ -423,7 +390,7 @@ function wrapRequest(agent, request) {
423
390
  options = Object.assign(input || {}, options)
424
391
  }
425
392
 
426
- let reqArgs = [options, cb]
393
+ const reqArgs = [options, cb]
427
394
 
428
395
  // Don't pollute metrics and calls with NR connections
429
396
  const internalOnly = options && options[NR_CONNECTION_PROP]
@@ -480,7 +447,7 @@ module.exports = function initialize(agent, http, moduleName) {
480
447
  'http.Server.prototype',
481
448
  'emit',
482
449
  function wrapEmit(emit) {
483
- var txStarter = wrapEmitWithTransaction(agent, emit, IS_HTTPS)
450
+ const txStarter = wrapEmitWithTransaction(agent, emit, IS_HTTPS)
484
451
  return function wrappedEmit(evnt) {
485
452
  if (evnt === 'request') {
486
453
  return txStarter.apply(this, arguments)
@@ -502,7 +469,7 @@ module.exports = function initialize(agent, http, moduleName) {
502
469
  )
503
470
  }
504
471
 
505
- var agentProto = http && http.Agent && http.Agent.prototype
472
+ const agentProto = http && http.Agent && http.Agent.prototype
506
473
 
507
474
  shimmer.wrapMethod(http, 'http', 'request', wrapRequest.bind(null, agent))
508
475
 
@@ -518,14 +485,14 @@ module.exports = function initialize(agent, http, moduleName) {
518
485
  return original.apply(this, arguments)
519
486
  }
520
487
 
521
- var segment = agent.tracer.createSegment('http.Agent#createConnection')
488
+ const segment = agent.tracer.createSegment('http.Agent#createConnection')
522
489
 
523
- var args = agent.tracer.slice(arguments)
490
+ const args = agent.tracer.slice(arguments)
524
491
  if (typeof args[1] === 'function') {
525
492
  args[1] = agent.tracer.bindFunction(args[1], segment, true)
526
493
  }
527
494
 
528
- var sock = agent.tracer.bindFunction(original, segment, true).apply(this, args)
495
+ const sock = agent.tracer.bindFunction(original, segment, true).apply(this, args)
529
496
  return sock
530
497
  }
531
498
  }
@@ -543,7 +510,7 @@ module.exports = function initialize(agent, http, moduleName) {
543
510
  * @param {Transaction} transaction - Where the synthetics data is attached to.
544
511
  */
545
512
  function handleSyntheticsHeader(header, encKey, trustedIds, transaction) {
546
- var synthData = parseSyntheticsHeader(header, encKey, trustedIds)
513
+ const synthData = parseSyntheticsHeader(header, encKey, trustedIds)
547
514
  if (!synthData) {
548
515
  return
549
516
  }
@@ -565,14 +532,14 @@ function handleSyntheticsHeader(header, encKey, trustedIds, transaction) {
565
532
  function parseSyntheticsHeader(header, encKey, trustedIds) {
566
533
  // Eagerly declare this object because we know what it should look like and
567
534
  // can use that for header verification.
568
- var parsedData = {
535
+ const parsedData = {
569
536
  version: null,
570
537
  accountId: null,
571
538
  resourceId: null,
572
539
  jobId: null,
573
540
  monitorId: null
574
541
  }
575
- var synthData = null
542
+ let synthData = null
576
543
  try {
577
544
  synthData = JSON.parse(hashes.deobfuscateNameUsingKey(header, encKey))
578
545
  } catch (e) {
@@ -8,14 +8,14 @@
8
8
  module.exports = initialize
9
9
 
10
10
  function initialize(agent, inspector, name, shim) {
11
- var sessionProto = inspector && inspector.Session && inspector.Session.prototype
11
+ const sessionProto = inspector && inspector.Session && inspector.Session.prototype
12
12
  if (!sessionProto) {
13
13
  return false
14
14
  }
15
15
 
16
16
  shim.wrap(sessionProto, 'post', function wrapPost(shim, fn) {
17
17
  return function wrappedPost() {
18
- var args = shim.argsToArray.apply(shim, arguments)
18
+ const args = shim.argsToArray.apply(shim, arguments)
19
19
  shim.bindCallbackSegment(args, shim.LAST)
20
20
  return fn.apply(this, args)
21
21
  }
@@ -18,9 +18,9 @@ function initialize(agent, timers, moduleName, shim) {
18
18
  }
19
19
 
20
20
  // Manual copy because helper methods add significant overhead in some usages
21
- var len = arguments.length
22
- var args = new Array(len)
23
- for (var i = 0; i < len; ++i) {
21
+ const len = arguments.length
22
+ const args = new Array(len)
23
+ for (let i = 0; i < len; ++i) {
24
24
  args[i] = arguments[i]
25
25
  }
26
26
 
@@ -70,7 +70,7 @@ function initialize(agent, timers, moduleName, shim) {
70
70
  return function wrappedClearTimeout(timer) {
71
71
  if (timer && timer._onTimeout) {
72
72
  const segment = timer._onTimeout.__NR_segment
73
- if (segment) {
73
+ if (segment && !segment.opaque) {
74
74
  segment.ignore = true
75
75
  }
76
76
  }
@@ -85,9 +85,9 @@ function initialize(agent, timers, moduleName, shim) {
85
85
  }
86
86
 
87
87
  function makeWrappedPromisifyCompatible(shim, timers) {
88
- const originalSetTimout = shim.getOriginal(timers.setTimeout)
89
- Object.getOwnPropertySymbols(originalSetTimout).forEach((symbol) => {
90
- timers.setTimeout[symbol] = originalSetTimout[symbol]
88
+ const originalSetTimeout = shim.getOriginal(timers.setTimeout)
89
+ Object.getOwnPropertySymbols(originalSetTimeout).forEach((symbol) => {
90
+ timers.setTimeout[symbol] = originalSetTimeout[symbol]
91
91
  })
92
92
 
93
93
  const originalSetInterval = shim.getOriginal(timers.setInterval)
@@ -9,13 +9,13 @@ const recorder = require('../../metrics/recorders/generic')
9
9
 
10
10
  module.exports = initialize
11
11
 
12
- var methods = ['deflate', 'deflateRaw', 'gzip', 'gunzip', 'inflate', 'inflateRaw', 'unzip']
12
+ const methods = ['deflate', 'deflateRaw', 'gzip', 'gunzip', 'inflate', 'inflateRaw', 'unzip']
13
13
 
14
14
  function initialize(agent, zlib, moduleName, shim) {
15
15
  shim.record(zlib, methods, recordZLib)
16
16
 
17
17
  if (zlib.Deflate && zlib.Deflate.prototype) {
18
- var proto = Object.getPrototypeOf(zlib.Deflate.prototype)
18
+ const proto = Object.getPrototypeOf(zlib.Deflate.prototype)
19
19
  if (proto._transform) {
20
20
  // streams2
21
21
  shim.wrap(proto, '_transform', wrapNoSegment)
@@ -12,8 +12,8 @@ module.exports = function initialize(agent, director, moduleName, shim) {
12
12
  return route instanceof Array ? route.join('/') : route
13
13
  })
14
14
 
15
- var methods = ['on', 'route']
16
- var proto = director.Router.prototype
15
+ const methods = ['on', 'route']
16
+ const proto = director.Router.prototype
17
17
  shim.wrapMiddlewareMounter(proto, methods, {
18
18
  route: shim.SECOND,
19
19
  wrapper: function wrapMiddleware(shim, middleware, name, path) {
@@ -32,7 +32,7 @@ module.exports = function initialize(agent, director, moduleName, shim) {
32
32
 
33
33
  shim.wrap(proto, 'mount', function wrapMount(shim, mount) {
34
34
  return function wrappedMount(routes, path) {
35
- var isAsync = this.async
35
+ const isAsync = this.async
36
36
  shim.wrap(routes, director.http.methods, function wrapRoute(shim, route) {
37
37
  return shim.recordMiddleware(route, {
38
38
  route: path.join('/'),
@@ -45,7 +45,7 @@ module.exports = function initialize(agent, director, moduleName, shim) {
45
45
  next: isAsync ? shim.LAST : null
46
46
  })
47
47
  })
48
- var args = [routes, path]
48
+ const args = [routes, path]
49
49
  return mount.apply(this, args)
50
50
  }
51
51
  })
@@ -48,7 +48,7 @@ function wrapExpress4(shim, express) {
48
48
  }
49
49
 
50
50
  return function wrappedRoute() {
51
- var route = fn.apply(this, arguments)
51
+ const route = fn.apply(this, arguments)
52
52
 
53
53
  // Express should create a new route and layer every time Router#route is
54
54
  // called, but just to be on the safe side, make sure we haven't wrapped
@@ -56,7 +56,7 @@ function wrapExpress4(shim, express) {
56
56
  if (!shim.isWrapped(route, 'get')) {
57
57
  wrapRouteMethods(shim, route, '')
58
58
 
59
- var layer = this.stack[this.stack.length - 1]
59
+ const layer = this.stack[this.stack.length - 1]
60
60
 
61
61
  // This wraps a 'done' function but not a traditional 'next' function. This allows
62
62
  // the route to stay on the stack for middleware nesting after the router.
@@ -120,7 +120,7 @@ function wrapExpress3(shim, express) {
120
120
  }
121
121
 
122
122
  function wrapRouteMethods(shim, route, path) {
123
- var methods = ['all', 'delete', 'get', 'head', 'opts', 'post', 'put', 'patch']
123
+ const methods = ['all', 'delete', 'get', 'head', 'opts', 'post', 'put', 'patch']
124
124
  shim.wrapMiddlewareMounter(route, methods, { route: path, wrapper: wrapMiddleware })
125
125
  }
126
126
 
@@ -128,13 +128,13 @@ function wrapResponse(shim, response) {
128
128
  shim.recordRender(response, 'render', {
129
129
  view: shim.FIRST,
130
130
  callback: function bindCallback(shim, render, name, segment, args) {
131
- var cbIdx = shim.normalizeIndex(args.length, shim.LAST)
131
+ let cbIdx = shim.normalizeIndex(args.length, shim.LAST)
132
132
  if (cbIdx === null) {
133
133
  return
134
134
  }
135
135
 
136
- var res = this
137
- var cb = args[cbIdx]
136
+ const res = this
137
+ let cb = args[cbIdx]
138
138
  if (!shim.isFunction(cb)) {
139
139
  ++cbIdx
140
140
  cb = function defaultRenderCB(err, str) {
@@ -152,8 +152,8 @@ function wrapResponse(shim, response) {
152
152
  }
153
153
 
154
154
  function wrapMiddleware(shim, middleware, name, route) {
155
- var method = null
156
- var spec = {
155
+ let method = null
156
+ const spec = {
157
157
  route: route,
158
158
  type: shim.MIDDLEWARE,
159
159
  matchArity: true,