newrelic 9.7.0 → 9.7.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.
- package/NEWS.md +42 -18
- package/THIRD_PARTY_NOTICES.md +203 -2
- package/api.js +155 -103
- package/lib/agent.js +29 -82
- package/lib/collector/api.js +234 -201
- package/lib/config/attribute-filter.js +35 -25
- package/lib/config/default.js +45 -19
- package/lib/config/index.js +260 -199
- package/lib/environment.js +16 -12
- package/lib/errors/error-collector.js +124 -55
- package/lib/errors/index.js +59 -49
- package/lib/instrumentation/@hapi/hapi.js +56 -50
- package/lib/instrumentation/@node-redis/client.js +50 -41
- package/lib/instrumentation/amqplib.js +116 -151
- package/lib/instrumentation/core/{async_hooks.js → async-hooks.js} +26 -11
- package/lib/instrumentation/core/globals.js +1 -1
- package/lib/instrumentation/core/http-outbound.js +193 -78
- package/lib/instrumentation/core/timers.js +106 -59
- package/lib/instrumentation/grpc-js/grpc.js +20 -23
- package/lib/instrumentation/mongodb/common.js +87 -85
- package/lib/instrumentation/redis.js +112 -90
- package/lib/instrumentation/undici.js +204 -192
- 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/shim/shim.js +2 -0
- package/lib/shim/webframework-shim.js +19 -0
- package/lib/symbols.js +1 -0
- package/lib/system-info.js +240 -163
- package/lib/util/async-each-limit.js +30 -0
- package/lib/util/attributes.js +159 -0
- package/lib/util/code-level-metrics.js +58 -0
- package/lib/util/deep-equal.js +11 -144
- package/package.json +5 -4
- package/lib/instrumentation/promise.js +0 -572
package/lib/agent.js
CHANGED
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
/* eslint sonarjs/cognitive-complexity: ["error", 23] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
-
|
|
10
8
|
const AdaptiveSampler = require('./adaptive-sampler')
|
|
11
9
|
const CollectorAPI = require('./collector/api')
|
|
12
10
|
const ServerlessCollector = require('./collector/serverless')
|
|
@@ -16,7 +14,6 @@ const ErrorCollector = require('./errors/error-collector')
|
|
|
16
14
|
const ErrorTraceAggregator = require('./errors/error-trace-aggregator')
|
|
17
15
|
const ErrorEventAggregator = require('./errors/error-event-aggregator')
|
|
18
16
|
const EventEmitter = require('events').EventEmitter
|
|
19
|
-
const hashes = require('./util/hashes')
|
|
20
17
|
const logger = require('./logger')
|
|
21
18
|
const LogAggregator = require('./aggregators/log-aggregator')
|
|
22
19
|
const MetricMapper = require('./metrics/mapper')
|
|
@@ -33,6 +30,15 @@ const uninstrumented = require('./uninstrumented')
|
|
|
33
30
|
const util = require('util')
|
|
34
31
|
const createSpanEventAggregator = require('./spans/create-span-event-aggregator')
|
|
35
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')
|
|
36
42
|
|
|
37
43
|
// Map of valid states to whether or not data collection is valid
|
|
38
44
|
const STATES = {
|
|
@@ -58,7 +64,7 @@ const DEFAULT_HARVEST_INTERVAL_MS = 60000
|
|
|
58
64
|
* available. Don't try to recover here, because without configuration the
|
|
59
65
|
* agent can't be brought up to a useful state.
|
|
60
66
|
*
|
|
61
|
-
* @param config
|
|
67
|
+
* @param {object} config Agent configuration object
|
|
62
68
|
*/
|
|
63
69
|
function Agent(config) {
|
|
64
70
|
EventEmitter.call(this)
|
|
@@ -201,8 +207,8 @@ util.inherits(Agent, EventEmitter)
|
|
|
201
207
|
* managed by index.js. An agent will be created even if the agent's disabled by
|
|
202
208
|
* the configuration.
|
|
203
209
|
*
|
|
204
|
-
* @config {boolean} agent_enabled Whether to start up the agent.
|
|
205
210
|
* @param {Function} callback Continuation and error handler.
|
|
211
|
+
* @returns {void}
|
|
206
212
|
*/
|
|
207
213
|
Agent.prototype.start = function start(callback) {
|
|
208
214
|
if (!callback) {
|
|
@@ -456,8 +462,8 @@ Agent.prototype.startAggregators = function startAggregators() {
|
|
|
456
462
|
* Completes any final setup upon full connection to New Relic
|
|
457
463
|
* servers and sets the agent state to 'started'.
|
|
458
464
|
*
|
|
459
|
-
* @param shouldImmediatelyHarvest
|
|
460
|
-
* @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)
|
|
461
467
|
*/
|
|
462
468
|
Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
|
|
463
469
|
this._reconfigureAggregators(this.config)
|
|
@@ -516,7 +522,7 @@ Agent.prototype._scheduleHarvests = function _scheduleHarvests(shouldImmediately
|
|
|
516
522
|
* Bypasses standard collector connection by immediately invoking the startup
|
|
517
523
|
* callback, after gathering local environment details.
|
|
518
524
|
*
|
|
519
|
-
* @param {Function} callback
|
|
525
|
+
* @param {Function} callback Immediately invoked callback
|
|
520
526
|
*/
|
|
521
527
|
Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
|
|
522
528
|
logger.info('New Relic for Node.js starting in serverless mode -- skipping connection process.')
|
|
@@ -531,7 +537,7 @@ Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
|
|
|
531
537
|
* "hard" restart. This requires working with shimmer to strip the
|
|
532
538
|
* current instrumentation and patch to the module loader.
|
|
533
539
|
*
|
|
534
|
-
* @param callback
|
|
540
|
+
* @param {Function} callback callback function to invoke after agent stop
|
|
535
541
|
*/
|
|
536
542
|
Agent.prototype.stop = function stop(callback) {
|
|
537
543
|
if (!callback) {
|
|
@@ -589,9 +595,6 @@ Agent.prototype._resetEvents = function resetEvents() {
|
|
|
589
595
|
|
|
590
596
|
/**
|
|
591
597
|
* Resets custom events.
|
|
592
|
-
*
|
|
593
|
-
* @param {boolean} forceReset
|
|
594
|
-
* Flag signalling unconditional reset, sent during LASP application.
|
|
595
598
|
*/
|
|
596
599
|
Agent.prototype._resetCustomEvents = function resetCustomEvents() {
|
|
597
600
|
this.customEventAggregator.clear()
|
|
@@ -698,6 +701,8 @@ Agent.prototype.setState = function setState(newState) {
|
|
|
698
701
|
/**
|
|
699
702
|
* Return true if the agent is in a run state that can collect and
|
|
700
703
|
* process data.
|
|
704
|
+
*
|
|
705
|
+
* @returns {boolean} Whether or not the agent can collect data in its current state
|
|
701
706
|
*/
|
|
702
707
|
Agent.prototype.canCollectData = function canCollectData() {
|
|
703
708
|
return STATES[this._state]
|
|
@@ -737,84 +742,26 @@ function _addIntrinsicAttrsFromTransaction(transaction) {
|
|
|
737
742
|
error: transaction.hasErrors()
|
|
738
743
|
}
|
|
739
744
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
metric = transaction.metrics.getMetric(NAMES.EXTERNAL.ALL)
|
|
746
|
-
if (metric) {
|
|
747
|
-
intrinsicAttributes.externalDuration = metric.total
|
|
748
|
-
intrinsicAttributes.externalCallCount = metric.callCount
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
metric = transaction.metrics.getMetric(NAMES.DB.ALL)
|
|
752
|
-
if (metric) {
|
|
753
|
-
intrinsicAttributes.databaseDuration = metric.total
|
|
754
|
-
intrinsicAttributes.databaseCallCount = metric.callCount
|
|
755
|
-
}
|
|
745
|
+
maybeAddQueueAttributes(transaction, intrinsicAttributes)
|
|
746
|
+
maybeAddExternalAttributes(transaction, intrinsicAttributes)
|
|
747
|
+
maybeAddDatabaseAttributes(transaction, intrinsicAttributes)
|
|
748
|
+
maybeAddSyntheticAttributes(transaction, intrinsicAttributes)
|
|
756
749
|
|
|
757
750
|
if (this.config.distributed_tracing.enabled) {
|
|
758
751
|
transaction.addDistributedTraceIntrinsics(intrinsicAttributes)
|
|
759
|
-
|
|
760
|
-
intrinsicAttributes.parentSpanId = transaction.parentSpanId
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
if (transaction.parentId) {
|
|
764
|
-
intrinsicAttributes.parentId = transaction.parentId
|
|
765
|
-
}
|
|
752
|
+
maybeAddParentAttributes(transaction, intrinsicAttributes)
|
|
766
753
|
} else if (
|
|
767
754
|
this.config.cross_application_tracer.enabled &&
|
|
768
755
|
!transaction.invalidIncomingExternalTransaction &&
|
|
769
756
|
(transaction.referringTransactionGuid || transaction.includesOutboundRequests())
|
|
770
757
|
) {
|
|
771
|
-
intrinsicAttributes
|
|
772
|
-
|
|
773
|
-
intrinsicAttributes['nr.pathHash'] = hashes.calculatePathHash(
|
|
774
|
-
this.config.applications()[0],
|
|
775
|
-
transaction.getFullName(),
|
|
776
|
-
transaction.referringPathHash
|
|
777
|
-
)
|
|
778
|
-
if (transaction.referringPathHash) {
|
|
779
|
-
intrinsicAttributes['nr.referringPathHash'] = transaction.referringPathHash
|
|
780
|
-
}
|
|
781
|
-
if (transaction.referringTransactionGuid) {
|
|
782
|
-
const refId = transaction.referringTransactionGuid
|
|
783
|
-
intrinsicAttributes['nr.referringTransactionGuid'] = refId
|
|
784
|
-
}
|
|
785
|
-
const alternatePathHashes = transaction.alternatePathHashes()
|
|
786
|
-
if (alternatePathHashes) {
|
|
787
|
-
intrinsicAttributes['nr.alternatePathHashes'] = alternatePathHashes
|
|
788
|
-
}
|
|
789
|
-
if (transaction.baseSegment && transaction.type === 'web') {
|
|
790
|
-
const apdex =
|
|
791
|
-
this.config.web_transactions_apdex[transaction.getFullName()] || this.config.apdex_t
|
|
792
|
-
const duration = transaction.baseSegment.getDurationInMillis() / 1000
|
|
793
|
-
intrinsicAttributes['nr.apdexPerfZone'] = calculateApdexZone(duration, apdex)
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
if (transaction.syntheticsData) {
|
|
798
|
-
intrinsicAttributes['nr.syntheticsResourceId'] = transaction.syntheticsData.resourceId
|
|
799
|
-
intrinsicAttributes['nr.syntheticsJobId'] = transaction.syntheticsData.jobId
|
|
800
|
-
intrinsicAttributes['nr.syntheticsMonitorId'] = transaction.syntheticsData.monitorId
|
|
758
|
+
addRequiredCATAttributes(transaction, intrinsicAttributes, this.config)
|
|
759
|
+
maybeAddExtraCATAttributes(transaction, intrinsicAttributes, this.config)
|
|
801
760
|
}
|
|
802
761
|
|
|
803
762
|
return intrinsicAttributes
|
|
804
763
|
}
|
|
805
764
|
|
|
806
|
-
function calculateApdexZone(duration, apdexT) {
|
|
807
|
-
if (duration <= apdexT) {
|
|
808
|
-
return 'S' // satisfied
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
if (duration <= apdexT * 4) {
|
|
812
|
-
return 'T' // tolerating
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
return 'F' // frustrated
|
|
816
|
-
}
|
|
817
|
-
|
|
818
765
|
Agent.prototype._addEventFromTransaction = function _addEventFromTransaction(tx) {
|
|
819
766
|
if (!this.config.transaction_events.enabled) {
|
|
820
767
|
return
|
|
@@ -833,7 +780,7 @@ Agent.prototype._addEventFromTransaction = function _addEventFromTransaction(tx)
|
|
|
833
780
|
* Put all the logic for handing finalized transactions off to the tracers and
|
|
834
781
|
* metric collections in one place.
|
|
835
782
|
*
|
|
836
|
-
* @param {
|
|
783
|
+
* @param {object} transaction Newly-finalized transaction.
|
|
837
784
|
*/
|
|
838
785
|
Agent.prototype._transactionFinished = function _transactionFinished(transaction) {
|
|
839
786
|
// Allow the API to explicitly set the ignored status.
|
|
@@ -881,7 +828,7 @@ Agent.prototype.setLambdaFunctionVersion = function setLambdaFunctionVersion(fun
|
|
|
881
828
|
/**
|
|
882
829
|
* Get the current transaction (if there is one) from the tracer.
|
|
883
830
|
*
|
|
884
|
-
* @returns {
|
|
831
|
+
* @returns {object} The current transaction.
|
|
885
832
|
*/
|
|
886
833
|
Agent.prototype.getTransaction = function getTransaction() {
|
|
887
834
|
return this.tracer.getTransaction()
|
|
@@ -938,7 +885,7 @@ Agent.prototype._listenForConfigChanges = function _listenForConfigChanges() {
|
|
|
938
885
|
* utilization.full_hostname. If utilization.full_hostname is null or empty,
|
|
939
886
|
* this will be the hostname specified in the connect request as host.
|
|
940
887
|
*
|
|
941
|
-
* @returns {
|
|
888
|
+
* @returns {object} The LinkingMetadata object with the data above
|
|
942
889
|
*/
|
|
943
890
|
Agent.prototype.getLinkingMetadata = function getLinkingMetadata() {
|
|
944
891
|
const segment = this.tracer.getSegment()
|
|
@@ -988,7 +935,7 @@ Agent.prototype.getNRLinkingMetadata = function getNRLinkingMetadata() {
|
|
|
988
935
|
* Retries value for a given key but defaults to `` if falsey
|
|
989
936
|
*
|
|
990
937
|
* @param {string} key in linking metadata
|
|
991
|
-
* @returns {string}
|
|
938
|
+
* @returns {string} Metadata value or empty string
|
|
992
939
|
*/
|
|
993
940
|
function getValue(key) {
|
|
994
941
|
return metadata[key] || ''
|
|
@@ -1039,7 +986,7 @@ function generateEventHarvestSupportMetrics(agent, harvestConfig) {
|
|
|
1039
986
|
* Increments the call counts of application logging supportability metrics
|
|
1040
987
|
* on every connect cycle
|
|
1041
988
|
*
|
|
1042
|
-
* @param {
|
|
989
|
+
* @param {object} agent Instantiation of Node.js agent
|
|
1043
990
|
*/
|
|
1044
991
|
function generateLoggingSupportMetrics(agent) {
|
|
1045
992
|
const loggingConfig = agent.config.application_logging
|