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/lib/db/utils.js
CHANGED
|
@@ -10,6 +10,6 @@ module.exports.extractDatabaseChangeFromUse = extractDatabaseChangeFromUse
|
|
|
10
10
|
function extractDatabaseChangeFromUse(sql) {
|
|
11
11
|
// The character ranges for this were pulled from
|
|
12
12
|
// http://dev.mysql.com/doc/refman/5.7/en/identifiers.html
|
|
13
|
-
|
|
13
|
+
const match = /^\s*use[^\w`]+([\w$_\u0080-\uFFFF]+|`[^`]+`)[\s;]*$/i.exec(sql)
|
|
14
14
|
return (match && match[1]) || null
|
|
15
15
|
}
|
package/lib/environment.js
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const a = require('async')
|
|
9
|
+
const path = require('path')
|
|
10
|
+
const fs = require('./util/unwrapped-core').fs
|
|
11
|
+
const os = require('os')
|
|
12
|
+
const logger = require('./logger').child({ component: 'environment' })
|
|
13
|
+
const stringify = require('json-stringify-safe')
|
|
14
14
|
|
|
15
15
|
// As of 1.7.0 you can no longer dynamically link v8
|
|
16
16
|
// https://github.com/nodejs/io.js/commit/d726a177ed
|
|
17
|
-
|
|
17
|
+
const remapping = {
|
|
18
18
|
node_install_npm: 'npm installed?',
|
|
19
19
|
node_install_waf: 'WAF build system installed?',
|
|
20
20
|
node_use_openssl: 'OpenSSL support?',
|
|
@@ -25,7 +25,7 @@ var remapping = {
|
|
|
25
25
|
node_use_etw: 'Event Tracing for Windows (ETW) support?'
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
let settings = Object.create(null)
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Fetches the setting of the given name, defaulting to an empty array.
|
|
@@ -112,7 +112,7 @@ function listPackages(root, packages, callback) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// Read the package and pull out the name and version of it.
|
|
115
|
-
|
|
115
|
+
const pkg = path.resolve(root, dir, 'package.json')
|
|
116
116
|
fs.readFile(pkg, function onPackageRead(err, pkgFile) {
|
|
117
117
|
_log('Read package at %s', pkg)
|
|
118
118
|
if (err) {
|
|
@@ -120,10 +120,10 @@ function listPackages(root, packages, callback) {
|
|
|
120
120
|
return cb()
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
let name = null
|
|
124
|
+
let version = null
|
|
125
125
|
try {
|
|
126
|
-
|
|
126
|
+
const pkgData = JSON.parse(pkgFile)
|
|
127
127
|
name = pkgData.name
|
|
128
128
|
version = pkgData.version
|
|
129
129
|
} catch (e) {
|
|
@@ -186,7 +186,7 @@ function listDependencies(root, children, visited, callback) {
|
|
|
186
186
|
function forEachEntry(entry, cb) {
|
|
187
187
|
_log('Checking dependencies in %s (%s)', entry, root)
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
const candidate = path.resolve(root, entry, 'node_modules')
|
|
190
190
|
fs.realpath(candidate, function realPathCb(err, realCandidate) {
|
|
191
191
|
_log('Resolved %s to real path %s', candidate, realCandidate)
|
|
192
192
|
if (err) {
|
|
@@ -230,10 +230,10 @@ function listDependencies(root, children, visited, callback) {
|
|
|
230
230
|
* appropriate names.
|
|
231
231
|
*/
|
|
232
232
|
function getLocalPackages(callback) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
const packages = []
|
|
234
|
+
const dependencies = []
|
|
235
|
+
let candidate = process.cwd()
|
|
236
|
+
const visited = Object.create(null)
|
|
237
237
|
_log('Getting local packages')
|
|
238
238
|
|
|
239
239
|
a.whilst(
|
|
@@ -242,7 +242,7 @@ function getLocalPackages(callback) {
|
|
|
242
242
|
},
|
|
243
243
|
function iterate(cb) {
|
|
244
244
|
_log('Checking for local packages in %s', candidate)
|
|
245
|
-
|
|
245
|
+
const root = path.resolve(candidate, 'node_modules')
|
|
246
246
|
a.series(
|
|
247
247
|
[
|
|
248
248
|
a.apply(listPackages, root, packages),
|
|
@@ -250,7 +250,7 @@ function getLocalPackages(callback) {
|
|
|
250
250
|
],
|
|
251
251
|
function onListComplete(err) {
|
|
252
252
|
_log('Done checking for local packages in %s', candidate)
|
|
253
|
-
|
|
253
|
+
const last = candidate
|
|
254
254
|
candidate = path.dirname(candidate)
|
|
255
255
|
if (last === candidate) {
|
|
256
256
|
candidate = null
|
|
@@ -280,8 +280,8 @@ function getLocalPackages(callback) {
|
|
|
280
280
|
* appropriate names.
|
|
281
281
|
*/
|
|
282
282
|
function getPackages(root, cb) {
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
const packages = []
|
|
284
|
+
const dependencies = []
|
|
285
285
|
_log('Getting packages from %s', root)
|
|
286
286
|
|
|
287
287
|
a.series(
|
|
@@ -307,9 +307,9 @@ function getPackages(root, cb) {
|
|
|
307
307
|
function getGlobalPackages(cb) {
|
|
308
308
|
_log('Getting global packages')
|
|
309
309
|
if (process.config && process.config.variables) {
|
|
310
|
-
|
|
310
|
+
const prefix = process.config.variables.node_prefix
|
|
311
311
|
if (prefix) {
|
|
312
|
-
|
|
312
|
+
const root = path.resolve(prefix, 'lib', 'node_modules')
|
|
313
313
|
_log('Getting global packages from %s', root)
|
|
314
314
|
return getPackages(root, cb)
|
|
315
315
|
}
|
|
@@ -328,10 +328,10 @@ function getGlobalPackages(cb) {
|
|
|
328
328
|
* @return {Array.<string[]>} Sorted list of [name, version] pairs.
|
|
329
329
|
*/
|
|
330
330
|
function flattenVersions(packages) {
|
|
331
|
-
|
|
331
|
+
const info = Object.create(null)
|
|
332
332
|
packages.forEach((pair) => {
|
|
333
|
-
|
|
334
|
-
|
|
333
|
+
const p = pair[0]
|
|
334
|
+
const v = pair[1]
|
|
335
335
|
|
|
336
336
|
if (info[p]) {
|
|
337
337
|
if (info[p].indexOf(v) < 0) {
|
|
@@ -365,10 +365,10 @@ function flattenVersions(packages) {
|
|
|
365
365
|
*/
|
|
366
366
|
function remapConfigSettings() {
|
|
367
367
|
if (process.config && process.config.variables) {
|
|
368
|
-
|
|
368
|
+
const variables = process.config.variables
|
|
369
369
|
Object.keys(variables).forEach((key) => {
|
|
370
370
|
if (remapping[key]) {
|
|
371
|
-
|
|
371
|
+
let value = variables[key]
|
|
372
372
|
|
|
373
373
|
if (value === true || value === 1) {
|
|
374
374
|
value = 'yes'
|
|
@@ -385,13 +385,13 @@ function remapConfigSettings() {
|
|
|
385
385
|
|
|
386
386
|
function getOtherPackages(callback) {
|
|
387
387
|
_log('Getting other packages')
|
|
388
|
-
|
|
388
|
+
const other = { packages: [], dependencies: [] }
|
|
389
389
|
|
|
390
390
|
if (!process.env.NODE_PATH) {
|
|
391
391
|
return callback(null, other)
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
-
|
|
394
|
+
let paths
|
|
395
395
|
if (process.platform === 'win32') {
|
|
396
396
|
// why. WHY.
|
|
397
397
|
paths = process.env.NODE_PATH.split(';')
|
|
@@ -425,7 +425,7 @@ function getOtherPackages(callback) {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
function getHomePackages(cb) {
|
|
428
|
-
|
|
428
|
+
let homeDir = null
|
|
429
429
|
if (process.platform === 'win32') {
|
|
430
430
|
if (process.env.USERDIR) {
|
|
431
431
|
homeDir = process.env.USERDIR
|
|
@@ -477,11 +477,11 @@ function findPackages(cb) {
|
|
|
477
477
|
return cb(err)
|
|
478
478
|
}
|
|
479
479
|
|
|
480
|
-
|
|
480
|
+
const packages = data.local.packages
|
|
481
481
|
packages.push.apply(packages, data.global.packages)
|
|
482
482
|
packages.push.apply(packages, data.other.packages)
|
|
483
483
|
|
|
484
|
-
|
|
484
|
+
const dependencies = data.local.dependencies
|
|
485
485
|
dependencies.push.apply(dependencies, data.global.dependencies)
|
|
486
486
|
dependencies.push.apply(dependencies, data.other.dependencies)
|
|
487
487
|
|
|
@@ -504,12 +504,12 @@ function findPackages(cb) {
|
|
|
504
504
|
}
|
|
505
505
|
|
|
506
506
|
function time(fn) {
|
|
507
|
-
|
|
507
|
+
const name = fn.name
|
|
508
508
|
return function timeWrapper(cb) {
|
|
509
|
-
|
|
509
|
+
const start = Date.now()
|
|
510
510
|
logger.trace('Starting %s', name)
|
|
511
511
|
return fn(function wrappedCb() {
|
|
512
|
-
|
|
512
|
+
const end = Date.now()
|
|
513
513
|
logger.trace('Finished %s in %dms', name, end - start)
|
|
514
514
|
cb.apply(this, arguments)
|
|
515
515
|
})
|
|
@@ -533,9 +533,9 @@ function gatherEnv() {
|
|
|
533
533
|
|
|
534
534
|
function refreshSyncOnly() {
|
|
535
535
|
// gather persisted settings
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
536
|
+
const framework = getSetting('Framework')
|
|
537
|
+
const dispatcher = getSetting('Dispatcher')
|
|
538
|
+
const dispatcherVersion = getSetting('Dispatcher Version')
|
|
539
539
|
|
|
540
540
|
// clearing and rebuilding a global variable
|
|
541
541
|
settings = Object.create(null)
|
|
@@ -569,8 +569,8 @@ function refresh(cb) {
|
|
|
569
569
|
_log('Refreshing environment settings')
|
|
570
570
|
refreshSyncOnly()
|
|
571
571
|
|
|
572
|
-
|
|
573
|
-
|
|
572
|
+
const packages = getSetting('Packages')
|
|
573
|
+
const dependencies = getSetting('Dependencies')
|
|
574
574
|
|
|
575
575
|
if (packages.length && dependencies.length) {
|
|
576
576
|
settings.Packages = packages
|
|
@@ -599,7 +599,7 @@ function getJSON(cb) {
|
|
|
599
599
|
return
|
|
600
600
|
}
|
|
601
601
|
|
|
602
|
-
|
|
602
|
+
const items = []
|
|
603
603
|
Object.keys(settings).forEach(function settingKeysForEach(key) {
|
|
604
604
|
settings[key].forEach(function settingsValuesForEach(setting) {
|
|
605
605
|
items.push([key, setting])
|
|
@@ -613,7 +613,7 @@ function getJSON(cb) {
|
|
|
613
613
|
// At startup, do the synchronous environment scanning stuff.
|
|
614
614
|
refreshSyncOnly()
|
|
615
615
|
|
|
616
|
-
|
|
616
|
+
let userSetDispatcher = false
|
|
617
617
|
module.exports = {
|
|
618
618
|
setFramework: function setFramework(framework) {
|
|
619
619
|
addSetting('Framework', framework)
|
|
@@ -82,7 +82,7 @@ class ErrorCollector {
|
|
|
82
82
|
this.seenObjectsByTransaction[txId] = new WeakSet()
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
const seenObjects = this.seenObjectsByTransaction[txId]
|
|
86
86
|
if (seenObjects.has(exception)) {
|
|
87
87
|
return true
|
|
88
88
|
}
|
|
@@ -97,7 +97,7 @@ class ErrorCollector {
|
|
|
97
97
|
this.seenStringsByTransaction[txId] = Object.create(null)
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
const seenStrings = this.seenStringsByTransaction[txId]
|
|
101
101
|
if (seenStrings[exception]) {
|
|
102
102
|
return true
|
|
103
103
|
}
|
|
@@ -50,7 +50,7 @@ class ErrorTraceAggregator extends TraceAggregator {
|
|
|
50
50
|
const len = Math.min(errors.length, this.limit - this.errors.length)
|
|
51
51
|
logger.warn('Merging %s (of %s) errors for next delivery.', len, errors.length)
|
|
52
52
|
|
|
53
|
-
for (
|
|
53
|
+
for (let i = 0; i < len; i++) {
|
|
54
54
|
this.errors.push(errors[i])
|
|
55
55
|
}
|
|
56
56
|
}
|
package/lib/errors/helper.js
CHANGED
|
@@ -37,7 +37,7 @@ module.exports = {
|
|
|
37
37
|
return false
|
|
38
38
|
},
|
|
39
39
|
isExpectedException: function isExpectedException(transaction, exception, config, urltils) {
|
|
40
|
-
|
|
40
|
+
const { type, message } = this.extractErrorInformation(transaction, exception, config, urltils)
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
43
|
this.isExpectedErrorClass(config, type) || this.isExpectedErrorMessage(config, type, message)
|
|
@@ -93,7 +93,7 @@ module.exports = {
|
|
|
93
93
|
|
|
94
94
|
shouldIgnoreError: function shouldIgnoreError(transaction, error, config) {
|
|
95
95
|
// extract _just_ the error information, not transaction stuff
|
|
96
|
-
|
|
96
|
+
const errorInfo = this.extractErrorInformation(null, error, config, null)
|
|
97
97
|
|
|
98
98
|
return (
|
|
99
99
|
this.shouldIgnoreErrorClass(errorInfo, config) ||
|
|
@@ -118,7 +118,7 @@ module.exports = {
|
|
|
118
118
|
},
|
|
119
119
|
|
|
120
120
|
shouldIgnoreErrorMessage: function shouldIgnoreErrorMessage(errorInfo, config) {
|
|
121
|
-
|
|
121
|
+
const configIgnoreMessages = config.error_collector.ignore_messages[errorInfo.type]
|
|
122
122
|
if (!configIgnoreMessages) {
|
|
123
123
|
return false
|
|
124
124
|
}
|
package/lib/errors/index.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const DESTINATIONS = require('../config/attribute-filter').DESTINATIONS
|
|
9
|
+
const NAMES = require('../metrics/names')
|
|
10
|
+
const props = require('../util/properties')
|
|
11
|
+
const urltils = require('../util/urltils')
|
|
12
12
|
const errorHelper = require('../errors/helper')
|
|
13
13
|
|
|
14
14
|
class Exception {
|
|
@@ -51,14 +51,14 @@ class Exception {
|
|
|
51
51
|
*/
|
|
52
52
|
function createError(transaction, exception, config) {
|
|
53
53
|
const error = exception.error
|
|
54
|
-
|
|
54
|
+
const { name, message, type } = errorHelper.extractErrorInformation(
|
|
55
55
|
transaction,
|
|
56
56
|
error,
|
|
57
57
|
config,
|
|
58
58
|
urltils
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
const params = {
|
|
62
62
|
userAttributes: Object.create(null),
|
|
63
63
|
agentAttributes: Object.create(null),
|
|
64
64
|
intrinsics: Object.create(null)
|
|
@@ -83,7 +83,7 @@ function createError(transaction, exception, config) {
|
|
|
83
83
|
|
|
84
84
|
const customAttributes = exception.customAttributes
|
|
85
85
|
if (!config.high_security && config.api.custom_attributes_enabled && customAttributes) {
|
|
86
|
-
for (
|
|
86
|
+
for (const key in customAttributes) {
|
|
87
87
|
if (props.hasOwn(customAttributes, key)) {
|
|
88
88
|
const dest = config.attributeFilter.filterTransaction(DESTINATIONS.ERROR_EVENT, key)
|
|
89
89
|
if (dest & DESTINATIONS.ERROR_EVENT) {
|
|
@@ -106,7 +106,7 @@ function createError(transaction, exception, config) {
|
|
|
106
106
|
params.intrinsics['error.expected'] = true
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
const res = [0, name, message, type, params]
|
|
110
110
|
if (transaction) {
|
|
111
111
|
res.transaction = transaction.id
|
|
112
112
|
}
|
|
@@ -118,11 +118,11 @@ function createError(transaction, exception, config) {
|
|
|
118
118
|
* The error parameter is an output of the createError() function for a given exception.
|
|
119
119
|
*/
|
|
120
120
|
function createEvent(transaction, error, timestamp, config) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
const message = error[2]
|
|
122
|
+
const errorClass = error[3]
|
|
123
|
+
const errorParams = error[4]
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
const intrinsicAttributes = _getErrorEventIntrinsicAttrs(
|
|
126
126
|
transaction,
|
|
127
127
|
errorClass,
|
|
128
128
|
message,
|
|
@@ -133,10 +133,10 @@ function createEvent(transaction, error, timestamp, config) {
|
|
|
133
133
|
|
|
134
134
|
// the error structure created by createError() already performs filtering of custom
|
|
135
135
|
// and agent attributes, so it is ok to just copy them
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const userAttributes = Object.assign(Object.create(null), errorParams.userAttributes)
|
|
137
|
+
const agentAttributes = Object.assign(Object.create(null), errorParams.agentAttributes)
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
const errorEvent = [intrinsicAttributes, userAttributes, agentAttributes]
|
|
140
140
|
|
|
141
141
|
return errorEvent
|
|
142
142
|
}
|
|
@@ -148,7 +148,7 @@ function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, expected
|
|
|
148
148
|
timestamp = timestamp / 1000
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
const attributes = {
|
|
152
152
|
'type': 'TransactionError',
|
|
153
153
|
'error.class': errorClass,
|
|
154
154
|
'error.message': conf.high_security ? '' : message,
|
|
@@ -160,7 +160,7 @@ function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, expected
|
|
|
160
160
|
attributes.transactionName = transaction.getFullName()
|
|
161
161
|
attributes.duration = transaction.timer.getDurationInMillis() / 1000
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
let metric = transaction.metrics.getMetric(NAMES.QUEUETIME)
|
|
164
164
|
if (metric) {
|
|
165
165
|
attributes.queueDuration = metric.total
|
|
166
166
|
}
|
package/lib/feature_flags.js
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
// unreleased flags gating an active feature
|
|
9
9
|
exports.prerelease = {
|
|
10
|
-
express5: false,
|
|
11
10
|
await_support: true,
|
|
12
|
-
promise_segments: false,
|
|
13
|
-
reverse_naming_rules: false,
|
|
14
|
-
fastify_instrumentation: false,
|
|
15
11
|
certificate_bundle: false,
|
|
12
|
+
express5: false,
|
|
16
13
|
new_promise_tracking: false,
|
|
14
|
+
promise_segments: false,
|
|
15
|
+
reverse_naming_rules: false,
|
|
16
|
+
undici_instrumentation: false,
|
|
17
|
+
undici_async_tracking: true,
|
|
17
18
|
unresolved_promise_cleanup: true
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -29,7 +30,8 @@ exports.released = [
|
|
|
29
30
|
'serverless_mode',
|
|
30
31
|
'send_request_uri_attribute',
|
|
31
32
|
'synthetics',
|
|
32
|
-
'dt_format_w3c'
|
|
33
|
+
'dt_format_w3c',
|
|
34
|
+
'fastify_instrumentation'
|
|
33
35
|
]
|
|
34
36
|
|
|
35
37
|
// flags that are no longer used for unreleased features
|
package/lib/header-attributes.js
CHANGED
|
@@ -111,25 +111,25 @@ function _collectHeaders(headers, nameMap, prefix, transaction) {
|
|
|
111
111
|
}, {})
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
const headerKeys = !transaction.agent.config.allow_all_headers
|
|
115
115
|
? COLLECTED_REQUEST_HEADERS
|
|
116
116
|
: Object.keys(headers)
|
|
117
117
|
|
|
118
118
|
const segment = transaction.agent.tracer.getSegment()
|
|
119
119
|
|
|
120
|
-
for (
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
for (let i = 0; i < headerKeys.length; i++) {
|
|
121
|
+
const headerKey = headerKeys[i]
|
|
122
|
+
let header = headers[headerKey]
|
|
123
123
|
if (header !== undefined) {
|
|
124
124
|
// If any more processing of the headers is required consider refactoring this.
|
|
125
125
|
if (headerKey === 'referer' && typeof header === 'string') {
|
|
126
|
-
|
|
126
|
+
const queryParamIndex = header.indexOf('?')
|
|
127
127
|
if (queryParamIndex !== -1) {
|
|
128
128
|
header = header.substring(0, queryParamIndex)
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
const attributeName = nameMap[headerKey] || prefix + _headerToCamelCase(headerKey)
|
|
133
133
|
transaction.trace.attributes.addAttribute(DESTS.TRANS_COMMON, attributeName, header)
|
|
134
134
|
|
|
135
135
|
segment.addSpanAttribute(attributeName, header)
|
package/lib/header-processing.js
CHANGED
|
@@ -65,7 +65,7 @@ function convertUnit(time) {
|
|
|
65
65
|
* @param {*} headers
|
|
66
66
|
*/
|
|
67
67
|
function getContentLengthFromHeaders(headers) {
|
|
68
|
-
|
|
68
|
+
const contentLength = -1
|
|
69
69
|
for (const [headerName, headerValue] of Object.entries(headers)) {
|
|
70
70
|
if (CONTENT_LENGTH_REGEX.test(headerName)) {
|
|
71
71
|
return headerValue
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const url = require('url')
|
|
9
9
|
|
|
10
10
|
// TODO: Make this an external module.
|
|
11
11
|
// var newrelic = require('newrelic')
|
|
@@ -45,7 +45,7 @@ module.exports.selfRegister = function selfRegister(shimmer) {
|
|
|
45
45
|
module.exports.instrumentPromiseAPI = instrumentChannelAPI
|
|
46
46
|
module.exports.instrumentCallbackAPI = instrumentCallbackAPI
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const CHANNEL_METHODS = [
|
|
49
49
|
'close',
|
|
50
50
|
'open',
|
|
51
51
|
'assertQueue',
|
|
@@ -63,7 +63,7 @@ var CHANNEL_METHODS = [
|
|
|
63
63
|
'recover'
|
|
64
64
|
]
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
const TEMP_RE = /^amq\./
|
|
67
67
|
|
|
68
68
|
function instrumentChannelAPI(shim, amqp) {
|
|
69
69
|
instrumentAMQP(shim, amqp, true)
|
|
@@ -88,8 +88,8 @@ function instrumentAMQP(shim, amqp, promiseMode) {
|
|
|
88
88
|
shim.setLibrary(shim.RABBITMQ)
|
|
89
89
|
|
|
90
90
|
shim.record(amqp, 'connect', function recordConnect(shim, connect, name, args) {
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
let connArgs = args[0]
|
|
92
|
+
let params = null
|
|
93
93
|
|
|
94
94
|
if (shim.isString(connArgs)) {
|
|
95
95
|
connArgs = url.parse(connArgs)
|
|
@@ -114,13 +114,13 @@ function instrumentAMQP(shim, amqp, promiseMode) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
function wrapChannel(shim) {
|
|
117
|
-
|
|
117
|
+
const libChannel = shim.require('./lib/channel')
|
|
118
118
|
if (!libChannel || !libChannel.Channel || !libChannel.Channel.prototype) {
|
|
119
119
|
shim.logger.debug('Could not get Channel class to instrument.')
|
|
120
120
|
return
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
const proto = libChannel.Channel.prototype
|
|
124
124
|
if (shim.isWrapped(proto.sendMessage)) {
|
|
125
125
|
shim.logger.trace('Channel already instrumented.')
|
|
126
126
|
return
|
|
@@ -133,15 +133,15 @@ function wrapChannel(shim) {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
return function wrappedSendOrEnqueue() {
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const segment = shim.getSegment()
|
|
137
|
+
const cb = arguments[arguments.length - 1]
|
|
138
138
|
if (!shim.isFunction(cb) || !segment) {
|
|
139
139
|
shim.logger.debug({ cb: !!cb, segment: !!segment }, 'Not binding sendOrEnqueue callback')
|
|
140
140
|
return fn.apply(this, arguments)
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
shim.logger.trace('Binding sendOrEnqueue callback to %s', segment.name)
|
|
144
|
-
|
|
144
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
145
145
|
args[args.length - 1] = shim.bindSegment(cb, segment)
|
|
146
146
|
return fn.apply(this, args)
|
|
147
147
|
}
|
|
@@ -170,11 +170,11 @@ function wrapChannel(shim) {
|
|
|
170
170
|
|
|
171
171
|
shim.recordProduce(proto, 'sendMessage', recordSendMessage)
|
|
172
172
|
function recordSendMessage(shim, fn, n, args) {
|
|
173
|
-
|
|
173
|
+
const fields = args[0]
|
|
174
174
|
if (!fields) {
|
|
175
175
|
return null
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
const isDefault = fields.exchange === ''
|
|
178
178
|
let exchange = 'Default'
|
|
179
179
|
if (!isDefault) {
|
|
180
180
|
exchange = TEMP_RE.test(fields.exchange) ? null : fields.exchange
|
|
@@ -205,12 +205,12 @@ function getParameters(parameters, fields) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
function wrapPromiseChannel(shim) {
|
|
208
|
-
|
|
208
|
+
const libPModel = shim.require('./lib/channel_model')
|
|
209
209
|
if (!libPModel || !libPModel.Channel || !libPModel.Channel.prototype) {
|
|
210
210
|
shim.logger.debug('Could not get promise model Channel to instrument')
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
const proto = libPModel.Channel.prototype
|
|
214
214
|
if (shim.isWrapped(proto.consume)) {
|
|
215
215
|
shim.logger.trace('Promise model already isntrumented.')
|
|
216
216
|
return
|
|
@@ -231,11 +231,11 @@ function wrapPromiseChannel(shim) {
|
|
|
231
231
|
shim.logger.trace('No results from consume.')
|
|
232
232
|
return null
|
|
233
233
|
}
|
|
234
|
-
|
|
234
|
+
const parameters = Object.create(null)
|
|
235
235
|
getParameters(parameters, message.fields)
|
|
236
236
|
getParameters(parameters, message.properties)
|
|
237
237
|
|
|
238
|
-
|
|
238
|
+
let headers = null
|
|
239
239
|
if (message.properties && message.properties.headers) {
|
|
240
240
|
headers = message.properties.headers
|
|
241
241
|
}
|
|
@@ -245,7 +245,7 @@ function wrapPromiseChannel(shim) {
|
|
|
245
245
|
})
|
|
246
246
|
|
|
247
247
|
shim.recordPurgeQueue(proto, 'purgeQueue', function recordPurge(shim, fn, name, args) {
|
|
248
|
-
|
|
248
|
+
let queue = args[0] || null
|
|
249
249
|
if (TEMP_RE.test(queue)) {
|
|
250
250
|
queue = null
|
|
251
251
|
}
|
|
@@ -263,13 +263,13 @@ function wrapPromiseChannel(shim) {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
function wrapCallbackChannel(shim) {
|
|
266
|
-
|
|
266
|
+
const libCbModel = shim.require('./lib/callback_model')
|
|
267
267
|
if (!libCbModel || !libCbModel.Channel || !libCbModel.Channel.prototype) {
|
|
268
268
|
shim.logger.debug('Could not get callback model Channel to instrument')
|
|
269
269
|
return
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
|
|
272
|
+
const proto = libCbModel.Channel.prototype
|
|
273
273
|
if (shim.isWrapped(proto.consume)) {
|
|
274
274
|
return
|
|
275
275
|
}
|
|
@@ -309,16 +309,16 @@ function wrapCallbackChannel(shim) {
|
|
|
309
309
|
destinationName: shim.FIRST,
|
|
310
310
|
callback: shim.LAST,
|
|
311
311
|
messageHandler: function handleConsumedMessage(shim, fn, name, args) {
|
|
312
|
-
|
|
312
|
+
const message = args[1]
|
|
313
313
|
if (!message) {
|
|
314
314
|
shim.logger.trace('No results from consume.')
|
|
315
315
|
return null
|
|
316
316
|
}
|
|
317
|
-
|
|
317
|
+
const parameters = Object.create(null)
|
|
318
318
|
getParameters(parameters, message.fields)
|
|
319
319
|
getParameters(parameters, message.properties)
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
let headers = null
|
|
322
322
|
if (message.properties && message.properties.headers) {
|
|
323
323
|
headers = message.properties.headers
|
|
324
324
|
}
|
|
@@ -328,7 +328,7 @@ function wrapCallbackChannel(shim) {
|
|
|
328
328
|
})
|
|
329
329
|
|
|
330
330
|
shim.recordPurgeQueue(proto, 'purgeQueue', function recordPurge(shim, fn, name, args) {
|
|
331
|
-
|
|
331
|
+
let queue = args[0]
|
|
332
332
|
if (TEMP_RE.test(queue)) {
|
|
333
333
|
queue = null
|
|
334
334
|
}
|
|
@@ -347,14 +347,14 @@ function wrapCallbackChannel(shim) {
|
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
function describeMessage(shim, consumer, name, args) {
|
|
350
|
-
|
|
350
|
+
const message = args[0]
|
|
351
351
|
if (!message || !message.properties) {
|
|
352
352
|
shim.logger.debug({ message: message }, 'Failed to find message in consume arguments.')
|
|
353
353
|
return null
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
let exchangeName = message.fields.exchange
|
|
357
|
+
const parameters = getParameters(Object.create(null), message.fields)
|
|
358
358
|
getParameters(parameters, message.properties)
|
|
359
359
|
|
|
360
360
|
if (!exchangeName) {
|
|
@@ -93,16 +93,16 @@ module.exports = function initialize(agent, bluebird, moduleName, shim) {
|
|
|
93
93
|
shim.wrap(bluebird.Promise, 'getNewLibraryCopy', function wrapNewCopy(shim, original) {
|
|
94
94
|
return function wrappedNewCopy() {
|
|
95
95
|
shim.logger.trace('Instrumenting new library copy...')
|
|
96
|
-
|
|
96
|
+
const copy = original.apply(this, arguments)
|
|
97
97
|
module.exports(agent, copy, moduleName, shim)
|
|
98
98
|
return copy
|
|
99
99
|
}
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
// Need to copy over `coroutine.addYieldHandler`
|
|
103
|
-
|
|
103
|
+
const coroutine = Promise && Promise.coroutine
|
|
104
104
|
if (shim.isWrapped(coroutine)) {
|
|
105
|
-
|
|
105
|
+
const original = shim.getOriginal(coroutine)
|
|
106
106
|
coroutine.addYieldHandler = original && original.addYieldHandler
|
|
107
107
|
}
|
|
108
108
|
}
|