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.
- package/NEWS.md +40 -16
- package/THIRD_PARTY_NOTICES.md +203 -2
- package/api.js +155 -101
- package/bin/test-naming-rules.js +1 -1
- package/esm-loader.mjs +1 -3
- package/lib/adaptive-sampler.js +1 -2
- package/lib/agent.js +29 -80
- package/lib/aggregators/event-aggregator.js +2 -2
- package/lib/attributes.js +2 -4
- package/lib/collector/api.js +252 -211
- package/lib/collector/facts.js +1 -3
- package/lib/collector/parse-response.js +3 -1
- package/lib/collector/remote-method.js +8 -9
- package/lib/config/attribute-filter.js +42 -34
- package/lib/config/default.js +60 -17
- package/lib/config/harvest-config-validator.js +3 -5
- package/lib/config/index.js +263 -199
- package/lib/environment.js +22 -17
- package/lib/errors/error-collector.js +123 -51
- package/lib/errors/helper.js +10 -18
- package/lib/errors/index.js +63 -47
- package/lib/grpc/connection.js +12 -5
- package/lib/header-attributes.js +4 -2
- package/lib/header-processing.js +2 -2
- package/lib/instrumentation/@hapi/hapi.js +56 -48
- package/lib/instrumentation/@node-redis/client.js +50 -39
- package/lib/instrumentation/amqplib.js +116 -149
- package/lib/instrumentation/core/{async_hooks.js → async-hooks.js} +26 -9
- package/lib/instrumentation/core/globals.js +12 -9
- package/lib/instrumentation/core/http-outbound.js +200 -83
- package/lib/instrumentation/core/http.js +10 -8
- package/lib/instrumentation/core/timers.js +106 -57
- package/lib/instrumentation/fastify.js +1 -3
- package/lib/instrumentation/grpc-js/grpc.js +14 -3
- package/lib/instrumentation/memcached.js +5 -0
- package/lib/instrumentation/mongodb/common.js +88 -83
- package/lib/instrumentation/mongodb/v2-mongo.js +6 -3
- package/lib/instrumentation/mongodb.js +1 -1
- package/lib/instrumentation/nr-winston-transport.js +3 -4
- package/lib/instrumentation/redis.js +112 -88
- package/lib/instrumentation/undici.js +204 -190
- package/lib/instrumentation/{when.js → when/constants.js} +13 -10
- package/lib/instrumentation/when/contextualizer.js +168 -0
- package/lib/instrumentation/when/index.js +354 -0
- package/lib/instrumentation/when/nr-hooks.js +15 -0
- package/lib/instrumentations.js +1 -1
- package/lib/metrics/mapper.js +2 -3
- package/lib/metrics/metric-aggregator.js +1 -3
- package/lib/metrics/names.js +19 -15
- package/lib/metrics/normalizer/rule.js +6 -7
- package/lib/metrics/normalizer/tx_segment.js +3 -2
- package/lib/metrics/normalizer.js +5 -3
- package/lib/parse-proc-cpuinfo.js +11 -6
- package/lib/serverless/api-gateway.js +3 -4
- package/lib/serverless/aws-lambda.js +3 -3
- package/lib/shim/conglomerate-shim.js +2 -3
- package/lib/shim/datastore-shim.js +22 -104
- package/lib/shim/index.js +7 -0
- package/lib/shim/message-shim.js +2 -0
- package/lib/shim/promise-shim.js +48 -42
- package/lib/shim/shim.js +9 -7
- package/lib/shim/webframework-shim.js +21 -0
- package/lib/spans/map-to-streaming-type.js +0 -2
- package/lib/spans/span-context.js +2 -0
- package/lib/spans/span-event-aggregator.js +2 -2
- package/lib/spans/span-event.js +2 -2
- package/lib/spans/span-streamer.js +4 -0
- package/lib/spans/streaming-span-event-aggregator.js +2 -4
- package/lib/spans/streaming-span-event.js +3 -2
- package/lib/symbols.js +1 -0
- package/lib/system-info.js +241 -166
- package/lib/timer.js +8 -6
- package/lib/transaction/dt-payload.js +4 -3
- package/lib/transaction/handle.js +12 -2
- package/lib/transaction/index.js +19 -18
- package/lib/transaction/name-state.js +17 -2
- package/lib/transaction/trace/aggregator.js +4 -12
- package/lib/transaction/trace/index.js +7 -5
- package/lib/transaction/trace/segment.js +6 -11
- package/lib/transaction/tracecontext.js +10 -6
- package/lib/transaction/tracer/index.js +23 -25
- package/lib/transaction/transaction-event-aggregator.js +1 -3
- package/lib/util/async-each-limit.js +30 -0
- package/lib/util/attribute-types.js +1 -2
- package/lib/util/attributes.js +159 -0
- package/lib/util/byte-limit.js +1 -3
- package/lib/util/cat.js +16 -13
- package/lib/util/code-level-metrics.js +58 -0
- package/lib/util/codec.js +0 -2
- package/lib/util/copy.js +1 -2
- package/lib/util/deep-equal.js +11 -137
- package/lib/util/flatten.js +4 -6
- package/lib/util/hashes.js +1 -3
- package/lib/util/process-version.js +2 -3
- package/lib/util/properties.js +2 -5
- package/lib/util/stream-sink.js +2 -0
- package/lib/util/urltils.js +4 -10
- package/newrelic.js +1 -1
- package/package.json +6 -4
- 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
|
-
|
|
739
|
-
|
|
740
|
-
|
|
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
|
-
|
|
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
|
|
770
|
-
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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
|
-
* @
|
|
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) {
|