newrelic 9.6.0 → 9.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/NEWS.md +40 -16
  2. package/THIRD_PARTY_NOTICES.md +203 -2
  3. package/api.js +155 -101
  4. package/bin/test-naming-rules.js +1 -1
  5. package/esm-loader.mjs +1 -3
  6. package/lib/adaptive-sampler.js +1 -2
  7. package/lib/agent.js +29 -80
  8. package/lib/aggregators/event-aggregator.js +2 -2
  9. package/lib/attributes.js +2 -4
  10. package/lib/collector/api.js +252 -211
  11. package/lib/collector/facts.js +1 -3
  12. package/lib/collector/parse-response.js +3 -1
  13. package/lib/collector/remote-method.js +8 -9
  14. package/lib/config/attribute-filter.js +42 -34
  15. package/lib/config/default.js +60 -17
  16. package/lib/config/harvest-config-validator.js +3 -5
  17. package/lib/config/index.js +263 -199
  18. package/lib/environment.js +22 -17
  19. package/lib/errors/error-collector.js +123 -51
  20. package/lib/errors/helper.js +10 -18
  21. package/lib/errors/index.js +63 -47
  22. package/lib/grpc/connection.js +12 -5
  23. package/lib/header-attributes.js +4 -2
  24. package/lib/header-processing.js +2 -2
  25. package/lib/instrumentation/@hapi/hapi.js +56 -48
  26. package/lib/instrumentation/@node-redis/client.js +50 -39
  27. package/lib/instrumentation/amqplib.js +116 -149
  28. package/lib/instrumentation/core/{async_hooks.js → async-hooks.js} +26 -9
  29. package/lib/instrumentation/core/globals.js +12 -9
  30. package/lib/instrumentation/core/http-outbound.js +200 -83
  31. package/lib/instrumentation/core/http.js +10 -8
  32. package/lib/instrumentation/core/timers.js +106 -57
  33. package/lib/instrumentation/fastify.js +1 -3
  34. package/lib/instrumentation/grpc-js/grpc.js +14 -3
  35. package/lib/instrumentation/memcached.js +5 -0
  36. package/lib/instrumentation/mongodb/common.js +88 -83
  37. package/lib/instrumentation/mongodb/v2-mongo.js +6 -3
  38. package/lib/instrumentation/mongodb.js +1 -1
  39. package/lib/instrumentation/nr-winston-transport.js +3 -4
  40. package/lib/instrumentation/redis.js +112 -88
  41. package/lib/instrumentation/undici.js +204 -190
  42. package/lib/instrumentation/{when.js → when/constants.js} +13 -10
  43. package/lib/instrumentation/when/contextualizer.js +168 -0
  44. package/lib/instrumentation/when/index.js +354 -0
  45. package/lib/instrumentation/when/nr-hooks.js +15 -0
  46. package/lib/instrumentations.js +1 -1
  47. package/lib/metrics/mapper.js +2 -3
  48. package/lib/metrics/metric-aggregator.js +1 -3
  49. package/lib/metrics/names.js +19 -15
  50. package/lib/metrics/normalizer/rule.js +6 -7
  51. package/lib/metrics/normalizer/tx_segment.js +3 -2
  52. package/lib/metrics/normalizer.js +5 -3
  53. package/lib/parse-proc-cpuinfo.js +11 -6
  54. package/lib/serverless/api-gateway.js +3 -4
  55. package/lib/serverless/aws-lambda.js +3 -3
  56. package/lib/shim/conglomerate-shim.js +2 -3
  57. package/lib/shim/datastore-shim.js +22 -104
  58. package/lib/shim/index.js +7 -0
  59. package/lib/shim/message-shim.js +2 -0
  60. package/lib/shim/promise-shim.js +48 -42
  61. package/lib/shim/shim.js +9 -7
  62. package/lib/shim/webframework-shim.js +21 -0
  63. package/lib/spans/map-to-streaming-type.js +0 -2
  64. package/lib/spans/span-context.js +2 -0
  65. package/lib/spans/span-event-aggregator.js +2 -2
  66. package/lib/spans/span-event.js +2 -2
  67. package/lib/spans/span-streamer.js +4 -0
  68. package/lib/spans/streaming-span-event-aggregator.js +2 -4
  69. package/lib/spans/streaming-span-event.js +3 -2
  70. package/lib/symbols.js +1 -0
  71. package/lib/system-info.js +241 -166
  72. package/lib/timer.js +8 -6
  73. package/lib/transaction/dt-payload.js +4 -3
  74. package/lib/transaction/handle.js +12 -2
  75. package/lib/transaction/index.js +19 -18
  76. package/lib/transaction/name-state.js +17 -2
  77. package/lib/transaction/trace/aggregator.js +4 -12
  78. package/lib/transaction/trace/index.js +7 -5
  79. package/lib/transaction/trace/segment.js +6 -11
  80. package/lib/transaction/tracecontext.js +10 -6
  81. package/lib/transaction/tracer/index.js +23 -25
  82. package/lib/transaction/transaction-event-aggregator.js +1 -3
  83. package/lib/util/async-each-limit.js +30 -0
  84. package/lib/util/attribute-types.js +1 -2
  85. package/lib/util/attributes.js +159 -0
  86. package/lib/util/byte-limit.js +1 -3
  87. package/lib/util/cat.js +16 -13
  88. package/lib/util/code-level-metrics.js +58 -0
  89. package/lib/util/codec.js +0 -2
  90. package/lib/util/copy.js +1 -2
  91. package/lib/util/deep-equal.js +11 -137
  92. package/lib/util/flatten.js +4 -6
  93. package/lib/util/hashes.js +1 -3
  94. package/lib/util/process-version.js +2 -3
  95. package/lib/util/properties.js +2 -5
  96. package/lib/util/stream-sink.js +2 -0
  97. package/lib/util/urltils.js +4 -10
  98. package/newrelic.js +1 -1
  99. package/package.json +6 -4
  100. package/lib/instrumentation/promise.js +0 -569
package/lib/agent.js CHANGED
@@ -14,7 +14,6 @@ const ErrorCollector = require('./errors/error-collector')
14
14
  const ErrorTraceAggregator = require('./errors/error-trace-aggregator')
15
15
  const ErrorEventAggregator = require('./errors/error-event-aggregator')
16
16
  const EventEmitter = require('events').EventEmitter
17
- const hashes = require('./util/hashes')
18
17
  const logger = require('./logger')
19
18
  const LogAggregator = require('./aggregators/log-aggregator')
20
19
  const MetricMapper = require('./metrics/mapper')
@@ -31,6 +30,15 @@ const uninstrumented = require('./uninstrumented')
31
30
  const util = require('util')
32
31
  const createSpanEventAggregator = require('./spans/create-span-event-aggregator')
33
32
  const createContextManager = require('./context-manager/create-context-manager')
33
+ const {
34
+ maybeAddDatabaseAttributes,
35
+ maybeAddExternalAttributes,
36
+ addRequiredCATAttributes,
37
+ maybeAddExtraCATAttributes,
38
+ maybeAddParentAttributes,
39
+ maybeAddQueueAttributes,
40
+ maybeAddSyntheticAttributes
41
+ } = require('./util/attributes')
34
42
 
35
43
  // Map of valid states to whether or not data collection is valid
36
44
  const STATES = {
@@ -56,7 +64,7 @@ const DEFAULT_HARVEST_INTERVAL_MS = 60000
56
64
  * available. Don't try to recover here, because without configuration the
57
65
  * agent can't be brought up to a useful state.
58
66
  *
59
- * @param config
67
+ * @param {object} config Agent configuration object
60
68
  */
61
69
  function Agent(config) {
62
70
  EventEmitter.call(this)
@@ -199,8 +207,8 @@ util.inherits(Agent, EventEmitter)
199
207
  * managed by index.js. An agent will be created even if the agent's disabled by
200
208
  * the configuration.
201
209
  *
202
- * @config {boolean} agent_enabled Whether to start up the agent.
203
210
  * @param {Function} callback Continuation and error handler.
211
+ * @returns {void}
204
212
  */
205
213
  Agent.prototype.start = function start(callback) {
206
214
  if (!callback) {
@@ -454,8 +462,8 @@ Agent.prototype.startAggregators = function startAggregators() {
454
462
  * Completes any final setup upon full connection to New Relic
455
463
  * servers and sets the agent state to 'started'.
456
464
  *
457
- * @param shouldImmediatelyHarvest
458
- * @param callback
465
+ * @param {boolean} shouldImmediatelyHarvest Whether we should immediately schedule a harvest, or wait a cycle
466
+ * @param {Function} callback callback function that executes after harvest completes (now if immediate, otherwise later)
459
467
  */
460
468
  Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
461
469
  this._reconfigureAggregators(this.config)
@@ -514,7 +522,7 @@ Agent.prototype._scheduleHarvests = function _scheduleHarvests(shouldImmediately
514
522
  * Bypasses standard collector connection by immediately invoking the startup
515
523
  * callback, after gathering local environment details.
516
524
  *
517
- * @param {Function} callback
525
+ * @param {Function} callback Immediately invoked callback
518
526
  */
519
527
  Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
520
528
  logger.info('New Relic for Node.js starting in serverless mode -- skipping connection process.')
@@ -529,7 +537,7 @@ Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
529
537
  * "hard" restart. This requires working with shimmer to strip the
530
538
  * current instrumentation and patch to the module loader.
531
539
  *
532
- * @param callback
540
+ * @param {Function} callback callback function to invoke after agent stop
533
541
  */
534
542
  Agent.prototype.stop = function stop(callback) {
535
543
  if (!callback) {
@@ -587,9 +595,6 @@ Agent.prototype._resetEvents = function resetEvents() {
587
595
 
588
596
  /**
589
597
  * Resets custom events.
590
- *
591
- * @param {boolean} forceReset
592
- * Flag signalling unconditional reset, sent during LASP application.
593
598
  */
594
599
  Agent.prototype._resetCustomEvents = function resetCustomEvents() {
595
600
  this.customEventAggregator.clear()
@@ -696,6 +701,8 @@ Agent.prototype.setState = function setState(newState) {
696
701
  /**
697
702
  * Return true if the agent is in a run state that can collect and
698
703
  * process data.
704
+ *
705
+ * @returns {boolean} Whether or not the agent can collect data in its current state
699
706
  */
700
707
  Agent.prototype.canCollectData = function canCollectData() {
701
708
  return STATES[this._state]
@@ -735,84 +742,26 @@ function _addIntrinsicAttrsFromTransaction(transaction) {
735
742
  error: transaction.hasErrors()
736
743
  }
737
744
 
738
- let metric = transaction.metrics.getMetric(NAMES.QUEUETIME)
739
- if (metric) {
740
- intrinsicAttributes.queueDuration = metric.total
741
- }
742
-
743
- metric = transaction.metrics.getMetric(NAMES.EXTERNAL.ALL)
744
- if (metric) {
745
- intrinsicAttributes.externalDuration = metric.total
746
- intrinsicAttributes.externalCallCount = metric.callCount
747
- }
748
-
749
- metric = transaction.metrics.getMetric(NAMES.DB.ALL)
750
- if (metric) {
751
- intrinsicAttributes.databaseDuration = metric.total
752
- intrinsicAttributes.databaseCallCount = metric.callCount
753
- }
745
+ maybeAddQueueAttributes(transaction, intrinsicAttributes)
746
+ maybeAddExternalAttributes(transaction, intrinsicAttributes)
747
+ maybeAddDatabaseAttributes(transaction, intrinsicAttributes)
748
+ maybeAddSyntheticAttributes(transaction, intrinsicAttributes)
754
749
 
755
750
  if (this.config.distributed_tracing.enabled) {
756
751
  transaction.addDistributedTraceIntrinsics(intrinsicAttributes)
757
- if (transaction.parentSpanId) {
758
- intrinsicAttributes.parentSpanId = transaction.parentSpanId
759
- }
760
-
761
- if (transaction.parentId) {
762
- intrinsicAttributes.parentId = transaction.parentId
763
- }
752
+ maybeAddParentAttributes(transaction, intrinsicAttributes)
764
753
  } else if (
765
754
  this.config.cross_application_tracer.enabled &&
766
755
  !transaction.invalidIncomingExternalTransaction &&
767
756
  (transaction.referringTransactionGuid || transaction.includesOutboundRequests())
768
757
  ) {
769
- intrinsicAttributes['nr.guid'] = transaction.id
770
- intrinsicAttributes['nr.tripId'] = transaction.tripId || transaction.id
771
- intrinsicAttributes['nr.pathHash'] = hashes.calculatePathHash(
772
- this.config.applications()[0],
773
- transaction.getFullName(),
774
- transaction.referringPathHash
775
- )
776
- if (transaction.referringPathHash) {
777
- intrinsicAttributes['nr.referringPathHash'] = transaction.referringPathHash
778
- }
779
- if (transaction.referringTransactionGuid) {
780
- const refId = transaction.referringTransactionGuid
781
- intrinsicAttributes['nr.referringTransactionGuid'] = refId
782
- }
783
- const alternatePathHashes = transaction.alternatePathHashes()
784
- if (alternatePathHashes) {
785
- intrinsicAttributes['nr.alternatePathHashes'] = alternatePathHashes
786
- }
787
- if (transaction.baseSegment && transaction.type === 'web') {
788
- const apdex =
789
- this.config.web_transactions_apdex[transaction.getFullName()] || this.config.apdex_t
790
- const duration = transaction.baseSegment.getDurationInMillis() / 1000
791
- intrinsicAttributes['nr.apdexPerfZone'] = calculateApdexZone(duration, apdex)
792
- }
793
- }
794
-
795
- if (transaction.syntheticsData) {
796
- intrinsicAttributes['nr.syntheticsResourceId'] = transaction.syntheticsData.resourceId
797
- intrinsicAttributes['nr.syntheticsJobId'] = transaction.syntheticsData.jobId
798
- intrinsicAttributes['nr.syntheticsMonitorId'] = transaction.syntheticsData.monitorId
758
+ addRequiredCATAttributes(transaction, intrinsicAttributes, this.config)
759
+ maybeAddExtraCATAttributes(transaction, intrinsicAttributes, this.config)
799
760
  }
800
761
 
801
762
  return intrinsicAttributes
802
763
  }
803
764
 
804
- function calculateApdexZone(duration, apdexT) {
805
- if (duration <= apdexT) {
806
- return 'S' // satisfied
807
- }
808
-
809
- if (duration <= apdexT * 4) {
810
- return 'T' // tolerating
811
- }
812
-
813
- return 'F' // frustrated
814
- }
815
-
816
765
  Agent.prototype._addEventFromTransaction = function _addEventFromTransaction(tx) {
817
766
  if (!this.config.transaction_events.enabled) {
818
767
  return
@@ -831,7 +780,7 @@ Agent.prototype._addEventFromTransaction = function _addEventFromTransaction(tx)
831
780
  * Put all the logic for handing finalized transactions off to the tracers and
832
781
  * metric collections in one place.
833
782
  *
834
- * @param {Transaction} transaction Newly-finalized transaction.
783
+ * @param {object} transaction Newly-finalized transaction.
835
784
  */
836
785
  Agent.prototype._transactionFinished = function _transactionFinished(transaction) {
837
786
  // Allow the API to explicitly set the ignored status.
@@ -879,7 +828,7 @@ Agent.prototype.setLambdaFunctionVersion = function setLambdaFunctionVersion(fun
879
828
  /**
880
829
  * Get the current transaction (if there is one) from the tracer.
881
830
  *
882
- * @returns {Transaction} The current transaction.
831
+ * @returns {object} The current transaction.
883
832
  */
884
833
  Agent.prototype.getTransaction = function getTransaction() {
885
834
  return this.tracer.getTransaction()
@@ -936,7 +885,7 @@ Agent.prototype._listenForConfigChanges = function _listenForConfigChanges() {
936
885
  * utilization.full_hostname. If utilization.full_hostname is null or empty,
937
886
  * this will be the hostname specified in the connect request as host.
938
887
  *
939
- * @returns {LinkingMetadata} The linking object with the data above
888
+ * @returns {object} The LinkingMetadata object with the data above
940
889
  */
941
890
  Agent.prototype.getLinkingMetadata = function getLinkingMetadata() {
942
891
  const segment = this.tracer.getSegment()
@@ -986,7 +935,7 @@ Agent.prototype.getNRLinkingMetadata = function getNRLinkingMetadata() {
986
935
  * Retries value for a given key but defaults to `` if falsey
987
936
  *
988
937
  * @param {string} key in linking metadata
989
- * @returns {string}
938
+ * @returns {string} Metadata value or empty string
990
939
  */
991
940
  function getValue(key) {
992
941
  return metadata[key] || ''
@@ -1037,7 +986,7 @@ function generateEventHarvestSupportMetrics(agent, harvestConfig) {
1037
986
  * Increments the call counts of application logging supportability metrics
1038
987
  * on every connect cycle
1039
988
  *
1040
- * @param {Agent} agent
989
+ * @param {object} agent Instantiation of Node.js agent
1041
990
  */
1042
991
  function generateLoggingSupportMetrics(agent) {
1043
992
  const loggingConfig = agent.config.application_logging
@@ -76,7 +76,7 @@ class EventAggregator extends Aggregator {
76
76
  /**
77
77
  * Fetches all the span events aggregated.
78
78
  *
79
- * @return {array.<Event>} An array of span events from the aggregator.
79
+ * @returns {Array.<Event>} An array of span events from the aggregator.
80
80
  */
81
81
  getEvents() {
82
82
  return this._items.toArray()
@@ -85,7 +85,7 @@ class EventAggregator extends Aggregator {
85
85
  /**
86
86
  * Resets the contents of the aggregator and all counters.
87
87
  *
88
- * @return {PriorityQueue} The old collection of aggregated events.
88
+ * @returns {PriorityQueue} The old collection of aggregated events.
89
89
  */
90
90
  clearEvents() {
91
91
  // ???: might be more efficient to clear here and come up with an efficient way to
package/lib/attributes.js CHANGED
@@ -22,7 +22,6 @@ 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
- *
26
25
  * @param {number} [limit=Infinity]
27
26
  * The maximum number of attributes to retrieve for each destination.
28
27
  */
@@ -61,7 +60,7 @@ class Attributes {
61
60
  * attributes allowed, no more than that number will be included in the result.
62
61
  *
63
62
  * @param {AttributeFilter.DESTINATIONS} dest
64
- * @return {object}
63
+ * @returns {object}
65
64
  */
66
65
  get(dest) {
67
66
  const attrs = Object.create(null)
@@ -168,8 +167,7 @@ class Attributes {
168
167
  * Creates a filter function for the given scope.
169
168
  *
170
169
  * @param {string} scope - The scope of the filter to make.
171
- *
172
- * @return {function} A function that performs attribute filtering for the given
170
+ * @returns {Function} A function that performs attribute filtering for the given
173
171
  * scope.
174
172
  */
175
173
  function makeFilter(scope) {