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.
- package/NEWS.md +76 -0
- package/README.md +7 -6
- package/THIRD_PARTY_NOTICES.md +95 -35
- package/api.js +74 -68
- package/bin/test-naming-rules.js +22 -22
- package/lib/agent.js +4 -4
- package/lib/attributes.js +2 -2
- package/lib/collector/api.js +12 -12
- package/lib/collector/facts.js +1 -1
- package/lib/collector/http-agents.js +12 -11
- package/lib/collector/key-parser.js +1 -1
- package/lib/collector/remote-method.js +27 -26
- package/lib/config/attribute-filter.js +23 -23
- package/lib/config/default.js +12 -10
- package/lib/config/hsm.js +1 -1
- package/lib/config/index.js +82 -66
- package/lib/config/lasp.js +3 -3
- package/lib/config/merge-server-config.js +1 -1
- package/lib/db/parse-sql.js +8 -8
- package/lib/db/parsed-statement.js +9 -8
- package/lib/db/query-parsers/sql.js +7 -7
- package/lib/db/query-sample.js +9 -9
- package/lib/db/query-trace-aggregator.js +4 -4
- package/lib/db/statement-matcher.js +5 -5
- package/lib/db/utils.js +1 -1
- package/lib/environment.js +43 -43
- package/lib/errors/error-collector.js +2 -2
- package/lib/errors/error-trace-aggregator.js +1 -1
- package/lib/errors/helper.js +3 -3
- package/lib/errors/index.js +17 -17
- package/lib/feature_flags.js +7 -5
- package/lib/header-attributes.js +6 -6
- package/lib/header-processing.js +1 -1
- package/lib/instrumentation/amqplib.js +26 -26
- package/lib/instrumentation/bluebird.js +3 -3
- package/lib/instrumentation/cassandra-driver.js +7 -3
- package/lib/instrumentation/connect.js +4 -4
- package/lib/instrumentation/core/async_hooks.js +6 -6
- package/lib/instrumentation/core/domain.js +2 -2
- package/lib/instrumentation/core/globals.js +1 -1
- package/lib/instrumentation/core/http-outbound.js +15 -84
- package/lib/instrumentation/core/http.js +34 -67
- package/lib/instrumentation/core/inspector.js +2 -2
- package/lib/instrumentation/core/timers.js +7 -7
- package/lib/instrumentation/core/zlib.js +2 -2
- package/lib/instrumentation/director.js +4 -4
- package/lib/instrumentation/express.js +8 -8
- package/lib/instrumentation/fastify/spec-builders.js +57 -47
- package/lib/instrumentation/fastify.js +85 -24
- package/lib/instrumentation/generic-pool.js +1 -1
- package/lib/instrumentation/hapi/hapi-17.js +11 -11
- package/lib/instrumentation/hapi/shared.js +1 -1
- package/lib/instrumentation/hapi.js +22 -22
- package/lib/instrumentation/ioredis.js +7 -7
- package/lib/instrumentation/memcached.js +7 -7
- package/lib/instrumentation/mongodb/common.js +16 -5
- package/lib/instrumentation/mysql.js +19 -19
- package/lib/instrumentation/oracle.js +15 -15
- package/lib/instrumentation/pg.js +4 -4
- package/lib/instrumentation/promise.js +46 -46
- package/lib/instrumentation/q.js +2 -2
- package/lib/instrumentation/redis.js +11 -11
- package/lib/instrumentation/restify.js +1 -1
- package/lib/instrumentation/undici.js +242 -0
- package/lib/instrumentation/vision.js +4 -4
- package/lib/instrumentation/when.js +3 -3
- package/lib/instrumentations.js +2 -1
- package/lib/logger.js +5 -5
- package/lib/metrics/index.js +15 -15
- package/lib/metrics/mapper.js +7 -7
- package/lib/metrics/normalizer/rule.js +9 -9
- package/lib/metrics/normalizer/tx_segment.js +17 -17
- package/lib/metrics/normalizer.js +22 -22
- package/lib/metrics/recorders/custom.js +5 -5
- package/lib/metrics/recorders/generic.js +3 -3
- package/lib/metrics/recorders/http.js +7 -7
- package/lib/metrics/recorders/http_external.js +7 -7
- package/lib/metrics/recorders/message-transaction.js +5 -6
- package/lib/metrics/recorders/other.js +5 -5
- package/lib/parse-proc-cpuinfo.js +25 -19
- package/lib/parse-proc-meminfo.js +8 -2
- package/lib/prioritized-attributes.js +2 -2
- package/lib/priority-queue.js +10 -10
- package/lib/reservoir.js +3 -3
- package/lib/sampler.js +26 -26
- package/lib/serverless/aws-lambda.js +8 -2
- package/lib/shim/datastore-shim.js +35 -32
- package/lib/shim/index.js +2 -2
- package/lib/shim/message-shim.js +47 -47
- package/lib/shim/promise-shim.js +1 -1
- package/lib/shim/shim.js +61 -61
- package/lib/shim/specs/index.js +3 -3
- package/lib/shim/transaction-shim.js +44 -192
- package/lib/shim/webframework-shim.js +52 -52
- package/lib/spans/span-event.js +1 -1
- package/lib/spans/streaming-span-attributes.js +1 -1
- package/lib/stats/apdex.js +2 -2
- package/lib/stats/index.js +2 -2
- package/lib/system-info.js +23 -23
- package/lib/timer.js +5 -5
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/index.js +40 -40
- package/lib/transaction/name-state.js +14 -14
- package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
- package/lib/transaction/trace/index.js +14 -14
- package/lib/transaction/trace/segment.js +18 -18
- package/lib/transaction/tracecontext.js +1 -1
- package/lib/transaction/tracer/index.js +53 -49
- package/lib/uninstrumented.js +7 -7
- package/lib/util/arity.js +2 -2
- package/lib/util/byte-limit.js +4 -4
- package/lib/util/cat.js +269 -24
- package/lib/util/codec.js +2 -2
- package/lib/util/copy.js +2 -2
- package/lib/util/deep-equal.js +10 -10
- package/lib/util/flatten.js +4 -4
- package/lib/util/hashes.js +14 -14
- package/lib/util/label-parser.js +17 -17
- package/lib/util/logger.js +24 -24
- package/lib/util/process-version.js +2 -2
- package/lib/util/properties.js +4 -4
- package/lib/util/sql/obfuscate.js +15 -15
- package/lib/util/stream-sink.js +3 -3
- package/lib/util/unwrapped-core.js +2 -2
- package/lib/util/urltils.js +16 -16
- package/lib/utilization/aws-info.js +7 -7
- package/lib/utilization/azure-info.js +6 -6
- package/lib/utilization/common.js +13 -13
- package/lib/utilization/docker-info.js +11 -11
- package/lib/utilization/gcp-info.js +4 -4
- package/lib/utilization/index.js +5 -5
- package/lib/utilization/pcf-info.js +9 -9
- package/package.json +13 -6
- package/stub_api.js +8 -8
package/api.js
CHANGED
|
@@ -76,12 +76,12 @@ function API(agent) {
|
|
|
76
76
|
* Relic UI. Will be prefixed with 'Custom/' when sent.
|
|
77
77
|
*/
|
|
78
78
|
API.prototype.setTransactionName = function setTransactionName(name) {
|
|
79
|
-
|
|
79
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
80
80
|
NAMES.SUPPORTABILITY.API + '/setTransactionName'
|
|
81
81
|
)
|
|
82
82
|
metric.incrementCallCount()
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
const transaction = this.agent.tracer.getTransaction()
|
|
85
85
|
if (!transaction) {
|
|
86
86
|
return logger.warn("No transaction found when setting name to '%s'.", name)
|
|
87
87
|
}
|
|
@@ -112,10 +112,10 @@ API.prototype.setTransactionName = function setTransactionName(name) {
|
|
|
112
112
|
* `ignore` methods on it.
|
|
113
113
|
*/
|
|
114
114
|
API.prototype.getTransaction = function getTransaction() {
|
|
115
|
-
|
|
115
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/getTransaction')
|
|
116
116
|
metric.incrementCallCount()
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
const transaction = this.agent.tracer.getTransaction()
|
|
119
119
|
if (!transaction) {
|
|
120
120
|
logger.debug('No transaction found when calling API#getTransaction')
|
|
121
121
|
return new TransactionHandle.Stub()
|
|
@@ -191,7 +191,7 @@ API.prototype.getLinkingMetadata = function getLinkingMetadata(omitSupportabilit
|
|
|
191
191
|
* report to New Relic
|
|
192
192
|
*/
|
|
193
193
|
API.prototype.setDispatcher = function setDispatcher(name, version) {
|
|
194
|
-
|
|
194
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/setDispatcher')
|
|
195
195
|
metric.incrementCallCount()
|
|
196
196
|
|
|
197
197
|
if (!name || typeof name !== 'string') {
|
|
@@ -230,10 +230,12 @@ API.prototype.setDispatcher = function setDispatcher(name, version) {
|
|
|
230
230
|
* to the HTTP method used for the request.
|
|
231
231
|
*/
|
|
232
232
|
API.prototype.setControllerName = function setControllerName(name, action) {
|
|
233
|
-
|
|
233
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
234
|
+
NAMES.SUPPORTABILITY.API + '/setControllerName'
|
|
235
|
+
)
|
|
234
236
|
metric.incrementCallCount()
|
|
235
237
|
|
|
236
|
-
|
|
238
|
+
const transaction = this.agent.tracer.getTransaction()
|
|
237
239
|
if (!transaction) {
|
|
238
240
|
return logger.warn('No transaction found when setting controller to %s.', name)
|
|
239
241
|
}
|
|
@@ -320,12 +322,12 @@ API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
|
320
322
|
* @param {string} [atts.KEY.VALUE] The value you want displayed. Must be serializable.
|
|
321
323
|
*/
|
|
322
324
|
API.prototype.addCustomAttributes = function addCustomAttributes(atts) {
|
|
323
|
-
|
|
325
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
324
326
|
NAMES.SUPPORTABILITY.API + '/addCustomAttributes'
|
|
325
327
|
)
|
|
326
328
|
metric.incrementCallCount()
|
|
327
329
|
|
|
328
|
-
for (
|
|
330
|
+
for (const key in atts) {
|
|
329
331
|
if (!properties.hasOwn(atts, key)) {
|
|
330
332
|
continue
|
|
331
333
|
}
|
|
@@ -353,7 +355,7 @@ API.prototype.addCustomSpanAttributes = function addCustomSpanAttributes(atts) {
|
|
|
353
355
|
)
|
|
354
356
|
metric.incrementCallCount()
|
|
355
357
|
|
|
356
|
-
for (
|
|
358
|
+
for (const key in atts) {
|
|
357
359
|
if (properties.hasOwn(atts, key)) {
|
|
358
360
|
this.addCustomSpanAttribute(key, atts[key])
|
|
359
361
|
}
|
|
@@ -478,7 +480,7 @@ API.prototype.noticeError = function noticeError(error, customAttributes) {
|
|
|
478
480
|
* @param {string} name The name to use for the transaction.
|
|
479
481
|
*/
|
|
480
482
|
API.prototype.addNamingRule = function addNamingRule(pattern, name) {
|
|
481
|
-
|
|
483
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/addNamingRule')
|
|
482
484
|
metric.incrementCallCount()
|
|
483
485
|
|
|
484
486
|
if (!name) {
|
|
@@ -502,7 +504,7 @@ API.prototype.addNamingRule = function addNamingRule(pattern, name) {
|
|
|
502
504
|
* @param {RegExp} pattern The pattern to ignore.
|
|
503
505
|
*/
|
|
504
506
|
API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
505
|
-
|
|
507
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/addIgnoringRule')
|
|
506
508
|
metric.incrementCallCount()
|
|
507
509
|
|
|
508
510
|
if (!pattern) {
|
|
@@ -528,12 +530,12 @@ API.prototype.addIgnoringRule = function addIgnoringRule(pattern) {
|
|
|
528
530
|
* @returns {string} The `<script>` header to be injected.
|
|
529
531
|
*/
|
|
530
532
|
API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options) {
|
|
531
|
-
|
|
533
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
532
534
|
NAMES.SUPPORTABILITY.API + '/getBrowserTimingHeader'
|
|
533
535
|
)
|
|
534
536
|
metric.incrementCallCount()
|
|
535
537
|
|
|
536
|
-
|
|
538
|
+
const config = this.agent.config
|
|
537
539
|
|
|
538
540
|
/**
|
|
539
541
|
* Gracefully fail.
|
|
@@ -555,7 +557,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
555
557
|
return '<!-- NREUM: (' + num + ') -->'
|
|
556
558
|
}
|
|
557
559
|
|
|
558
|
-
|
|
560
|
+
const browserMonitoring = config.browser_monitoring
|
|
559
561
|
|
|
560
562
|
// config.browser_monitoring should always exist, but we don't want the agent
|
|
561
563
|
// to bail here if something goes wrong
|
|
@@ -573,14 +575,14 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
573
575
|
return _gracefail(0, true)
|
|
574
576
|
}
|
|
575
577
|
|
|
576
|
-
|
|
578
|
+
const trans = this.agent.getTransaction()
|
|
577
579
|
|
|
578
580
|
// bail gracefully outside a transaction
|
|
579
581
|
if (!trans || trans.isIgnored()) {
|
|
580
582
|
return _gracefail(1)
|
|
581
583
|
}
|
|
582
584
|
|
|
583
|
-
|
|
585
|
+
const name = trans.getFullName()
|
|
584
586
|
|
|
585
587
|
/* If we're in an unnamed transaction, add a friendly warning this is to
|
|
586
588
|
* avoid people going crazy, trying to figure out why browser monitoring is
|
|
@@ -590,14 +592,14 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
590
592
|
return _gracefail(3)
|
|
591
593
|
}
|
|
592
594
|
|
|
593
|
-
|
|
595
|
+
const time = trans.timer.getDurationInMillis()
|
|
594
596
|
|
|
595
597
|
/*
|
|
596
598
|
* Only the first 13 chars of the license should be used for hashing with
|
|
597
599
|
* the transaction name.
|
|
598
600
|
*/
|
|
599
|
-
|
|
600
|
-
|
|
601
|
+
const key = config.license_key.substr(0, 13)
|
|
602
|
+
const appid = config.application_id
|
|
601
603
|
|
|
602
604
|
/* This is only going to work if the agent has successfully handshaked with
|
|
603
605
|
* the collector. If the networks is bad, or there is no license key set in
|
|
@@ -611,7 +613,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
611
613
|
/* If there is no browser_key, the server has likely decided to disable
|
|
612
614
|
* browser monitoring.
|
|
613
615
|
*/
|
|
614
|
-
|
|
616
|
+
const licenseKey = browserMonitoring.browser_key
|
|
615
617
|
if (!licenseKey) {
|
|
616
618
|
return _gracefail(5)
|
|
617
619
|
}
|
|
@@ -619,7 +621,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
619
621
|
/* If there is no agent_loader script, there is no point
|
|
620
622
|
* in setting the rum data
|
|
621
623
|
*/
|
|
622
|
-
|
|
624
|
+
const jsAgentLoader = browserMonitoring.js_agent_loader
|
|
623
625
|
if (!jsAgentLoader) {
|
|
624
626
|
return _gracefail(6)
|
|
625
627
|
}
|
|
@@ -631,13 +633,13 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
631
633
|
* the lifetime of an application, and it should be picked up
|
|
632
634
|
* on the next ForceRestart by the collector.
|
|
633
635
|
*/
|
|
634
|
-
|
|
636
|
+
const loader = browserMonitoring.loader
|
|
635
637
|
if (loader === 'none') {
|
|
636
638
|
return _gracefail(7)
|
|
637
639
|
}
|
|
638
640
|
|
|
639
641
|
// This hash gets written directly into the browser.
|
|
640
|
-
|
|
642
|
+
const rumHash = {
|
|
641
643
|
agent: browserMonitoring.js_agent_file,
|
|
642
644
|
beacon: browserMonitoring.beacon,
|
|
643
645
|
errorBeacon: browserMonitoring.error_beacon,
|
|
@@ -652,7 +654,7 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
652
654
|
agentToken: null
|
|
653
655
|
}
|
|
654
656
|
|
|
655
|
-
|
|
657
|
+
const attrs = Object.create(null)
|
|
656
658
|
|
|
657
659
|
const customAttrs = trans.trace.custom.get(ATTR_DEST.BROWSER_EVENT)
|
|
658
660
|
if (!properties.isEmpty(customAttrs)) {
|
|
@@ -669,14 +671,14 @@ API.prototype.getBrowserTimingHeader = function getBrowserTimingHeader(options)
|
|
|
669
671
|
}
|
|
670
672
|
|
|
671
673
|
// if debugging, do pretty format of JSON
|
|
672
|
-
|
|
673
|
-
|
|
674
|
+
const tabs = config.browser_monitoring.debug ? 2 : 0
|
|
675
|
+
const json = JSON.stringify(rumHash, null, tabs)
|
|
674
676
|
|
|
675
677
|
// set nonce attribute if passed in options
|
|
676
|
-
|
|
678
|
+
const nonce = options && options.nonce ? 'nonce="' + options.nonce + '"' : ''
|
|
677
679
|
|
|
678
680
|
// the complete header to be written to the browser
|
|
679
|
-
|
|
681
|
+
const out = util.format(RUM_STUB, nonce, json, jsAgentLoader)
|
|
680
682
|
|
|
681
683
|
logger.trace('generating RUM header', out)
|
|
682
684
|
|
|
@@ -742,7 +744,7 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
742
744
|
}
|
|
743
745
|
|
|
744
746
|
// Create the segment and call the handler.
|
|
745
|
-
|
|
747
|
+
const wrappedHandler = this.shim.record(handler, function handlerNamer(shim) {
|
|
746
748
|
return {
|
|
747
749
|
name: name,
|
|
748
750
|
recorder: record ? customRecorder : null,
|
|
@@ -782,7 +784,7 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
782
784
|
* Function that represents the transaction work.
|
|
783
785
|
*/
|
|
784
786
|
API.prototype.startWebTransaction = function startWebTransaction(url, handle) {
|
|
785
|
-
|
|
787
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
786
788
|
NAMES.SUPPORTABILITY.API + '/startWebTransaction'
|
|
787
789
|
)
|
|
788
790
|
metric.incrementCallCount()
|
|
@@ -799,12 +801,12 @@ API.prototype.startWebTransaction = function startWebTransaction(url, handle) {
|
|
|
799
801
|
|
|
800
802
|
logger.debug('starting web transaction %s (%s).', url, handle && handle.name)
|
|
801
803
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
804
|
+
const shim = this.shim
|
|
805
|
+
const tracer = this.agent.tracer
|
|
806
|
+
const parent = tracer.getTransaction()
|
|
805
807
|
|
|
806
808
|
return tracer.transactionNestProxy('web', function startWebSegment() {
|
|
807
|
-
|
|
809
|
+
const tx = tracer.getTransaction()
|
|
808
810
|
|
|
809
811
|
if (!tx) {
|
|
810
812
|
return handle.apply(this, arguments)
|
|
@@ -827,8 +829,8 @@ API.prototype.startWebTransaction = function startWebTransaction(url, handle) {
|
|
|
827
829
|
tx.baseSegment = tracer.createSegment(url, recordWeb)
|
|
828
830
|
tx.baseSegment.start()
|
|
829
831
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
+
const boundHandle = tracer.bindFunction(handle, tx.baseSegment)
|
|
833
|
+
let returnResult = boundHandle.call(this)
|
|
832
834
|
if (returnResult && shim.isPromise(returnResult)) {
|
|
833
835
|
returnResult = shim.interceptPromise(returnResult, tx.end.bind(tx))
|
|
834
836
|
} else if (!tx.handledExternally) {
|
|
@@ -877,7 +879,7 @@ API.prototype.startBackgroundTransaction = startBackgroundTransaction
|
|
|
877
879
|
* @memberOf API#
|
|
878
880
|
*/
|
|
879
881
|
function startBackgroundTransaction(name, group, handle) {
|
|
880
|
-
|
|
882
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
881
883
|
NAMES.SUPPORTABILITY.API + '/startBackgroundTransaction'
|
|
882
884
|
)
|
|
883
885
|
metric.incrementCallCount()
|
|
@@ -899,13 +901,13 @@ function startBackgroundTransaction(name, group, handle) {
|
|
|
899
901
|
|
|
900
902
|
logger.debug('starting background transaction %s:%s (%s)', name, group, handle && handle.name)
|
|
901
903
|
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
904
|
+
const tracer = this.agent.tracer
|
|
905
|
+
const shim = this.shim
|
|
906
|
+
const txName = group + '/' + name
|
|
907
|
+
const parent = tracer.getTransaction()
|
|
906
908
|
|
|
907
909
|
return tracer.transactionNestProxy('bg', function startBackgroundSegment() {
|
|
908
|
-
|
|
910
|
+
const tx = tracer.getTransaction()
|
|
909
911
|
|
|
910
912
|
if (!tx) {
|
|
911
913
|
return handle.apply(this, arguments)
|
|
@@ -929,8 +931,8 @@ function startBackgroundTransaction(name, group, handle) {
|
|
|
929
931
|
tx.baseSegment.partialName = group
|
|
930
932
|
tx.baseSegment.start()
|
|
931
933
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
+
const boundHandle = tracer.bindFunction(handle, tx.baseSegment)
|
|
935
|
+
let returnResult = boundHandle.call(this)
|
|
934
936
|
if (returnResult && shim.isPromise(returnResult)) {
|
|
935
937
|
returnResult = shim.interceptPromise(returnResult, tx.end.bind(tx))
|
|
936
938
|
} else if (!tx.handledExternally) {
|
|
@@ -946,11 +948,11 @@ function startBackgroundTransaction(name, group, handle) {
|
|
|
946
948
|
* the correct transaction context when called.
|
|
947
949
|
*/
|
|
948
950
|
API.prototype.endTransaction = function endTransaction() {
|
|
949
|
-
|
|
951
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/endTransaction')
|
|
950
952
|
metric.incrementCallCount()
|
|
951
953
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
+
const tracer = this.agent.tracer
|
|
955
|
+
const tx = tracer.getTransaction()
|
|
954
956
|
|
|
955
957
|
if (tx) {
|
|
956
958
|
if (tx.baseSegment) {
|
|
@@ -1069,7 +1071,9 @@ API.prototype.incrementMetric = function incrementMetric(name, value) {
|
|
|
1069
1071
|
* or boolean.
|
|
1070
1072
|
*/
|
|
1071
1073
|
API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attributes) {
|
|
1072
|
-
|
|
1074
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1075
|
+
NAMES.SUPPORTABILITY.API + '/recordCustomEvent'
|
|
1076
|
+
)
|
|
1073
1077
|
metric.incrementCallCount()
|
|
1074
1078
|
|
|
1075
1079
|
// If high security mode is on, custom events are disabled.
|
|
@@ -1086,7 +1090,7 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1086
1090
|
}
|
|
1087
1091
|
// Check all the arguments before bailing to give maximum information in a
|
|
1088
1092
|
// single invocation.
|
|
1089
|
-
|
|
1093
|
+
let fail = false
|
|
1090
1094
|
|
|
1091
1095
|
if (!eventType || typeof eventType !== 'string') {
|
|
1092
1096
|
logger.warn(
|
|
@@ -1131,13 +1135,13 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1131
1135
|
// Filter all object type valued attributes out
|
|
1132
1136
|
const filteredAttributes = _filterAttributes(attributes, `${eventType} custom event`)
|
|
1133
1137
|
|
|
1134
|
-
|
|
1138
|
+
const instrinics = {
|
|
1135
1139
|
type: eventType,
|
|
1136
1140
|
timestamp: Date.now()
|
|
1137
1141
|
}
|
|
1138
1142
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1143
|
+
const tx = this.agent.getTransaction()
|
|
1144
|
+
const priority = (tx && tx.priority) || Math.random()
|
|
1141
1145
|
this.agent.customEventAggregator.add([instrinics, filteredAttributes], priority)
|
|
1142
1146
|
}
|
|
1143
1147
|
|
|
@@ -1161,10 +1165,10 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
|
|
|
1161
1165
|
* this function.
|
|
1162
1166
|
*/
|
|
1163
1167
|
API.prototype.instrument = function instrument(moduleName, onRequire, onError) {
|
|
1164
|
-
|
|
1168
|
+
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/instrument')
|
|
1165
1169
|
metric.incrementCallCount()
|
|
1166
1170
|
|
|
1167
|
-
|
|
1171
|
+
let opts = moduleName
|
|
1168
1172
|
if (typeof opts === 'string') {
|
|
1169
1173
|
opts = {
|
|
1170
1174
|
moduleName: moduleName,
|
|
@@ -1234,12 +1238,12 @@ API.prototype.instrumentConglomerate = function instrumentConglomerate(
|
|
|
1234
1238
|
* this function.
|
|
1235
1239
|
*/
|
|
1236
1240
|
API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onRequire, onError) {
|
|
1237
|
-
|
|
1241
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1238
1242
|
NAMES.SUPPORTABILITY.API + '/instrumentDatastore'
|
|
1239
1243
|
)
|
|
1240
1244
|
metric.incrementCallCount()
|
|
1241
1245
|
|
|
1242
|
-
|
|
1246
|
+
let opts = moduleName
|
|
1243
1247
|
if (typeof opts === 'string') {
|
|
1244
1248
|
opts = {
|
|
1245
1249
|
moduleName: moduleName,
|
|
@@ -1271,7 +1275,7 @@ API.prototype.instrumentDatastore = function instrumentDatastore(moduleName, onR
|
|
|
1271
1275
|
* The actual module object or function we're instrumenting
|
|
1272
1276
|
*/
|
|
1273
1277
|
API.prototype.instrumentLoadedModule = function instrumentLoadedModule(moduleName, module) {
|
|
1274
|
-
|
|
1278
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1275
1279
|
NAMES.SUPPORTABILITY.API + '/instrumentLoadedModule'
|
|
1276
1280
|
)
|
|
1277
1281
|
metric.incrementCallCount()
|
|
@@ -1329,12 +1333,12 @@ API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
|
1329
1333
|
onRequire,
|
|
1330
1334
|
onError
|
|
1331
1335
|
) {
|
|
1332
|
-
|
|
1336
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1333
1337
|
NAMES.SUPPORTABILITY.API + '/instrumentWebframework'
|
|
1334
1338
|
)
|
|
1335
1339
|
metric.incrementCallCount()
|
|
1336
1340
|
|
|
1337
|
-
|
|
1341
|
+
let opts = moduleName
|
|
1338
1342
|
if (typeof opts === 'string') {
|
|
1339
1343
|
opts = {
|
|
1340
1344
|
moduleName: moduleName,
|
|
@@ -1367,12 +1371,12 @@ API.prototype.instrumentWebframework = function instrumentWebframework(
|
|
|
1367
1371
|
* this function.
|
|
1368
1372
|
*/
|
|
1369
1373
|
API.prototype.instrumentMessages = function instrumentMessages(moduleName, onRequire, onError) {
|
|
1370
|
-
|
|
1374
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1371
1375
|
NAMES.SUPPORTABILITY.API + '/instrumentMessages'
|
|
1372
1376
|
)
|
|
1373
1377
|
metric.incrementCallCount()
|
|
1374
1378
|
|
|
1375
|
-
|
|
1379
|
+
let opts = moduleName
|
|
1376
1380
|
if (typeof opts === 'string') {
|
|
1377
1381
|
opts = {
|
|
1378
1382
|
moduleName: moduleName,
|
|
@@ -1391,7 +1395,9 @@ API.prototype.instrumentMessages = function instrumentMessages(moduleName, onReq
|
|
|
1391
1395
|
* @returns {*} The object containing the current trace and span ids
|
|
1392
1396
|
*/
|
|
1393
1397
|
API.prototype.getTraceMetadata = function getTraceMetadata() {
|
|
1394
|
-
|
|
1398
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
1399
|
+
NAMES.SUPPORTABILITY.API + '/getTraceMetadata'
|
|
1400
|
+
)
|
|
1395
1401
|
metric.incrementCallCount()
|
|
1396
1402
|
|
|
1397
1403
|
const metadata = {}
|
|
@@ -1501,11 +1507,11 @@ function _doShutdown(api, options, callback) {
|
|
|
1501
1507
|
}
|
|
1502
1508
|
|
|
1503
1509
|
function _checkKeyLength(object, maxLength) {
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
for (
|
|
1510
|
+
const keys = Object.keys(object)
|
|
1511
|
+
let badKey = false
|
|
1512
|
+
const len = keys.length
|
|
1513
|
+
let key = '' // init to string because gotta go fast
|
|
1514
|
+
for (let i = 0; i < len; i++) {
|
|
1509
1515
|
key = keys[i]
|
|
1510
1516
|
if (key.length > maxLength) {
|
|
1511
1517
|
logger.warn(
|
package/bin/test-naming-rules.js
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
'use strict'
|
|
8
8
|
/* eslint-disable no-console */
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
const fs = require('fs')
|
|
11
|
+
const path = require('path')
|
|
12
|
+
const readline = require('readline')
|
|
13
|
+
const urltils = require('../lib/util/urltils')
|
|
14
|
+
const MetricNormalizer = require('../lib/metrics/normalizer')
|
|
15
|
+
|
|
16
|
+
const cwd = process.cwd()
|
|
17
|
+
let options = null
|
|
18
18
|
if (arrayContainsAny(process.argv, '-h', '-?', '--help')) {
|
|
19
19
|
printHelp()
|
|
20
20
|
} else if (process.argv.length === 3) {
|
|
@@ -59,26 +59,26 @@ function printHelp() {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function run(opts) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const config = require('../lib/config').initialize()
|
|
63
|
+
const runtimeRules = opts.rules ? require(opts.rules) : null
|
|
64
|
+
let appliedRules = []
|
|
65
65
|
|
|
66
66
|
// responsible for handling default rules provided by the server
|
|
67
|
-
|
|
67
|
+
const defaultNormalizer = loadDefaultNormalizer(config, runtimeRules)
|
|
68
68
|
|
|
69
69
|
// rules defined by user in local configuration file
|
|
70
|
-
|
|
70
|
+
const userNormalizer = loadUserNormalizer(config, runtimeRules)
|
|
71
71
|
|
|
72
72
|
defaultNormalizer.on('appliedRule', onAppliedRule)
|
|
73
73
|
userNormalizer.on('appliedRule', onAppliedRule)
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const urlsFile = fs.createReadStream(opts.urls, { encoding: 'utf-8' })
|
|
76
|
+
const reader = readline.createInterface({ input: urlsFile, output: null })
|
|
77
77
|
reader.on('line', function onUrlLine(urlLine) {
|
|
78
78
|
appliedRules = []
|
|
79
|
-
|
|
79
|
+
const scrubbedUrl = urltils.scrub(urlLine)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
let normalized = userNormalizer.normalize(scrubbedUrl)
|
|
82
82
|
|
|
83
83
|
if (!normalized.matched) {
|
|
84
84
|
normalized = defaultNormalizer.normalize(scrubbedUrl)
|
|
@@ -88,8 +88,8 @@ function run(opts) {
|
|
|
88
88
|
if (appliedRules.length === 0) {
|
|
89
89
|
console.log('no rules matched')
|
|
90
90
|
} else {
|
|
91
|
-
for (
|
|
92
|
-
|
|
91
|
+
for (let i = 0; i < appliedRules.length; i++) {
|
|
92
|
+
const match = appliedRules[i]
|
|
93
93
|
console.log(
|
|
94
94
|
' %s: %s => %s (rule %s)',
|
|
95
95
|
i + 1,
|
|
@@ -119,7 +119,7 @@ function run(opts) {
|
|
|
119
119
|
|
|
120
120
|
function loadDefaultNormalizer(config) {
|
|
121
121
|
// Load the normalizer.
|
|
122
|
-
|
|
122
|
+
const normalizer = new MetricNormalizer(config, 'URL')
|
|
123
123
|
|
|
124
124
|
// Add in the rules the collector would ship down.
|
|
125
125
|
normalizer.load([
|
|
@@ -159,7 +159,7 @@ function loadDefaultNormalizer(config) {
|
|
|
159
159
|
|
|
160
160
|
function loadUserNormalizer(config, rules) {
|
|
161
161
|
// Load the normalizer.
|
|
162
|
-
|
|
162
|
+
const normalizer = new MetricNormalizer(config, 'user')
|
|
163
163
|
normalizer.loadFromConfig()
|
|
164
164
|
|
|
165
165
|
if (rules && rules.length) {
|
|
@@ -173,7 +173,7 @@ function loadUserNormalizer(config, rules) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
function arrayContainsAny(array) {
|
|
176
|
-
for (
|
|
176
|
+
for (let i = 1; i < arguments.length; ++i) {
|
|
177
177
|
if (array.indexOf(arguments[i]) !== -1) {
|
|
178
178
|
return true
|
|
179
179
|
}
|
package/lib/agent.js
CHANGED
|
@@ -731,17 +731,17 @@ function _addIntrinsicAttrsFromTransaction(transaction) {
|
|
|
731
731
|
intrinsicAttributes['nr.referringPathHash'] = transaction.referringPathHash
|
|
732
732
|
}
|
|
733
733
|
if (transaction.referringTransactionGuid) {
|
|
734
|
-
|
|
734
|
+
const refId = transaction.referringTransactionGuid
|
|
735
735
|
intrinsicAttributes['nr.referringTransactionGuid'] = refId
|
|
736
736
|
}
|
|
737
|
-
|
|
737
|
+
const alternatePathHashes = transaction.alternatePathHashes()
|
|
738
738
|
if (alternatePathHashes) {
|
|
739
739
|
intrinsicAttributes['nr.alternatePathHashes'] = alternatePathHashes
|
|
740
740
|
}
|
|
741
741
|
if (transaction.baseSegment && transaction.type === 'web') {
|
|
742
|
-
|
|
742
|
+
const apdex =
|
|
743
743
|
this.config.web_transactions_apdex[transaction.getFullName()] || this.config.apdex_t
|
|
744
|
-
|
|
744
|
+
const duration = transaction.baseSegment.getDurationInMillis() / 1000
|
|
745
745
|
intrinsicAttributes['nr.apdexPerfZone'] = calculateApdexZone(duration, apdex)
|
|
746
746
|
}
|
|
747
747
|
}
|
package/lib/attributes.js
CHANGED
|
@@ -66,7 +66,7 @@ class Attributes {
|
|
|
66
66
|
get(dest) {
|
|
67
67
|
const attrs = Object.create(null)
|
|
68
68
|
// eslint-disable-next-line guard-for-in
|
|
69
|
-
for (
|
|
69
|
+
for (const key in this.attributes) {
|
|
70
70
|
const attr = this.attributes[key]
|
|
71
71
|
if (!(attr.destinations & dest)) {
|
|
72
72
|
continue
|
|
@@ -144,7 +144,7 @@ class Attributes {
|
|
|
144
144
|
* @param {object} attrs - The attributes to add.
|
|
145
145
|
*/
|
|
146
146
|
addAttributes(destinations, attrs) {
|
|
147
|
-
for (
|
|
147
|
+
for (const key in attrs) {
|
|
148
148
|
if (properties.hasOwn(attrs, key)) {
|
|
149
149
|
this.addAttribute(destinations, key, attrs[key])
|
|
150
150
|
}
|
package/lib/collector/api.js
CHANGED
|
@@ -36,7 +36,7 @@ const FAILURE_DISCARD_DATA = new Set([400, 403, 404, 405, 407, 411, 413, 414, 41
|
|
|
36
36
|
const AGENT_RUN_BEHAVIOR = CollectorResponse.AGENT_RUN_BEHAVIOR
|
|
37
37
|
|
|
38
38
|
function dumpErrors(errors, name) {
|
|
39
|
-
|
|
39
|
+
let index = 1
|
|
40
40
|
|
|
41
41
|
errors.forEach(function forEachError(error) {
|
|
42
42
|
logger.trace(error, 'Error %s during %s:', index++, name)
|
|
@@ -169,7 +169,7 @@ CollectorAPI.prototype.connect = function connect(callback) {
|
|
|
169
169
|
)
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
const backoff = BACKOFFS[Math.min(attempts, max) - 1]
|
|
173
173
|
if (backoff.warn) {
|
|
174
174
|
logger.warn('No connection has been established to New Relic after %d attempts.', attempts)
|
|
175
175
|
}
|
|
@@ -192,9 +192,9 @@ CollectorAPI.prototype.connect = function connect(callback) {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
CollectorAPI.prototype._login = function _login(callback) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
const methods = this._methods
|
|
196
|
+
const agent = this._agent
|
|
197
|
+
const self = this
|
|
198
198
|
|
|
199
199
|
const preconnectData = { high_security: agent.config.high_security }
|
|
200
200
|
if (agent.config.security_policies_token) {
|
|
@@ -217,7 +217,7 @@ CollectorAPI.prototype._login = function _login(callback) {
|
|
|
217
217
|
agent.config.host
|
|
218
218
|
)
|
|
219
219
|
} else {
|
|
220
|
-
|
|
220
|
+
const parts = res.redirect_host.split(':')
|
|
221
221
|
if (parts.length > 2) {
|
|
222
222
|
logger.error(
|
|
223
223
|
"Requesting collector from %s returned bogus result '%s'; trying default.",
|
|
@@ -241,7 +241,7 @@ CollectorAPI.prototype._login = function _login(callback) {
|
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
const policies = res.security_policies || Object.create(null)
|
|
245
245
|
|
|
246
246
|
const laspResponse = agent.config.applyLasp(agent, policies)
|
|
247
247
|
if (laspResponse.shouldShutdownRun()) {
|
|
@@ -253,8 +253,8 @@ CollectorAPI.prototype._login = function _login(callback) {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
CollectorAPI.prototype._getFacts = function _getFacts(lasp, callback) {
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
const agent = this._agent
|
|
257
|
+
const self = this
|
|
258
258
|
|
|
259
259
|
facts(agent, function getEnvDict(environmentDict) {
|
|
260
260
|
if (lasp) {
|
|
@@ -263,7 +263,7 @@ CollectorAPI.prototype._getFacts = function _getFacts(lasp, callback) {
|
|
|
263
263
|
|
|
264
264
|
// The collector really likes arrays.
|
|
265
265
|
// In fact, it kind of insists on them.
|
|
266
|
-
|
|
266
|
+
const environment = [environmentDict]
|
|
267
267
|
|
|
268
268
|
self._connect(environment, callback)
|
|
269
269
|
})
|
|
@@ -491,7 +491,7 @@ CollectorAPI.prototype.shutdown = function shutdown(callback) {
|
|
|
491
491
|
|
|
492
492
|
logger.info('Shutting down collector.')
|
|
493
493
|
|
|
494
|
-
|
|
494
|
+
const agent = this._agent
|
|
495
495
|
this._methods.shutdown.invoke(null, this._reqHeadersMap, onShutdown)
|
|
496
496
|
|
|
497
497
|
function onShutdown(error, response) {
|
|
@@ -511,7 +511,7 @@ CollectorAPI.prototype.restart = function restart(callback) {
|
|
|
511
511
|
logger.info('Restarting collector.')
|
|
512
512
|
|
|
513
513
|
this._agent.stopAggregators()
|
|
514
|
-
|
|
514
|
+
const api = this
|
|
515
515
|
this.shutdown(function reconnect() {
|
|
516
516
|
api.connect(function afterConnect() {
|
|
517
517
|
const shouldImmediatelyHarvest = false
|
package/lib/collector/facts.js
CHANGED