newrelic 8.2.0 → 8.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/NEWS.md +5061 -4963
  2. package/README.md +7 -6
  3. package/THIRD_PARTY_NOTICES.md +95 -68
  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 +2 -3
  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 +26 -9
  15. package/lib/config/env.js +14 -4
  16. package/lib/config/hsm.js +1 -1
  17. package/lib/config/index.js +90 -69
  18. package/lib/config/lasp.js +3 -3
  19. package/lib/config/merge-server-config.js +1 -1
  20. package/lib/db/parse-sql.js +8 -8
  21. package/lib/db/parsed-statement.js +9 -8
  22. package/lib/db/query-parsers/sql.js +7 -7
  23. package/lib/db/query-sample.js +9 -9
  24. package/lib/db/query-trace-aggregator.js +4 -4
  25. package/lib/db/statement-matcher.js +5 -5
  26. package/lib/db/utils.js +1 -1
  27. package/lib/environment.js +43 -43
  28. package/lib/errors/error-collector.js +2 -2
  29. package/lib/errors/error-trace-aggregator.js +1 -1
  30. package/lib/errors/helper.js +3 -3
  31. package/lib/errors/index.js +17 -17
  32. package/lib/feature_flags.js +7 -5
  33. package/lib/header-attributes.js +6 -6
  34. package/lib/header-processing.js +1 -1
  35. package/lib/instrumentation/amqplib.js +26 -26
  36. package/lib/instrumentation/bluebird.js +3 -3
  37. package/lib/instrumentation/cassandra-driver.js +7 -3
  38. package/lib/instrumentation/connect.js +4 -4
  39. package/lib/instrumentation/core/async_hooks.js +6 -6
  40. package/lib/instrumentation/core/domain.js +2 -2
  41. package/lib/instrumentation/core/globals.js +1 -1
  42. package/lib/instrumentation/core/http-outbound.js +15 -84
  43. package/lib/instrumentation/core/http.js +34 -67
  44. package/lib/instrumentation/core/inspector.js +2 -2
  45. package/lib/instrumentation/core/timers.js +7 -7
  46. package/lib/instrumentation/core/zlib.js +2 -2
  47. package/lib/instrumentation/director.js +4 -4
  48. package/lib/instrumentation/express.js +8 -8
  49. package/lib/instrumentation/fastify/spec-builders.js +57 -47
  50. package/lib/instrumentation/fastify.js +111 -28
  51. package/lib/instrumentation/generic-pool.js +1 -1
  52. package/lib/instrumentation/hapi/hapi-17.js +11 -11
  53. package/lib/instrumentation/hapi/shared.js +1 -1
  54. package/lib/instrumentation/hapi.js +22 -22
  55. package/lib/instrumentation/ioredis.js +7 -7
  56. package/lib/instrumentation/memcached.js +7 -7
  57. package/lib/instrumentation/mongodb/common.js +73 -23
  58. package/lib/instrumentation/mongodb/v3-mongo.js +20 -1
  59. package/lib/instrumentation/mongodb/v4-mongo.js +6 -7
  60. package/lib/instrumentation/mysql.js +19 -19
  61. package/lib/instrumentation/oracle.js +15 -15
  62. package/lib/instrumentation/pg.js +4 -4
  63. package/lib/instrumentation/promise.js +46 -46
  64. package/lib/instrumentation/q.js +2 -2
  65. package/lib/instrumentation/redis.js +11 -11
  66. package/lib/instrumentation/restify.js +1 -1
  67. package/lib/instrumentation/undici.js +242 -0
  68. package/lib/instrumentation/vision.js +4 -4
  69. package/lib/instrumentation/when.js +3 -3
  70. package/lib/instrumentations.js +2 -1
  71. package/lib/logger.js +5 -5
  72. package/lib/metrics/index.js +15 -15
  73. package/lib/metrics/mapper.js +7 -7
  74. package/lib/metrics/names.js +6 -3
  75. package/lib/metrics/normalizer/rule.js +9 -9
  76. package/lib/metrics/normalizer/tx_segment.js +17 -17
  77. package/lib/metrics/normalizer.js +22 -22
  78. package/lib/metrics/recorders/custom.js +5 -5
  79. package/lib/metrics/recorders/generic.js +3 -3
  80. package/lib/metrics/recorders/http.js +7 -7
  81. package/lib/metrics/recorders/http_external.js +7 -7
  82. package/lib/metrics/recorders/message-transaction.js +5 -6
  83. package/lib/metrics/recorders/other.js +5 -5
  84. package/lib/parse-proc-cpuinfo.js +25 -19
  85. package/lib/parse-proc-meminfo.js +8 -2
  86. package/lib/prioritized-attributes.js +2 -2
  87. package/lib/priority-queue.js +10 -10
  88. package/lib/reservoir.js +3 -3
  89. package/lib/sampler.js +26 -26
  90. package/lib/shim/datastore-shim.js +35 -32
  91. package/lib/shim/index.js +2 -2
  92. package/lib/shim/message-shim.js +47 -47
  93. package/lib/shim/promise-shim.js +1 -1
  94. package/lib/shim/shim.js +61 -61
  95. package/lib/shim/specs/index.js +3 -3
  96. package/lib/shim/transaction-shim.js +44 -192
  97. package/lib/shim/webframework-shim.js +52 -52
  98. package/lib/spans/span-event-aggregator.js +62 -10
  99. package/lib/spans/span-event.js +1 -1
  100. package/lib/spans/streaming-span-attributes.js +1 -1
  101. package/lib/stats/apdex.js +2 -2
  102. package/lib/stats/index.js +2 -2
  103. package/lib/system-info.js +23 -23
  104. package/lib/timer.js +5 -5
  105. package/lib/transaction/dt-payload.js +1 -1
  106. package/lib/transaction/index.js +40 -40
  107. package/lib/transaction/name-state.js +14 -14
  108. package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
  109. package/lib/transaction/trace/index.js +14 -14
  110. package/lib/transaction/trace/segment.js +18 -18
  111. package/lib/transaction/tracecontext.js +1 -1
  112. package/lib/transaction/tracer/index.js +53 -49
  113. package/lib/uninstrumented.js +7 -7
  114. package/lib/util/arity.js +2 -2
  115. package/lib/util/byte-limit.js +4 -4
  116. package/lib/util/cat.js +269 -24
  117. package/lib/util/codec.js +2 -2
  118. package/lib/util/copy.js +2 -2
  119. package/lib/util/deep-equal.js +10 -10
  120. package/lib/util/flatten.js +4 -4
  121. package/lib/util/hashes.js +14 -14
  122. package/lib/util/label-parser.js +17 -17
  123. package/lib/util/logger.js +24 -24
  124. package/lib/util/process-version.js +2 -2
  125. package/lib/util/properties.js +4 -4
  126. package/lib/util/sql/obfuscate.js +15 -15
  127. package/lib/util/stream-sink.js +3 -3
  128. package/lib/util/unwrapped-core.js +2 -2
  129. package/lib/util/urltils.js +16 -16
  130. package/lib/utilization/aws-info.js +7 -7
  131. package/lib/utilization/azure-info.js +6 -6
  132. package/lib/utilization/common.js +13 -13
  133. package/lib/utilization/docker-info.js +11 -11
  134. package/lib/utilization/gcp-info.js +4 -4
  135. package/lib/utilization/index.js +5 -5
  136. package/lib/utilization/pcf-info.js +9 -9
  137. package/package.json +13 -7
  138. package/stub_api.js +8 -8
@@ -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,
@@ -1,19 +1,43 @@
1
1
  /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
2
+ * Copyright 2021 New Relic Corporation. All rights reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
6
  'use strict'
7
7
 
8
- const getRawRequestFromFastifyRequest = (shim, fn, fnName, args) => {
9
- const request = args[0]
8
+ /**
9
+ * Retrieves the IncomingMessage from a Fastify request. Depending on the
10
+ * context of this function it either exists on `request.raw` or just `request`
11
+ *
12
+ * @param {WebFrameworkShim} shim
13
+ * @param {Function} fn middleware function executing
14
+ * @param {string} fnName name of middleware executing
15
+ * @param {args} args that are passed to middleware
16
+ * @returns {IncomingMessage}
17
+ */
18
+ const getRequestFromFastify = (shim, fn, fnName, args) => {
19
+ const [request] = args
20
+
21
+ // request is Fastify request
22
+ // object, get IncomingMessage from .raw
10
23
  if (request && request.raw) {
11
24
  return request.raw
12
25
  }
26
+
27
+ return request
13
28
  }
14
29
 
30
+ /**
31
+ * Retrieves the params from the Fastify request.
32
+ *
33
+ * @param {WebFrameworkShim} shim
34
+ * @param {Function} fn middleware function executing
35
+ * @param {string} fnName name of middleware executing
36
+ * @param {args} args that are passed to middleware
37
+ * @returns {object} URL params on a Fastify request
38
+ */
15
39
  const getParamsFromFastifyRequest = (shim, fn, fnName, args) => {
16
- const req = args[0]
40
+ const [req] = args
17
41
  return req && req.params
18
42
  }
19
43
 
@@ -21,32 +45,17 @@ const getParamsFromFastifyRequest = (shim, fn, fnName, args) => {
21
45
  * Builds the recordMiddleware Spec for the route handler
22
46
  *
23
47
  * A spec is basically a specification -- or a list
24
- * of insrtuctions to the recordMiddleware function
48
+ * of instructions to the recordMiddleware function
25
49
  * that provide it with the information it needs to
26
50
  * do its job. You could also think of it as a
27
51
  * mini-DSL
52
+ *
53
+ * @param {WebFrameworkShim} shim
54
+ * @param {string} path URL route being executed
55
+ * @returns {object} spec for Fastify route handler
28
56
  */
29
57
  function buildMiddlewareSpecForRouteHandler(shim, path) {
30
58
  return {
31
- /**
32
- * The path to use for transaction naming
33
- */
34
- route: path,
35
-
36
- /**
37
- * A function the returns the NodeJS Request Object
38
- *
39
- * The job of the `req` callback is to return the current NodeJS
40
- * IncomingMessage object for this particular handler. Most NodeJS
41
- * frameworks will pass the request to each handler -- sometimes (as
42
- * is the case here) wrapped by another object.
43
- *
44
- * @param {any} shim the Webframework Shim
45
- * @param {any} fn the handler function passed to buildMiddlewareSpec
46
- * @param {any} fnName the handler function's name
47
- * @param {any} args the arguments passed to the handler function
48
- */
49
- req: getRawRequestFromFastifyRequest,
50
59
  /**
51
60
  * A function where we can wrap next, reply send, etc. methods
52
61
  *
@@ -66,6 +75,12 @@ function buildMiddlewareSpecForRouteHandler(shim, path) {
66
75
  * The isFinal param determines whether or not a path is appended for
67
76
  * this particular piece of middleware. (i.e. if this is the final handler
68
77
  * that is actually handling the request, the path is actually left on)
78
+ *
79
+ * @param shim
80
+ * @param fn
81
+ * @param fnName
82
+ * @param args
83
+ * @param bindSegment
69
84
  */
70
85
  next: function wrapNext(shim, fn, fnName, args, bindSegment) {
71
86
  const reply = args[1]
@@ -75,33 +90,28 @@ function buildMiddlewareSpecForRouteHandler(shim, path) {
75
90
  const isFinal = true
76
91
  bindSegment(reply, 'send', isFinal)
77
92
  },
78
-
79
- /**
80
- * A function that returns the request paramates
81
- *
82
- * @param {any} shim the Webframework Shim
83
- * @param {any} fn the handler function passed to buildMiddlewareSpec
84
- * @param {any} fnName the handler function's name
85
- * @param {any} args the arguments passed to the handler function
86
- */
87
- params: getParamsFromFastifyRequest
93
+ params: getParamsFromFastifyRequest,
94
+ req: getRequestFromFastify,
95
+ route: path
88
96
  }
89
97
  }
90
98
 
91
- function buildMiddlewareSpecForMiddlewareFunction() {
99
+ /**
100
+ * Spec for all Fastify middleware(excluding route handlers)
101
+ *
102
+ * @param {WebFrameworkShim} shim
103
+ * @param {string} name metric name for middleware being executed
104
+ * @param route
105
+ * @returns {object} spec for Fastify middleware
106
+ */
107
+ function buildMiddlewareSpecForMiddlewareFunction(shim, name, route) {
92
108
  return {
93
- req: getRawRequestFromFastifyRequest,
94
-
95
- next: function wrapNext(shim, fn, fnName, args, bindSegment) {
96
- const next = args[2]
97
- if (!shim.isFunction(next)) {
98
- return
99
- }
100
- const isFinal = false
101
- bindSegment(next, null, isFinal)
102
- },
103
-
104
- params: getParamsFromFastifyRequest
109
+ name,
110
+ route,
111
+ next: shim.LAST,
112
+ params: getParamsFromFastifyRequest,
113
+ req: getRequestFromFastify,
114
+ type: shim.MIDDLEWARE
105
115
  }
106
116
  }
107
117