newrelic 9.5.0 → 9.7.0
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 +14 -0
- package/api.js +2 -0
- package/bin/test-naming-rules.js +1 -1
- package/esm-loader.mjs +1 -3
- package/index.js +6 -5
- package/lib/adaptive-sampler.js +1 -2
- package/lib/agent.js +2 -0
- package/lib/aggregators/event-aggregator.js +2 -2
- package/lib/attributes.js +2 -4
- package/lib/collector/api.js +20 -12
- package/lib/collector/facts.js +1 -3
- package/lib/collector/parse-response.js +3 -1
- package/lib/collector/remote-method.js +10 -10
- package/lib/config/attribute-filter.js +14 -16
- package/lib/config/default.js +544 -286
- package/lib/config/formatters.js +108 -0
- package/lib/config/harvest-config-validator.js +3 -5
- package/lib/config/index.js +74 -93
- package/lib/environment.js +6 -5
- package/lib/errors/error-collector.js +6 -3
- package/lib/errors/helper.js +10 -18
- package/lib/errors/index.js +12 -6
- 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 +231 -1
- package/lib/instrumentation/{vision.js → @hapi/vision.js} +0 -0
- package/lib/instrumentation/@node-redis/client.js +2 -0
- package/lib/instrumentation/amqplib.js +2 -0
- package/lib/instrumentation/core/async_hooks.js +3 -4
- package/lib/instrumentation/core/globals.js +12 -10
- package/lib/instrumentation/core/http-outbound.js +17 -17
- package/lib/instrumentation/core/http.js +16 -27
- package/lib/instrumentation/core/timers.js +5 -1
- 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 +3 -0
- package/lib/instrumentation/mongodb/v2-mongo.js +6 -3
- package/lib/instrumentation/mongodb.js +1 -1
- package/lib/instrumentation/mysql/mysql.js +6 -5
- package/lib/instrumentation/nr-winston-transport.js +3 -4
- package/lib/instrumentation/promise.js +22 -18
- package/lib/instrumentation/redis.js +2 -0
- package/lib/instrumentation/undici.js +12 -15
- 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/constants.js +1 -16
- package/lib/shim/datastore-shim.js +24 -105
- package/lib/shim/index.js +7 -0
- package/lib/shim/message-shim.js +2 -0
- package/lib/shim/promise-shim.js +66 -59
- package/lib/shim/shim.js +44 -89
- package/lib/shim/transaction-shim.js +1 -1
- package/lib/shim/webframework-shim.js +4 -8
- package/lib/shimmer.js +29 -23
- 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 +26 -0
- package/lib/system-info.js +4 -7
- 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 +35 -43
- package/lib/transaction/transaction-event-aggregator.js +1 -3
- package/lib/util/arity.js +4 -9
- package/lib/util/attribute-types.js +1 -2
- package/lib/util/byte-limit.js +1 -3
- package/lib/util/cat.js +16 -13
- package/lib/util/codec.js +0 -2
- package/lib/util/copy.js +1 -2
- package/lib/util/deep-equal.js +7 -0
- 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 -51
- package/lib/util/stream-sink.js +2 -0
- package/lib/util/urltils.js +4 -10
- package/newrelic.js +1 -1
- package/package.json +2 -1
- package/lib/config/env.js +0 -294
- package/lib/instrumentation/hapi/hapi.js +0 -207
- package/lib/instrumentation/hapi/shared.js +0 -28
- package/lib/instrumentation/hapi.js +0 -254
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const dbutils = require('../../db/utils')
|
|
9
9
|
const properties = require('../../util/properties')
|
|
10
|
+
const symbols = require('../../symbols')
|
|
10
11
|
|
|
11
12
|
exports.callbackInitialize = function callbackInitialize(shim, mysql) {
|
|
12
13
|
shim.setDatastore(shim.MYSQL)
|
|
@@ -17,7 +18,7 @@ exports.callbackInitialize = function callbackInitialize(shim, mysql) {
|
|
|
17
18
|
shim.logger.debug('Wrapping Connection#query')
|
|
18
19
|
if (wrapQueryable(shim, connection, false)) {
|
|
19
20
|
const connProto = Object.getPrototypeOf(connection)
|
|
20
|
-
|
|
21
|
+
connProto[symbols.storeDatabase] = true
|
|
21
22
|
shim.unwrap(mysql, 'createConnection')
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -133,7 +134,7 @@ function wrapQueryable(shim, queryable, isPoolQuery) {
|
|
|
133
134
|
describe = describePoolQuery
|
|
134
135
|
} else {
|
|
135
136
|
describe = describeQuery
|
|
136
|
-
|
|
137
|
+
proto[symbols.databaseName] = null
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
shim.recordQuery(proto, 'query', describe)
|
|
@@ -214,7 +215,7 @@ function getInstanceParameters(shim, queryable, query) {
|
|
|
214
215
|
const parameters = { host: null, port_path_or_id: null, database_name: null }
|
|
215
216
|
let conf = queryable.config
|
|
216
217
|
conf = (conf && conf.connectionConfig) || conf
|
|
217
|
-
let databaseName = queryable.
|
|
218
|
+
let databaseName = queryable[symbols.databaseName] || null
|
|
218
219
|
if (conf) {
|
|
219
220
|
parameters.database_name = databaseName = databaseName || conf.database
|
|
220
221
|
|
|
@@ -235,10 +236,10 @@ function getInstanceParameters(shim, queryable, query) {
|
|
|
235
236
|
}
|
|
236
237
|
|
|
237
238
|
function storeDatabaseName(shim, queryable, query) {
|
|
238
|
-
if (queryable.
|
|
239
|
+
if (queryable[symbols.storeDatabase]) {
|
|
239
240
|
const databaseName = dbutils.extractDatabaseChangeFromUse(query)
|
|
240
241
|
if (databaseName) {
|
|
241
|
-
|
|
242
|
+
queryable[symbols.databaseName] = databaseName
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
245
|
}
|
|
@@ -36,7 +36,7 @@ class NrTransport extends TransportStream {
|
|
|
36
36
|
*/
|
|
37
37
|
log(logLine, callback) {
|
|
38
38
|
const metadata = this.agent.getLinkingMetadata()
|
|
39
|
-
const formattedLine = reformatLogLine(logLine, metadata
|
|
39
|
+
const formattedLine = reformatLogLine(logLine, metadata)
|
|
40
40
|
this.agent.logs.add(formattedLine)
|
|
41
41
|
callback()
|
|
42
42
|
}
|
|
@@ -52,10 +52,9 @@ module.exports = NrTransport
|
|
|
52
52
|
*
|
|
53
53
|
* @param {object} logLine log line
|
|
54
54
|
* @param {object} metadata linking metadata
|
|
55
|
-
* @param {object} agent NR agent
|
|
56
55
|
* @returns {object} copy of log line with NR linking metadata
|
|
57
56
|
*/
|
|
58
|
-
function reformatLogLine(logLine, metadata
|
|
57
|
+
function reformatLogLine(logLine, metadata) {
|
|
59
58
|
// Add the metadata to a copy of the logLine
|
|
60
59
|
const formattedLine = Object.assign({}, logLine, metadata)
|
|
61
60
|
|
|
@@ -63,7 +62,7 @@ function reformatLogLine(logLine, metadata, agent) {
|
|
|
63
62
|
reformatError(formattedLine)
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
reformatTimestamp(formattedLine
|
|
65
|
+
reformatTimestamp(formattedLine)
|
|
67
66
|
|
|
68
67
|
return formattedLine
|
|
69
68
|
}
|
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
/* eslint sonarjs/cognitive-complexity: ["error", 101] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
+
|
|
8
10
|
const util = require('util')
|
|
9
11
|
const properties = require('../util/properties')
|
|
10
12
|
const shimmer = require('../shimmer')
|
|
13
|
+
const symbols = require('../symbols')
|
|
14
|
+
const ANONYMOUS = '<anonymous>'
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* @namespace Library.Spec
|
|
@@ -143,7 +147,7 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
143
147
|
cnstrctArgs.unshift(Promise) // `unshift` === `push_front`
|
|
144
148
|
promise = new (Promise.bind.apply(Promise, cnstrctArgs))()
|
|
145
149
|
} else {
|
|
146
|
-
const segmentName = 'Promise ' + (executor.name ||
|
|
150
|
+
const segmentName = 'Promise ' + (executor.name || ANONYMOUS)
|
|
147
151
|
const context = {
|
|
148
152
|
promise: null,
|
|
149
153
|
self: null,
|
|
@@ -213,13 +217,13 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
213
217
|
self: null,
|
|
214
218
|
args: null
|
|
215
219
|
}
|
|
216
|
-
if (!this.
|
|
217
|
-
const segmentName = 'Promise ' + executor.name ||
|
|
220
|
+
if (!this[symbols.context]) {
|
|
221
|
+
const segmentName = 'Promise ' + executor.name || ANONYMOUS
|
|
218
222
|
const segment = _createSegment(segmentName)
|
|
219
223
|
Contextualizer.link(null, this, segment, spec.useFinally)
|
|
220
224
|
}
|
|
221
225
|
const args = [].slice.call(arguments)
|
|
222
|
-
args[0] = wrapExecutorContext(context
|
|
226
|
+
args[0] = wrapExecutorContext(context)
|
|
223
227
|
const ret = caller.apply(this, args)
|
|
224
228
|
|
|
225
229
|
// Bluebird catches executor errors and auto-rejects when it catches them,
|
|
@@ -256,8 +260,8 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
256
260
|
function wrapResolver(context, fn) {
|
|
257
261
|
return function wrappedResolveReject(val) {
|
|
258
262
|
const promise = context.promise
|
|
259
|
-
if (promise && promise.
|
|
260
|
-
promise.
|
|
263
|
+
if (promise && promise[symbols.context]) {
|
|
264
|
+
promise[symbols.context].getSegment().touch()
|
|
261
265
|
}
|
|
262
266
|
fn(val)
|
|
263
267
|
}
|
|
@@ -333,15 +337,15 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
333
337
|
}
|
|
334
338
|
|
|
335
339
|
return function __NR_wrappedThenHandler() {
|
|
336
|
-
if (!next || !next.
|
|
340
|
+
if (!next || !next[symbols.context]) {
|
|
337
341
|
return fn.apply(this, arguments)
|
|
338
342
|
}
|
|
339
343
|
|
|
340
|
-
let promSegment = next.
|
|
341
|
-
const segmentName = segmentNamePrefix + (fn.name ||
|
|
344
|
+
let promSegment = next[symbols.context].getSegment()
|
|
345
|
+
const segmentName = segmentNamePrefix + (fn.name || ANONYMOUS)
|
|
342
346
|
const segment = _createSegment(segmentName, promSegment)
|
|
343
347
|
if (segment && segment !== promSegment) {
|
|
344
|
-
next.
|
|
348
|
+
next[symbols.context].setSegment(segment)
|
|
345
349
|
promSegment = segment
|
|
346
350
|
}
|
|
347
351
|
|
|
@@ -350,7 +354,7 @@ module.exports = function initialize(agent, library, spec) {
|
|
|
350
354
|
ret = agent.tracer.bindFunction(fn, promSegment, true).apply(this, arguments)
|
|
351
355
|
} finally {
|
|
352
356
|
if (ret && typeof ret.then === 'function') {
|
|
353
|
-
ret = next.
|
|
357
|
+
ret = next[symbols.context].continue(ret)
|
|
354
358
|
}
|
|
355
359
|
}
|
|
356
360
|
return ret
|
|
@@ -453,9 +457,9 @@ function Contextualizer(idx, context, useFinally) {
|
|
|
453
457
|
module.exports.Contextualizer = Contextualizer
|
|
454
458
|
|
|
455
459
|
Contextualizer.link = function link(prev, next, segment, useFinally) {
|
|
456
|
-
let ctxlzr = prev && prev.
|
|
460
|
+
let ctxlzr = prev && prev[symbols.context]
|
|
457
461
|
if (ctxlzr && !ctxlzr.isActive()) {
|
|
458
|
-
ctxlzr = prev.
|
|
462
|
+
ctxlzr = prev[symbols.context] = null
|
|
459
463
|
}
|
|
460
464
|
|
|
461
465
|
if (ctxlzr) {
|
|
@@ -497,17 +501,17 @@ Contextualizer.link = function link(prev, next, segment, useFinally) {
|
|
|
497
501
|
const idx = ctxlzr.child === false ? ctxlzr.context.branch() : ctxlzr.idx
|
|
498
502
|
|
|
499
503
|
// Create a new context for this next promise.
|
|
500
|
-
next.
|
|
501
|
-
next.
|
|
504
|
+
next[symbols.context] = new Contextualizer(idx, ctxlzr.context, ctxlzr.useFinally)
|
|
505
|
+
next[symbols.context].parentIdx = ctxlzr.idx
|
|
502
506
|
|
|
503
507
|
// If this was our first child, remember it in case we have a 2nd.
|
|
504
508
|
if (ctxlzr.child === null) {
|
|
505
|
-
ctxlzr.child = next.
|
|
509
|
+
ctxlzr.child = next[symbols.context]
|
|
506
510
|
}
|
|
507
511
|
} else if (segment) {
|
|
508
512
|
// This next promise is the root of a chain. Either there was no previous
|
|
509
513
|
// promise or the promise was created out of context.
|
|
510
|
-
next.
|
|
514
|
+
next[symbols.context] = new Contextualizer(0, new Context(segment), useFinally)
|
|
511
515
|
}
|
|
512
516
|
}
|
|
513
517
|
|
|
@@ -538,7 +542,7 @@ Contextualizer.prototype.toJSON = function toJSON() {
|
|
|
538
542
|
|
|
539
543
|
Contextualizer.prototype.continue = function continueContext(prom) {
|
|
540
544
|
const self = this
|
|
541
|
-
const nextContext = prom.
|
|
545
|
+
const nextContext = prom[symbols.context]
|
|
542
546
|
if (!nextContext) {
|
|
543
547
|
return prom
|
|
544
548
|
}
|
|
@@ -5,15 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
/* eslint sonarjs/cognitive-complexity: ["error", 53] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
+
|
|
8
10
|
const cat = require('../util/cat')
|
|
9
11
|
const recordExternal = require('../metrics/recorders/http_external')
|
|
10
12
|
const logger = require('../logger').child({ component: 'undici' })
|
|
11
13
|
const NAMES = require('../metrics/names')
|
|
12
14
|
const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
|
|
13
|
-
const
|
|
14
|
-
SEGMENT: Symbol('__NR_segment'),
|
|
15
|
-
PARENT_SEGMENT: Symbol('__NR_parent_segment')
|
|
16
|
-
}
|
|
15
|
+
const symbols = require('../symbols')
|
|
17
16
|
const { executionAsyncResource } = require('async_hooks')
|
|
18
17
|
|
|
19
18
|
let diagnosticsChannel = null
|
|
@@ -52,11 +51,11 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
52
51
|
if (agent.config.feature_flag.undici_async_tracking) {
|
|
53
52
|
const resource = executionAsyncResource()
|
|
54
53
|
|
|
55
|
-
if (!resource[
|
|
54
|
+
if (!resource[symbols.parentSegment]) {
|
|
56
55
|
const parent = shim.getSegment()
|
|
57
|
-
resource[
|
|
56
|
+
resource[symbols.parentSegment] = parent
|
|
58
57
|
}
|
|
59
|
-
return resource[
|
|
58
|
+
return resource[symbols.parentSegment]
|
|
60
59
|
}
|
|
61
60
|
return shim.getSegment()
|
|
62
61
|
}
|
|
@@ -71,7 +70,7 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
71
70
|
*/
|
|
72
71
|
diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
|
|
73
72
|
const parent = getParentSegment()
|
|
74
|
-
request[
|
|
73
|
+
request[symbols.parentSegment] = parent
|
|
75
74
|
if (!parent || (parent && parent.opaque)) {
|
|
76
75
|
logger.trace(
|
|
77
76
|
'Not capturing data for outbound request (%s) because parent segment opaque (%s)',
|
|
@@ -114,7 +113,7 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
114
113
|
* @param {TLSSocket | net.Socket} socket active socket connection
|
|
115
114
|
*/
|
|
116
115
|
diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, socket }) => {
|
|
117
|
-
const parentSegment = request[
|
|
116
|
+
const parentSegment = request[symbols.parentSegment]
|
|
118
117
|
if (!parentSegment || (parentSegment && parentSegment.opaque)) {
|
|
119
118
|
return
|
|
120
119
|
}
|
|
@@ -143,7 +142,7 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
143
142
|
segment.addSpanAttribute(`request.parameters.${key}`, value)
|
|
144
143
|
})
|
|
145
144
|
segment.addAttribute('procedure', request.method || 'GET')
|
|
146
|
-
request[
|
|
145
|
+
request[symbols.segment] = segment
|
|
147
146
|
}
|
|
148
147
|
})
|
|
149
148
|
|
|
@@ -157,7 +156,7 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
157
156
|
* @param {object} params.response { statusCode, headers, statusText }
|
|
158
157
|
*/
|
|
159
158
|
diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {
|
|
160
|
-
const activeSegment = request[
|
|
159
|
+
const activeSegment = request[symbols.segment]
|
|
161
160
|
if (!activeSegment) {
|
|
162
161
|
return
|
|
163
162
|
}
|
|
@@ -211,8 +210,8 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
211
210
|
* @param {Error} error
|
|
212
211
|
*/
|
|
213
212
|
function endAndRestoreSegment(ctx, error) {
|
|
214
|
-
const activeSegment = ctx[
|
|
215
|
-
const parentSegment = ctx[
|
|
213
|
+
const activeSegment = ctx[symbols.segment]
|
|
214
|
+
const parentSegment = ctx[symbols.parentSegment]
|
|
216
215
|
if (activeSegment) {
|
|
217
216
|
activeSegment.end()
|
|
218
217
|
|
|
@@ -238,5 +237,3 @@ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
|
|
|
238
237
|
shim.agent.errors.add(tx, error)
|
|
239
238
|
}
|
|
240
239
|
}
|
|
241
|
-
|
|
242
|
-
module.exports.SYMBOLS = SYMBOLS
|
package/lib/instrumentations.js
CHANGED
|
@@ -36,7 +36,7 @@ module.exports = function instrumentations() {
|
|
|
36
36
|
'restify': { type: MODULE_TYPE.WEB_FRAMEWORK },
|
|
37
37
|
'superagent': { module: '@newrelic/superagent' },
|
|
38
38
|
'undici': { type: MODULE_TYPE.TRANSACTION },
|
|
39
|
-
'vision': { type: MODULE_TYPE.WEB_FRAMEWORK },
|
|
39
|
+
'@hapi/vision': { type: MODULE_TYPE.WEB_FRAMEWORK },
|
|
40
40
|
'when': { type: null },
|
|
41
41
|
'winston': { type: MODULE_TYPE.GENERIC }
|
|
42
42
|
}
|
package/lib/metrics/mapper.js
CHANGED
|
@@ -67,9 +67,8 @@ MetricMapper.prototype.load = function load(raw) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
* @param {
|
|
71
|
-
* @param {
|
|
72
|
-
*
|
|
70
|
+
* @param {string} name The metric name.
|
|
71
|
+
* @param {string} scope The scope for the metric, if set.
|
|
73
72
|
* @returns {object} Either a metric spec based on the parameters, or the
|
|
74
73
|
* server-sent ID.
|
|
75
74
|
*/
|
|
@@ -43,9 +43,7 @@ class MetricAggregator extends Aggregator {
|
|
|
43
43
|
const beginSeconds = this._metrics.started * FROM_MILLIS
|
|
44
44
|
const endSeconds = Date.now() * FROM_MILLIS
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return payload
|
|
46
|
+
return [this.runId, beginSeconds, endSeconds, this._metrics.toJSON()]
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
_getMergeData() {
|
package/lib/metrics/names.js
CHANGED
|
@@ -10,6 +10,10 @@ const NODEJS = {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const ALL = 'all'
|
|
13
|
+
const POSTGRES_LITERAL = 'Postgres'
|
|
14
|
+
const CASSANDRA_LITERAL = 'Cassandra'
|
|
15
|
+
const EXPRESS_LITERAL = 'Expressjs'
|
|
16
|
+
const OTHER_TRANSACTION_MESSAGE = 'OtherTransaction/Message'
|
|
13
17
|
|
|
14
18
|
const SUPPORTABILITY = {
|
|
15
19
|
PREFIX: 'Supportability/',
|
|
@@ -133,24 +137,24 @@ const REDIS = {
|
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
const POSTGRES = {
|
|
136
|
-
PREFIX:
|
|
137
|
-
STATEMENT: DB.STATEMENT +
|
|
138
|
-
OPERATION: DB.OPERATION +
|
|
139
|
-
INSTANCE: DB.INSTANCE +
|
|
140
|
+
PREFIX: POSTGRES_LITERAL,
|
|
141
|
+
STATEMENT: DB.STATEMENT + `/${POSTGRES_LITERAL}/`,
|
|
142
|
+
OPERATION: DB.OPERATION + `/${POSTGRES_LITERAL}/`,
|
|
143
|
+
INSTANCE: DB.INSTANCE + `/${POSTGRES_LITERAL}/`
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
const CASSANDRA = {
|
|
143
|
-
PREFIX:
|
|
144
|
-
OPERATION: DB.OPERATION +
|
|
145
|
-
STATEMENT: DB.STATEMENT +
|
|
146
|
-
INSTANCE: DB.INSTANCE +
|
|
147
|
-
ALL: DB.PREFIX +
|
|
147
|
+
PREFIX: CASSANDRA_LITERAL,
|
|
148
|
+
OPERATION: DB.OPERATION + `/${CASSANDRA_LITERAL}/`,
|
|
149
|
+
STATEMENT: DB.STATEMENT + `/${CASSANDRA_LITERAL}/`,
|
|
150
|
+
INSTANCE: DB.INSTANCE + `/${CASSANDRA_LITERAL}/`,
|
|
151
|
+
ALL: DB.PREFIX + `${CASSANDRA_LITERAL}/` + ALL
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
const EXPRESS = {
|
|
151
|
-
PREFIX:
|
|
152
|
-
MIDDLEWARE: MIDDLEWARE.PREFIX +
|
|
153
|
-
ERROR_HANDLER: MIDDLEWARE.PREFIX +
|
|
155
|
+
PREFIX: `${EXPRESS_LITERAL}/`,
|
|
156
|
+
MIDDLEWARE: MIDDLEWARE.PREFIX + `${EXPRESS_LITERAL}/`,
|
|
157
|
+
ERROR_HANDLER: MIDDLEWARE.PREFIX + `${EXPRESS_LITERAL}/`
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
const RESTIFY = {
|
|
@@ -216,12 +220,12 @@ const OTHER_TRANSACTION = {
|
|
|
216
220
|
PREFIX: 'OtherTransaction',
|
|
217
221
|
RESPONSE_TIME: 'OtherTransaction',
|
|
218
222
|
TOTAL_TIME: 'OtherTransactionTotalTime',
|
|
219
|
-
MESSAGE:
|
|
223
|
+
MESSAGE: OTHER_TRANSACTION_MESSAGE
|
|
220
224
|
}
|
|
221
225
|
|
|
222
226
|
const MESSAGE_TRANSACTION = {
|
|
223
|
-
PREFIX:
|
|
224
|
-
RESPONSE_TIME:
|
|
227
|
+
PREFIX: OTHER_TRANSACTION_MESSAGE,
|
|
228
|
+
RESPONSE_TIME: OTHER_TRANSACTION_MESSAGE,
|
|
225
229
|
TOTAL_TIME: 'OtherTransactionTotalTime/Message'
|
|
226
230
|
}
|
|
227
231
|
|
|
@@ -9,6 +9,8 @@ const logger = require('../../logger').child({ component: 'normalizer_rule' })
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* JavaScript just has to do things slightly differently.
|
|
12
|
+
*
|
|
13
|
+
* @param input
|
|
12
14
|
*/
|
|
13
15
|
const replaceReplacer = function replaceReplacer(input) {
|
|
14
16
|
return input.replace(/\\/g, '$')
|
|
@@ -20,7 +22,7 @@ const replaceReplacer = function replaceReplacer(input) {
|
|
|
20
22
|
* fairly straightforward mapping of the concepts in metric normalization
|
|
21
23
|
* rules into an object form.
|
|
22
24
|
*
|
|
23
|
-
* @param {
|
|
25
|
+
* @param {object} json A JavaScript object literal parsed out from the JSON
|
|
24
26
|
* from the collector.
|
|
25
27
|
*/
|
|
26
28
|
function NormalizerRule(json) {
|
|
@@ -74,8 +76,7 @@ NormalizerRule.prototype.getSegments = function getSegments(input) {
|
|
|
74
76
|
* Does not set {NormalizerRule#matched}.
|
|
75
77
|
*
|
|
76
78
|
* @param {string} input - URL to match.
|
|
77
|
-
*
|
|
78
|
-
* @return {bool} - True if this rule matches the given input, otherwise false.
|
|
79
|
+
* @returns {bool} - True if this rule matches the given input, otherwise false.
|
|
79
80
|
*/
|
|
80
81
|
NormalizerRule.prototype.matches = function matches(input) {
|
|
81
82
|
const segments = this.getSegments(input)
|
|
@@ -106,8 +107,7 @@ NormalizerRule.prototype.matches = function matches(input) {
|
|
|
106
107
|
* XXX `RegExp#lastIndex` to `0`.
|
|
107
108
|
*
|
|
108
109
|
* @param {string} input - URL to normalize.
|
|
109
|
-
*
|
|
110
|
-
* @return {string?} - The normalized url, or `null` if this is an ignore rule
|
|
110
|
+
* @returns {string?} - The normalized url, or `null` if this is an ignore rule
|
|
111
111
|
* that matched this url.
|
|
112
112
|
*/
|
|
113
113
|
NormalizerRule.prototype.apply = function apply(input) {
|
|
@@ -150,8 +150,7 @@ NormalizerRule.prototype.toJSON = function toJSON() {
|
|
|
150
150
|
*
|
|
151
151
|
* @param {RegExp} re - The regular expression to add flags to.
|
|
152
152
|
* @param {string} flags - The flags to add to the regex.
|
|
153
|
-
*
|
|
154
|
-
* @return {RegExp} - A regular expression with all the given flags added.
|
|
153
|
+
* @returns {RegExp} - A regular expression with all the given flags added.
|
|
155
154
|
*/
|
|
156
155
|
function _addRegExpFlags(re, flags) {
|
|
157
156
|
let foundMissing = false
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
/* eslint sonarjs/cognitive-complexity: ["error", 17] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
+
|
|
8
10
|
const logger = require('../../logger').child({ component: 'tx_segment_normalizer' })
|
|
9
11
|
|
|
10
12
|
module.exports = TxSegmentNormalizer
|
|
@@ -29,8 +31,7 @@ function TxSegmentNormalizer() {
|
|
|
29
31
|
* 6. Join together the modified segments with slashes, and re-prepend the prefix.
|
|
30
32
|
*
|
|
31
33
|
* @param {string} path - The transaction metric path to normalize.
|
|
32
|
-
*
|
|
33
|
-
* @return {NormalizationResults} - The results of normalizing the given path.
|
|
34
|
+
* @returns {NormalizationResults} - The results of normalizing the given path.
|
|
34
35
|
*/
|
|
35
36
|
TxSegmentNormalizer.prototype.normalize = function normalize(path) {
|
|
36
37
|
let currentTerm
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
/* eslint sonarjs/cognitive-complexity: ["error", 24] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
+
|
|
8
10
|
const EventEmitter = require('events').EventEmitter
|
|
9
11
|
const util = require('util')
|
|
10
12
|
const logger = require('../logger').child({ component: 'metric_normalizer' })
|
|
@@ -41,6 +43,7 @@ function plain(normalized, path) {
|
|
|
41
43
|
* @param {object} config The agent's configuration blob, which has a parameter
|
|
42
44
|
* that indicates whether to enforce the normalization
|
|
43
45
|
* backstop.
|
|
46
|
+
* @param type
|
|
44
47
|
*/
|
|
45
48
|
function MetricNormalizer(config, type) {
|
|
46
49
|
if (!config) {
|
|
@@ -68,8 +71,7 @@ util.inherits(MetricNormalizer, EventEmitter)
|
|
|
68
71
|
// -------------------------------------------------------------------------- //
|
|
69
72
|
|
|
70
73
|
/**
|
|
71
|
-
* @typedef {
|
|
72
|
-
*
|
|
74
|
+
* @typedef {object} NormalizationResults
|
|
73
75
|
* @property {bool} matched - True if a rule was found that matched.
|
|
74
76
|
* @property {bool} ignore - True if the given input should be ignored.
|
|
75
77
|
* @property {string} value - The normalized input value.
|
|
@@ -83,6 +85,7 @@ util.inherits(MetricNormalizer, EventEmitter)
|
|
|
83
85
|
*
|
|
84
86
|
* @param object json The de-serialized JSON response sent on collector
|
|
85
87
|
* connection.
|
|
88
|
+
* @param json
|
|
86
89
|
*/
|
|
87
90
|
MetricNormalizer.prototype.load = function load(json) {
|
|
88
91
|
if (json) {
|
|
@@ -196,7 +199,6 @@ MetricNormalizer.prototype.addSimple = function addSimple(pattern, name) {
|
|
|
196
199
|
* Turn a (scrubbed) URL path into partial metric name.
|
|
197
200
|
*
|
|
198
201
|
* @param {string} path - The URL path to turn into a name.
|
|
199
|
-
*
|
|
200
202
|
* @returns {NormalizationResults} - The results of normalization.
|
|
201
203
|
*/
|
|
202
204
|
MetricNormalizer.prototype.normalize = function normalize(path) {
|
|
@@ -6,10 +6,15 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const logger = require('./logger.js').child({ component: 'proc-cpuinfo' })
|
|
9
|
+
const PHYSICAL_ID = 'physical id'
|
|
10
|
+
const CPU_CORES = 'cpu cores'
|
|
11
|
+
const PROCESSOR = 'processor'
|
|
12
|
+
const CORE_ID = 'core id'
|
|
13
|
+
|
|
9
14
|
module.exports = parseProcCPUInfo
|
|
10
15
|
|
|
11
16
|
function parseProcCPUInfo(data) {
|
|
12
|
-
const relevantAttributes = [
|
|
17
|
+
const relevantAttributes = [PROCESSOR, PHYSICAL_ID, CPU_CORES, CORE_ID]
|
|
13
18
|
|
|
14
19
|
let processorStats = {
|
|
15
20
|
logical: null,
|
|
@@ -102,12 +107,12 @@ function countProcessorStats(processors) {
|
|
|
102
107
|
for (let i = 0; i < processors.length; i++) {
|
|
103
108
|
const processor = processors[i]
|
|
104
109
|
if (
|
|
105
|
-
processor[
|
|
106
|
-
processor[
|
|
107
|
-
phys.indexOf(processor[
|
|
110
|
+
processor[PHYSICAL_ID] &&
|
|
111
|
+
processor[CPU_CORES] &&
|
|
112
|
+
phys.indexOf(processor[PHYSICAL_ID]) === -1
|
|
108
113
|
) {
|
|
109
|
-
phys.push(processor[
|
|
110
|
-
cores.push(processor[
|
|
114
|
+
phys.push(processor[PHYSICAL_ID])
|
|
115
|
+
cores.push(processor[CPU_CORES])
|
|
111
116
|
}
|
|
112
117
|
}
|
|
113
118
|
|
|
@@ -38,8 +38,7 @@ class LambdaProxyWebResponse {
|
|
|
38
38
|
/**
|
|
39
39
|
* Determines if Lambda event appears to be a valid Lambda Proxy event.
|
|
40
40
|
*
|
|
41
|
-
* @param {
|
|
42
|
-
*
|
|
41
|
+
* @param {object} event The event to inspect.
|
|
43
42
|
* @returns {boolean} Whether the given object contains fields necessary
|
|
44
43
|
* to create a web transaction.
|
|
45
44
|
*/
|
|
@@ -50,8 +49,8 @@ function isLambdaProxyEvent(event) {
|
|
|
50
49
|
/**
|
|
51
50
|
* Determines if Lambda event appears to be a valid Lambda Proxy response.
|
|
52
51
|
*
|
|
53
|
-
* @param {
|
|
54
|
-
*
|
|
52
|
+
* @param {object} event The response to inspect.
|
|
53
|
+
* @param response
|
|
55
54
|
* @returns {boolean} Whether the given object contains fields necessary
|
|
56
55
|
* to create a web transaction.
|
|
57
56
|
*/
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
/* eslint sonarjs/cognitive-complexity: ["error", 29] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-5252 */
|
|
9
|
+
|
|
8
10
|
const apiGateway = require('./api-gateway')
|
|
9
11
|
const headerAttributes = require('../header-attributes')
|
|
10
12
|
const get = require('../util/get')
|
|
@@ -348,12 +350,10 @@ function setWebRequest(shim, transaction, request) {
|
|
|
348
350
|
}
|
|
349
351
|
|
|
350
352
|
function lowercaseObjectKeys(original) {
|
|
351
|
-
|
|
353
|
+
return Object.keys(original).reduce((destination, key) => {
|
|
352
354
|
destination[key.toLowerCase()] = original[key]
|
|
353
355
|
return destination
|
|
354
356
|
}, {})
|
|
355
|
-
|
|
356
|
-
return lowercaseObject
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
function endTransaction(transaction, enderIndex) {
|
|
@@ -22,7 +22,7 @@ const SHIM_CLASSES = {
|
|
|
22
22
|
* A shim for wrapping all-in-one modules which implement multiple services.
|
|
23
23
|
*
|
|
24
24
|
* @private
|
|
25
|
-
* @
|
|
25
|
+
* @augments Shim
|
|
26
26
|
*/
|
|
27
27
|
class ConglomerateShim extends Shim {
|
|
28
28
|
constructor(agent, moduleName, resolvedName) {
|
|
@@ -56,8 +56,7 @@ class ConglomerateShim extends Shim {
|
|
|
56
56
|
*
|
|
57
57
|
* @param {MODULE_TYPE} type - The type of shim to construct.
|
|
58
58
|
* @param {string} submodule - The name of the submodule this will instrument.
|
|
59
|
-
*
|
|
60
|
-
* @return {Shim} A new shim of the given type.
|
|
59
|
+
* @returns {Shim} A new shim of the given type.
|
|
61
60
|
*/
|
|
62
61
|
makeSpecializedShim(type, submodule) {
|
|
63
62
|
const ShimClass = SHIM_CLASSES[type]
|
package/lib/shim/constants.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @readonly
|
|
13
13
|
* @enum {string}
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
exports.MODULE_TYPE = {
|
|
16
16
|
/** Utility/generic module, such as pooling libraries. */
|
|
17
17
|
GENERIC: 'generic',
|
|
18
18
|
|
|
@@ -34,18 +34,3 @@ const MODULE_TYPE = {
|
|
|
34
34
|
/** Web server framework module, such as Express or Restify. */
|
|
35
35
|
WEB_FRAMEWORK: 'web-framework'
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Enumeration of symbols used by shims.
|
|
40
|
-
*
|
|
41
|
-
* @memberof Shim.prototype
|
|
42
|
-
* @readonly
|
|
43
|
-
* @enum {Symbol}
|
|
44
|
-
*/
|
|
45
|
-
const SYMBOLS = {
|
|
46
|
-
/** Indicates distributed tracing should be disabled for a single request. */
|
|
47
|
-
DISABLE_DT: Symbol('Disable distributed tracing')
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
exports.MODULE_TYPE = MODULE_TYPE
|
|
51
|
-
exports.SYMBOLS = SYMBOLS
|