newrelic 7.5.2 → 8.3.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 +4989 -4886
- package/THIRD_PARTY_NOTICES.md +625 -216
- package/api.js +105 -174
- package/bin/test-naming-rules.js +38 -32
- package/bin/tracetractor +0 -1
- package/index.js +12 -18
- package/lib/agent.js +108 -111
- package/lib/aggregators/base-aggregator.js +1 -1
- package/lib/aggregators/event-aggregator.js +6 -6
- package/lib/attributes.js +12 -13
- package/lib/collector/api.js +32 -42
- package/lib/collector/facts.js +67 -65
- package/lib/collector/http-agents.js +30 -27
- package/lib/collector/parse-response.js +1 -2
- package/lib/collector/remote-method.js +43 -36
- package/lib/collector/serverless.js +13 -18
- package/lib/collector/ssl/certificates.js +1056 -1056
- package/lib/config/attribute-filter.js +90 -82
- package/lib/config/default.js +30 -18
- package/lib/config/env.js +17 -12
- package/lib/config/harvest-config-validator.js +1 -1
- package/lib/config/index.js +160 -177
- package/lib/config/merge-server-config.js +7 -5
- package/lib/custom-events/custom-event-aggregator.js +1 -1
- package/lib/db/parse-sql.js +6 -9
- package/lib/db/parsed-statement.js +6 -13
- package/lib/db/query-parsers/sql.js +6 -9
- package/lib/db/query-sample.js +7 -3
- package/lib/db/query-trace-aggregator.js +12 -12
- package/lib/db/utils.js +1 -1
- package/lib/environment.js +173 -138
- package/lib/errors/error-collector.js +18 -31
- package/lib/errors/error-event-aggregator.js +1 -1
- package/lib/errors/error-trace-aggregator.js +2 -3
- package/lib/errors/helper.js +21 -30
- package/lib/errors/index.js +16 -28
- package/lib/feature_flags.js +5 -8
- package/lib/grpc/connection/states.js +6 -6
- package/lib/grpc/connection.js +35 -46
- package/lib/header-attributes.js +49 -53
- package/lib/instrumentation/amqplib.js +8 -17
- package/lib/instrumentation/bluebird.js +61 -20
- package/lib/instrumentation/cassandra-driver.js +2 -2
- package/lib/instrumentation/connect.js +4 -3
- package/lib/instrumentation/core/async_hooks.js +11 -4
- package/lib/instrumentation/core/child_process.js +20 -28
- package/lib/instrumentation/core/crypto.js +1 -7
- package/lib/instrumentation/core/dns.js +3 -7
- package/lib/instrumentation/core/domain.js +2 -8
- package/lib/instrumentation/core/fs.js +22 -37
- package/lib/instrumentation/core/globals.js +3 -7
- package/lib/instrumentation/core/http-outbound.js +15 -40
- package/lib/instrumentation/core/http.js +29 -63
- package/lib/instrumentation/core/inspector.js +6 -10
- package/lib/instrumentation/core/net.js +3 -1
- package/lib/instrumentation/core/timers.js +17 -24
- package/lib/instrumentation/core/zlib.js +2 -10
- package/lib/instrumentation/express.js +4 -2
- package/lib/instrumentation/fastify/spec-builders.js +5 -0
- package/lib/instrumentation/fastify.js +37 -10
- package/lib/instrumentation/hapi/hapi-17.js +9 -10
- package/lib/instrumentation/hapi.js +15 -15
- package/lib/instrumentation/ioredis.js +1 -2
- package/lib/instrumentation/memcached.js +39 -43
- package/lib/instrumentation/mongodb/common.js +218 -0
- package/lib/instrumentation/mongodb/constants.js +87 -0
- package/lib/instrumentation/mongodb/v2-mongo.js +110 -0
- package/lib/instrumentation/mongodb/v3-mongo.js +80 -0
- package/lib/instrumentation/mongodb/v4-mongo.js +90 -0
- package/lib/instrumentation/mongodb.js +20 -312
- package/lib/instrumentation/mysql.js +33 -26
- package/lib/instrumentation/oracle.js +10 -14
- package/lib/instrumentation/pg.js +30 -21
- package/lib/instrumentation/promise.js +20 -17
- package/lib/instrumentation/redis.js +30 -30
- package/lib/instrumentation/when.js +9 -1
- package/lib/instrumentations.js +24 -24
- package/lib/logger.js +1 -1
- package/lib/metrics/index.js +37 -17
- package/lib/metrics/mapper.js +9 -9
- package/lib/metrics/metric-aggregator.js +5 -10
- package/lib/metrics/names.js +8 -7
- package/lib/metrics/normalizer/rule.js +6 -7
- package/lib/metrics/normalizer/tx_segment.js +17 -13
- package/lib/metrics/normalizer.js +30 -33
- package/lib/metrics/recorders/custom.js +3 -1
- package/lib/metrics/recorders/distributed-trace.js +3 -18
- package/lib/metrics/recorders/generic.js +3 -2
- package/lib/metrics/recorders/http.js +4 -6
- package/lib/metrics/recorders/http_external.js +1 -3
- package/lib/metrics/recorders/message-transaction.js +2 -12
- package/lib/metrics/recorders/other.js +2 -12
- package/lib/parse-proc-cpuinfo.js +11 -16
- package/lib/parse-proc-meminfo.js +5 -3
- package/lib/prioritized-attributes.js +12 -17
- package/lib/priority-queue.js +1 -1
- package/lib/proxy/grpc.js +1 -1
- package/lib/reservoir.js +9 -3
- package/lib/sampler.js +12 -13
- package/lib/serverless/api-gateway.js +3 -3
- package/lib/serverless/aws-lambda.js +28 -37
- package/lib/shim/conglomerate-shim.js +4 -4
- package/lib/shim/datastore-shim.js +29 -38
- package/lib/shim/index.js +8 -9
- package/lib/shim/message-shim.js +111 -113
- package/lib/shim/promise-shim.js +18 -13
- package/lib/shim/shim.js +72 -66
- package/lib/shim/specs/index.js +18 -19
- package/lib/shim/transaction-shim.js +26 -36
- package/lib/shim/webframework-shim.js +25 -35
- package/lib/shimmer.js +184 -166
- package/lib/spans/create-span-event-aggregator.js +24 -44
- package/lib/spans/span-context.js +4 -10
- package/lib/spans/span-event-aggregator.js +68 -13
- package/lib/spans/span-event.js +5 -7
- package/lib/spans/span-streamer.js +10 -18
- package/lib/spans/streaming-span-event-aggregator.js +1 -1
- package/lib/spans/streaming-span-event.js +4 -4
- package/lib/stats/apdex.js +5 -11
- package/lib/stats/index.js +12 -17
- package/lib/system-info.js +7 -3
- package/lib/timer.js +30 -16
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/handle.js +19 -19
- package/lib/transaction/index.js +94 -112
- package/lib/transaction/name-state.js +5 -6
- package/lib/transaction/trace/aggregator.js +78 -73
- package/lib/transaction/trace/exclusive-time-calculator.js +5 -9
- package/lib/transaction/trace/index.js +26 -24
- package/lib/transaction/trace/segment.js +39 -56
- package/lib/transaction/tracecontext.js +37 -45
- package/lib/transaction/tracer/index.js +79 -44
- package/lib/transaction/transaction-event-aggregator.js +29 -31
- package/lib/uninstrumented.js +4 -5
- package/lib/util/attribute-types.js +1 -5
- package/lib/util/byte-limit.js +0 -1
- package/lib/util/cat.js +5 -13
- package/lib/util/codec.js +8 -4
- package/lib/util/deep-equal.js +48 -18
- package/lib/util/flatten.js +5 -2
- package/lib/util/hashes.js +2 -2
- package/lib/util/label-parser.js +7 -13
- package/lib/util/logger.js +31 -13
- package/lib/util/process-version.js +1 -1
- package/lib/util/properties.js +1 -1
- package/lib/util/sql/obfuscate.js +7 -17
- package/lib/util/stream-sink.js +2 -3
- package/lib/util/urltils.js +9 -13
- package/lib/utilization/aws-info.js +2 -3
- package/lib/utilization/azure-info.js +32 -30
- package/lib/utilization/common.js +5 -4
- package/lib/utilization/docker-info.js +4 -6
- package/lib/utilization/gcp-info.js +36 -35
- package/lib/utilization/index.js +1 -1
- package/lib/utilization/kubernetes-info.js +2 -2
- package/lib/utilization/pcf-info.js +4 -4
- package/package.json +32 -18
- package/stub_api.js +8 -6
package/bin/test-naming-rules.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
|
|
3
2
|
/*
|
|
4
3
|
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
5
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -19,7 +18,7 @@ var options = null
|
|
|
19
18
|
if (arrayContainsAny(process.argv, '-h', '-?', '--help')) {
|
|
20
19
|
printHelp()
|
|
21
20
|
} else if (process.argv.length === 3) {
|
|
22
|
-
options = {rules: null, urls: path.resolve(cwd, process.argv[2])}
|
|
21
|
+
options = { rules: null, urls: path.resolve(cwd, process.argv[2]) }
|
|
23
22
|
} else if (process.argv.length === 4) {
|
|
24
23
|
options = {
|
|
25
24
|
rules: path.resolve(cwd, process.argv[2]),
|
|
@@ -73,8 +72,8 @@ function run(opts) {
|
|
|
73
72
|
defaultNormalizer.on('appliedRule', onAppliedRule)
|
|
74
73
|
userNormalizer.on('appliedRule', onAppliedRule)
|
|
75
74
|
|
|
76
|
-
var urlsFile = fs.createReadStream(opts.urls, {encoding: 'utf-8'})
|
|
77
|
-
var reader = readline.createInterface({input: urlsFile, output: null})
|
|
75
|
+
var urlsFile = fs.createReadStream(opts.urls, { encoding: 'utf-8' })
|
|
76
|
+
var reader = readline.createInterface({ input: urlsFile, output: null })
|
|
78
77
|
reader.on('line', function onUrlLine(urlLine) {
|
|
79
78
|
appliedRules = []
|
|
80
79
|
var scrubbedUrl = urltils.scrub(urlLine)
|
|
@@ -93,7 +92,10 @@ function run(opts) {
|
|
|
93
92
|
var match = appliedRules[i]
|
|
94
93
|
console.log(
|
|
95
94
|
' %s: %s => %s (rule %s)',
|
|
96
|
-
|
|
95
|
+
i + 1,
|
|
96
|
+
match.original,
|
|
97
|
+
match.normalized,
|
|
98
|
+
match.rule.pattern
|
|
97
99
|
)
|
|
98
100
|
}
|
|
99
101
|
}
|
|
@@ -120,33 +122,37 @@ function loadDefaultNormalizer(config) {
|
|
|
120
122
|
var normalizer = new MetricNormalizer(config, 'URL')
|
|
121
123
|
|
|
122
124
|
// Add in the rules the collector would ship down.
|
|
123
|
-
normalizer.load([
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
125
|
+
normalizer.load([
|
|
126
|
+
{
|
|
127
|
+
match_expression:
|
|
128
|
+
'.*\\.(ace|arj|ini|txt|udl|plist|css|gif|ico|jpe?g|js|png|swf|woff|caf|' +
|
|
129
|
+
'aiff|m4v|mpe?g|mp3|mp4|mov)$',
|
|
130
|
+
replacement: '/*.\\1',
|
|
131
|
+
replace_all: false,
|
|
132
|
+
each_segment: false,
|
|
133
|
+
ignore: false,
|
|
134
|
+
terminate_chain: true,
|
|
135
|
+
eval_order: 1000
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
match_expression: '^[0-9][0-9a-f_,.-]*$',
|
|
139
|
+
replacement: '*',
|
|
140
|
+
replace_all: false,
|
|
141
|
+
each_segment: true,
|
|
142
|
+
ignore: false,
|
|
143
|
+
terminate_chain: false,
|
|
144
|
+
eval_order: 1001
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
match_expression: '^(.*)/[0-9][0-9a-f_,-]*\\.([0-9a-z][0-9a-z]*)$',
|
|
148
|
+
replacement: '\\1/.*\\2',
|
|
149
|
+
replace_all: false,
|
|
150
|
+
each_segment: false,
|
|
151
|
+
ignore: false,
|
|
152
|
+
terminate_chain: false,
|
|
153
|
+
eval_order: 1002
|
|
154
|
+
}
|
|
155
|
+
])
|
|
150
156
|
|
|
151
157
|
return normalizer
|
|
152
158
|
}
|
package/bin/tracetractor
CHANGED
package/index.js
CHANGED
|
@@ -16,7 +16,6 @@ const featureFlags = require('./lib/feature_flags').prerelease
|
|
|
16
16
|
const psemver = require('./lib/util/process-version')
|
|
17
17
|
let logger = require('./lib/logger') // Gets re-loaded after initialization.
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
const pkgJSON = require('./package.json')
|
|
21
20
|
logger.info(
|
|
22
21
|
'Using New Relic for Node.js. Agent version: %s; Node version: %s.',
|
|
@@ -43,24 +42,23 @@ function initialize() {
|
|
|
43
42
|
let message = null
|
|
44
43
|
|
|
45
44
|
try {
|
|
46
|
-
logger.debug(
|
|
47
|
-
'Process was running %s seconds before agent was loaded.',
|
|
48
|
-
preAgentTime
|
|
49
|
-
)
|
|
45
|
+
logger.debug('Process was running %s seconds before agent was loaded.', preAgentTime)
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
message =
|
|
54
|
-
|
|
47
|
+
if (!psemver.satisfies(pkgJSON.engines.node)) {
|
|
48
|
+
// TODO: Update this message when Node v12 is deprecated.
|
|
49
|
+
message =
|
|
50
|
+
'New Relic for Node.js requires a version of Node equal to or\n' +
|
|
51
|
+
'greater than 12.0.0. Not starting!'
|
|
55
52
|
|
|
56
53
|
logger.error(message)
|
|
57
54
|
throw new Error(message)
|
|
55
|
+
}
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
// TODO: Update this check when Node v18 support is added
|
|
58
|
+
if (psemver.satisfies('>=17.0.0')) {
|
|
61
59
|
logger.warn(
|
|
62
60
|
'New Relic for Node.js %s has not been tested on Node.js %s. Please ' +
|
|
63
|
-
|
|
61
|
+
'update the agent or downgrade your version of Node.js',
|
|
64
62
|
pkgJSON.version,
|
|
65
63
|
process.version
|
|
66
64
|
)
|
|
@@ -131,9 +129,7 @@ function createAgent(config) {
|
|
|
131
129
|
const appNames = agent.config.applications()
|
|
132
130
|
|
|
133
131
|
if (config.logging.diagnostics) {
|
|
134
|
-
logger.warn(
|
|
135
|
-
'Diagnostics logging is enabled, this may cause significant overhead.'
|
|
136
|
-
)
|
|
132
|
+
logger.warn('Diagnostics logging is enabled, this may cause significant overhead.')
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
if (appNames.length < 1) {
|
|
@@ -175,9 +171,7 @@ function createAgent(config) {
|
|
|
175
171
|
function addStartupSupportabilities(agent) {
|
|
176
172
|
// TODO: As new versions come out, make sure to update Angler metrics.
|
|
177
173
|
const nodeMajor = /^v?(\d+)/.exec(process.version)
|
|
178
|
-
agent.recordSupportability(
|
|
179
|
-
'Nodejs/Version/' + ((nodeMajor && nodeMajor[1]) || 'unknown')
|
|
180
|
-
)
|
|
174
|
+
agent.recordSupportability('Nodejs/Version/' + ((nodeMajor && nodeMajor[1]) || 'unknown'))
|
|
181
175
|
|
|
182
176
|
const configFlags = Object.keys(agent.config.feature_flag)
|
|
183
177
|
for (let i = 0; i < configFlags.length; ++i) {
|
package/lib/agent.js
CHANGED
|
@@ -57,7 +57,9 @@ const DEFAULT_HARVEST_INTERVAL_MS = 60000
|
|
|
57
57
|
function Agent(config) {
|
|
58
58
|
EventEmitter.call(this)
|
|
59
59
|
|
|
60
|
-
if (!config)
|
|
60
|
+
if (!config) {
|
|
61
|
+
throw new Error('Agent must be created with a configuration!')
|
|
62
|
+
}
|
|
61
63
|
|
|
62
64
|
// The agent base attributes which last throughout its lifetime.
|
|
63
65
|
this._state = 'stopped'
|
|
@@ -84,10 +86,7 @@ function Agent(config) {
|
|
|
84
86
|
this.collector
|
|
85
87
|
)
|
|
86
88
|
|
|
87
|
-
this.metrics.on(
|
|
88
|
-
'starting metric_data data send.',
|
|
89
|
-
this._beforeMetricDataSend.bind(this)
|
|
90
|
-
)
|
|
89
|
+
this.metrics.on('starting metric_data data send.', this._beforeMetricDataSend.bind(this))
|
|
91
90
|
|
|
92
91
|
this.spanEventAggregator = createSpanEventAggregator(config, this.collector, this.metrics)
|
|
93
92
|
|
|
@@ -126,7 +125,7 @@ function Agent(config) {
|
|
|
126
125
|
this.collector
|
|
127
126
|
)
|
|
128
127
|
|
|
129
|
-
const errorEventAggregator =
|
|
128
|
+
const errorEventAggregator = new ErrorEventAggregator(
|
|
130
129
|
{
|
|
131
130
|
periodMs: config.event_harvest_config.report_period_ms,
|
|
132
131
|
limit: config.event_harvest_config.harvest_limits.error_event_data
|
|
@@ -135,12 +134,7 @@ function Agent(config) {
|
|
|
135
134
|
this.metrics
|
|
136
135
|
)
|
|
137
136
|
|
|
138
|
-
this.errors = new ErrorCollector(
|
|
139
|
-
config,
|
|
140
|
-
errorTraceAggregator,
|
|
141
|
-
errorEventAggregator,
|
|
142
|
-
this.metrics
|
|
143
|
-
)
|
|
137
|
+
this.errors = new ErrorCollector(config, errorTraceAggregator, errorEventAggregator, this.metrics)
|
|
144
138
|
|
|
145
139
|
// Transaction tracing.
|
|
146
140
|
this.tracer = new Tracer(this)
|
|
@@ -195,15 +189,16 @@ util.inherits(Agent, EventEmitter)
|
|
|
195
189
|
* @param {Function} callback Continuation and error handler.
|
|
196
190
|
*/
|
|
197
191
|
Agent.prototype.start = function start(callback) {
|
|
198
|
-
if (!callback)
|
|
192
|
+
if (!callback) {
|
|
193
|
+
throw new TypeError('callback required!')
|
|
194
|
+
}
|
|
199
195
|
|
|
200
196
|
const agent = this
|
|
201
197
|
|
|
202
198
|
this.setState('starting')
|
|
203
199
|
|
|
204
200
|
if (this.config.agent_enabled !== true) {
|
|
205
|
-
logger.warn('The New Relic Node.js agent is disabled by its configuration. ' +
|
|
206
|
-
'Not starting!')
|
|
201
|
+
logger.warn('The New Relic Node.js agent is disabled by its configuration. ' + 'Not starting!')
|
|
207
202
|
|
|
208
203
|
this.setState('stopped')
|
|
209
204
|
return process.nextTick(callback)
|
|
@@ -216,9 +211,11 @@ Agent.prototype.start = function start(callback) {
|
|
|
216
211
|
}
|
|
217
212
|
|
|
218
213
|
if (!this.config.license_key) {
|
|
219
|
-
logger.error(
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
logger.error(
|
|
215
|
+
'A valid account license key cannot be found. ' +
|
|
216
|
+
'Has a license key been specified in the agent configuration ' +
|
|
217
|
+
'file or via the NEW_RELIC_LICENSE_KEY environment variable?'
|
|
218
|
+
)
|
|
222
219
|
|
|
223
220
|
this.setState('errored')
|
|
224
221
|
sampler.stop()
|
|
@@ -232,40 +229,17 @@ Agent.prototype.start = function start(callback) {
|
|
|
232
229
|
if (error || response.shouldShutdownRun()) {
|
|
233
230
|
agent.setState('errored')
|
|
234
231
|
sampler.stop()
|
|
235
|
-
callback(
|
|
236
|
-
error || new Error('Failed to connect to collector'),
|
|
237
|
-
response && response.payload
|
|
238
|
-
)
|
|
232
|
+
callback(error || new Error('Failed to connect to collector'), response && response.payload)
|
|
239
233
|
return
|
|
240
234
|
}
|
|
241
235
|
|
|
242
236
|
if (agent.collector.isConnected()) {
|
|
243
|
-
agent.onConnect()
|
|
244
|
-
agent.setState('started')
|
|
245
237
|
const config = response.payload
|
|
246
238
|
|
|
247
|
-
|
|
248
|
-
|
|
239
|
+
const shouldImmediatelyHarvest = !agent.config.no_immediate_harvest
|
|
240
|
+
agent.onConnect(shouldImmediatelyHarvest, () => {
|
|
249
241
|
callback(null, config)
|
|
250
|
-
}
|
|
251
|
-
// For data collection that streams immediately, dont delay capture/sending until
|
|
252
|
-
// the harvest of everything else has completed.
|
|
253
|
-
agent.startStreaming()
|
|
254
|
-
|
|
255
|
-
// Harvest immediately for quicker data display, but after at least 1
|
|
256
|
-
// second or the collector will throw away the data.
|
|
257
|
-
//
|
|
258
|
-
// NOTE: this setTimeout is deliberately NOT unref'd due to it being
|
|
259
|
-
// the last step in the Agent startup process
|
|
260
|
-
setTimeout(function afterTimeout() {
|
|
261
|
-
logger.info(`Starting initial ${INITIAL_HARVEST_DELAY_MS}ms harvest.`)
|
|
262
|
-
|
|
263
|
-
agent.forceHarvestAll(function afterAllAggregatorsSend() {
|
|
264
|
-
agent.startAggregators()
|
|
265
|
-
callback(null, config)
|
|
266
|
-
})
|
|
267
|
-
}, INITIAL_HARVEST_DELAY_MS)
|
|
268
|
-
}
|
|
242
|
+
})
|
|
269
243
|
} else {
|
|
270
244
|
callback(new Error('Collector did not connect and did not error'))
|
|
271
245
|
}
|
|
@@ -281,12 +255,9 @@ Agent.prototype.forceHarvestAll = function forceHarvestAll(callback) {
|
|
|
281
255
|
const promises = []
|
|
282
256
|
|
|
283
257
|
const metricPromise = new Promise((resolve) => {
|
|
284
|
-
agent.metrics.once(
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
resolve()
|
|
288
|
-
}
|
|
289
|
-
)
|
|
258
|
+
agent.metrics.once('finished metric_data data send.', function onMetricsFinished() {
|
|
259
|
+
resolve()
|
|
260
|
+
})
|
|
290
261
|
agent.metrics.send()
|
|
291
262
|
})
|
|
292
263
|
|
|
@@ -341,12 +312,9 @@ Agent.prototype.forceHarvestAll = function forceHarvestAll(callback) {
|
|
|
341
312
|
|
|
342
313
|
if (agent.config.transaction_tracer.enabled && agent.config.collect_traces) {
|
|
343
314
|
const transactionTracePromise = new Promise((resolve) => {
|
|
344
|
-
agent.traces.once(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
resolve()
|
|
348
|
-
}
|
|
349
|
-
)
|
|
315
|
+
agent.traces.once('finished transaction_sample_data data send.', function onTracesFinished() {
|
|
316
|
+
resolve()
|
|
317
|
+
})
|
|
350
318
|
agent.traces.send()
|
|
351
319
|
})
|
|
352
320
|
|
|
@@ -355,20 +323,16 @@ Agent.prototype.forceHarvestAll = function forceHarvestAll(callback) {
|
|
|
355
323
|
|
|
356
324
|
if (agent.config.slow_sql.enabled) {
|
|
357
325
|
const sqlTracePromise = new Promise((resolve) => {
|
|
358
|
-
agent.queries.once(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
resolve()
|
|
362
|
-
}
|
|
363
|
-
)
|
|
326
|
+
agent.queries.once('finished sql_trace_data data send.', function onSqlTracesFinished() {
|
|
327
|
+
resolve()
|
|
328
|
+
})
|
|
364
329
|
agent.queries.send()
|
|
365
330
|
})
|
|
366
331
|
|
|
367
332
|
promises.push(sqlTracePromise)
|
|
368
333
|
}
|
|
369
334
|
|
|
370
|
-
const errorCollectorEnabled =
|
|
371
|
-
agent.config.error_collector && agent.config.error_collector.enabled
|
|
335
|
+
const errorCollectorEnabled = agent.config.error_collector && agent.config.error_collector.enabled
|
|
372
336
|
|
|
373
337
|
if (errorCollectorEnabled && agent.config.collect_errors) {
|
|
374
338
|
const errorTracePromise = new Promise((resolve) => {
|
|
@@ -436,8 +400,7 @@ Agent.prototype.startAggregators = function startAggregators() {
|
|
|
436
400
|
this.queries.start()
|
|
437
401
|
}
|
|
438
402
|
|
|
439
|
-
if (this.config.distributed_tracing.enabled &&
|
|
440
|
-
this.config.span_events.enabled) {
|
|
403
|
+
if (this.config.distributed_tracing.enabled && this.config.span_events.enabled) {
|
|
441
404
|
this.spanEventAggregator.start()
|
|
442
405
|
}
|
|
443
406
|
|
|
@@ -450,18 +413,58 @@ Agent.prototype.startAggregators = function startAggregators() {
|
|
|
450
413
|
}
|
|
451
414
|
}
|
|
452
415
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
this.
|
|
459
|
-
this.transactionEventAggregator.reconfigure(this.config)
|
|
460
|
-
this.customEventAggregator.reconfigure(this.config)
|
|
416
|
+
/**
|
|
417
|
+
* Completes any final setup upon full connection to New Relic
|
|
418
|
+
* servers and sets the agent state to 'started'.
|
|
419
|
+
*/
|
|
420
|
+
Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
|
|
421
|
+
this._reconfigureAggregators(this.config)
|
|
461
422
|
|
|
462
423
|
if (this.config.certificates && this.config.certificates.length > 0) {
|
|
463
424
|
this.metrics.getOrCreateMetric(NAMES.FEATURES.CERTIFICATES).incrementCallCount()
|
|
464
425
|
}
|
|
426
|
+
|
|
427
|
+
this._scheduleHarvests(shouldImmediatelyHarvest, callback)
|
|
428
|
+
|
|
429
|
+
this.setState('started')
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
Agent.prototype._reconfigureAggregators = function _reconfigureAggregators(config) {
|
|
433
|
+
this.metrics.reconfigure(config)
|
|
434
|
+
this.errors.reconfigure(config)
|
|
435
|
+
this.traces.reconfigure(config)
|
|
436
|
+
this.queries.reconfigure(config)
|
|
437
|
+
this.spanEventAggregator.reconfigure(config)
|
|
438
|
+
this.transactionEventAggregator.reconfigure(config)
|
|
439
|
+
this.customEventAggregator.reconfigure(config)
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
Agent.prototype._scheduleHarvests = function _scheduleHarvests(shouldImmediatelyHarvest, callback) {
|
|
443
|
+
if (!shouldImmediatelyHarvest) {
|
|
444
|
+
this.startAggregators()
|
|
445
|
+
setImmediate(callback)
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const agent = this
|
|
450
|
+
|
|
451
|
+
// For data collection that streams immediately, dont delay capture/sending until
|
|
452
|
+
// the harvest of everything else has completed.
|
|
453
|
+
agent.startStreaming()
|
|
454
|
+
|
|
455
|
+
// Harvest immediately for quicker data display, but after at least 1
|
|
456
|
+
// second or the collector will throw away the data.
|
|
457
|
+
//
|
|
458
|
+
// NOTE: this setTimeout is deliberately NOT unref'd due to it being
|
|
459
|
+
// the last step in the Agent startup process
|
|
460
|
+
setTimeout(function afterTimeout() {
|
|
461
|
+
logger.info(`Starting initial ${INITIAL_HARVEST_DELAY_MS}ms harvest.`)
|
|
462
|
+
|
|
463
|
+
agent.forceHarvestAll(function afterAllAggregatorsSend() {
|
|
464
|
+
agent.startAggregators()
|
|
465
|
+
callback()
|
|
466
|
+
})
|
|
467
|
+
}, INITIAL_HARVEST_DELAY_MS)
|
|
465
468
|
}
|
|
466
469
|
|
|
467
470
|
/**
|
|
@@ -471,9 +474,7 @@ Agent.prototype.onConnect = function onConnect() {
|
|
|
471
474
|
* @param {Function} callback
|
|
472
475
|
*/
|
|
473
476
|
Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
|
|
474
|
-
logger.info(
|
|
475
|
-
'New Relic for Node.js starting in serverless mode -- skipping connection process.'
|
|
476
|
-
)
|
|
477
|
+
logger.info('New Relic for Node.js starting in serverless mode -- skipping connection process.')
|
|
477
478
|
|
|
478
479
|
setImmediate(() => callback(null, this.config))
|
|
479
480
|
}
|
|
@@ -486,7 +487,9 @@ Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
|
|
|
486
487
|
* current instrumentation and patch to the module loader.
|
|
487
488
|
*/
|
|
488
489
|
Agent.prototype.stop = function stop(callback) {
|
|
489
|
-
if (!callback)
|
|
490
|
+
if (!callback) {
|
|
491
|
+
throw new TypeError('callback required!')
|
|
492
|
+
}
|
|
490
493
|
|
|
491
494
|
const agent = this
|
|
492
495
|
|
|
@@ -597,12 +600,15 @@ Agent.prototype._beforeMetricDataSend = function _beforeMetricDataSend() {
|
|
|
597
600
|
Agent.prototype._generateEntityStatsAndClear = function _generateHarvestMetrics() {
|
|
598
601
|
// Note some information about the size of this harvest.
|
|
599
602
|
if (logger.traceEnabled()) {
|
|
600
|
-
logger.trace(
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
603
|
+
logger.trace(
|
|
604
|
+
{
|
|
605
|
+
segmentTotal: this.totalActiveSegments,
|
|
606
|
+
harvestCreated: this.segmentsCreatedInHarvest,
|
|
607
|
+
harvestCleared: this.segmentsClearedInHarvest,
|
|
608
|
+
activeTransactions: this.activeTransactions
|
|
609
|
+
},
|
|
610
|
+
'Entity stats on metric harvest'
|
|
611
|
+
)
|
|
606
612
|
}
|
|
607
613
|
|
|
608
614
|
// Reset the counters.
|
|
@@ -618,7 +624,9 @@ Agent.prototype._generateEntityStatsAndClear = function _generateHarvestMetrics(
|
|
|
618
624
|
* @param {object} configuration New config JSON from the collector.
|
|
619
625
|
*/
|
|
620
626
|
Agent.prototype.reconfigure = function reconfigure(configuration) {
|
|
621
|
-
if (!configuration)
|
|
627
|
+
if (!configuration) {
|
|
628
|
+
throw new TypeError('must pass configuration')
|
|
629
|
+
}
|
|
622
630
|
|
|
623
631
|
this.config.onConnect(configuration)
|
|
624
632
|
}
|
|
@@ -709,10 +717,8 @@ function _addIntrinsicAttrsFromTransaction(transaction) {
|
|
|
709
717
|
}
|
|
710
718
|
} else if (
|
|
711
719
|
this.config.cross_application_tracer.enabled &&
|
|
712
|
-
!transaction.invalidIncomingExternalTransaction &&
|
|
713
|
-
|
|
714
|
-
transaction.includesOutboundRequests()
|
|
715
|
-
)
|
|
720
|
+
!transaction.invalidIncomingExternalTransaction &&
|
|
721
|
+
(transaction.referringTransactionGuid || transaction.includesOutboundRequests())
|
|
716
722
|
) {
|
|
717
723
|
intrinsicAttributes['nr.guid'] = transaction.id
|
|
718
724
|
intrinsicAttributes['nr.tripId'] = transaction.tripId || transaction.id
|
|
@@ -733,10 +739,8 @@ function _addIntrinsicAttrsFromTransaction(transaction) {
|
|
|
733
739
|
intrinsicAttributes['nr.alternatePathHashes'] = alternatePathHashes
|
|
734
740
|
}
|
|
735
741
|
if (transaction.baseSegment && transaction.type === 'web') {
|
|
736
|
-
var apdex =
|
|
737
|
-
this.config.web_transactions_apdex[transaction.getFullName()] ||
|
|
738
|
-
this.config.apdex_t
|
|
739
|
-
)
|
|
742
|
+
var apdex =
|
|
743
|
+
this.config.web_transactions_apdex[transaction.getFullName()] || this.config.apdex_t
|
|
740
744
|
var duration = transaction.baseSegment.getDurationInMillis() / 1000
|
|
741
745
|
intrinsicAttributes['nr.apdexPerfZone'] = calculateApdexZone(duration, apdex)
|
|
742
746
|
}
|
|
@@ -764,17 +768,15 @@ function calculateApdexZone(duration, apdexT) {
|
|
|
764
768
|
}
|
|
765
769
|
|
|
766
770
|
Agent.prototype._addEventFromTransaction = function _addEventFromTransaction(tx) {
|
|
767
|
-
if (!this.config.transaction_events.enabled)
|
|
771
|
+
if (!this.config.transaction_events.enabled) {
|
|
772
|
+
return
|
|
773
|
+
}
|
|
768
774
|
|
|
769
775
|
const intrinsicAttributes = this._addIntrinsicAttrsFromTransaction(tx)
|
|
770
776
|
const userAttributes = tx.trace.custom.get(DESTINATIONS.TRANS_EVENT)
|
|
771
777
|
const agentAttributes = tx.trace.attributes.get(DESTINATIONS.TRANS_EVENT)
|
|
772
778
|
|
|
773
|
-
const event = [
|
|
774
|
-
intrinsicAttributes,
|
|
775
|
-
userAttributes,
|
|
776
|
-
agentAttributes
|
|
777
|
-
]
|
|
779
|
+
const event = [intrinsicAttributes, userAttributes, agentAttributes]
|
|
778
780
|
|
|
779
781
|
this.transactionEventAggregator.add(event, tx.priority || Math.random())
|
|
780
782
|
}
|
|
@@ -822,9 +824,9 @@ Agent.prototype.setLambdaArn = function setLambdaArn(arn) {
|
|
|
822
824
|
}
|
|
823
825
|
}
|
|
824
826
|
|
|
825
|
-
Agent.prototype.setLambdaFunctionVersion = function setLambdaFunctionVersion(
|
|
827
|
+
Agent.prototype.setLambdaFunctionVersion = function setLambdaFunctionVersion(functionVersion) {
|
|
826
828
|
if (this.collector instanceof ServerlessCollector) {
|
|
827
|
-
this.collector.setLambdaFunctionVersion(
|
|
829
|
+
this.collector.setLambdaFunctionVersion(functionVersion)
|
|
828
830
|
}
|
|
829
831
|
}
|
|
830
832
|
|
|
@@ -865,12 +867,9 @@ Agent.prototype._listenForConfigChanges = function _listenForConfigChanges() {
|
|
|
865
867
|
this.config.on('sampling_target', function updateSamplingTarget(target) {
|
|
866
868
|
self.transactionSampler.samplingTarget = target
|
|
867
869
|
})
|
|
868
|
-
this.config.on(
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
self.transactionSampler.samplingPeriod = period * 1000
|
|
872
|
-
}
|
|
873
|
-
)
|
|
870
|
+
this.config.on('sampling_target_period_in_seconds', function updateSamplePeriod(period) {
|
|
871
|
+
self.transactionSampler.samplingPeriod = period * 1000
|
|
872
|
+
})
|
|
874
873
|
this.config.on('event_harvest_config', function onHarvestConfigReceived(harvestConfig) {
|
|
875
874
|
if (harvestConfig) {
|
|
876
875
|
generateEventHarvestSupportMetrics(self, harvestConfig)
|
|
@@ -889,9 +888,7 @@ function generateEventHarvestSupportMetrics(agent, harvestConfig) {
|
|
|
889
888
|
|
|
890
889
|
const analyticLimit = harvestLimits.analytic_event_data
|
|
891
890
|
if (analyticLimit) {
|
|
892
|
-
const analyticLimitMetric = agent.metrics.getOrCreateMetric(
|
|
893
|
-
harvestLimitNames.ANALYTIC
|
|
894
|
-
)
|
|
891
|
+
const analyticLimitMetric = agent.metrics.getOrCreateMetric(harvestLimitNames.ANALYTIC)
|
|
895
892
|
analyticLimitMetric.recordValue(analyticLimit)
|
|
896
893
|
}
|
|
897
894
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const EventEmitter = require('events').EventEmitter
|
|
9
|
-
const logger = require('../logger').child({component: 'base_aggregator'})
|
|
9
|
+
const logger = require('../logger').child({ component: 'base_aggregator' })
|
|
10
10
|
|
|
11
11
|
class Aggregator extends EventEmitter {
|
|
12
12
|
constructor(opts, collector) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const Aggregator = require('./base-aggregator')
|
|
9
|
-
const logger = require('../logger').child({component: 'event_aggregator'})
|
|
9
|
+
const logger = require('../logger').child({ component: 'event_aggregator' })
|
|
10
10
|
const PriorityQueue = require('../priority-queue')
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -49,7 +49,7 @@ class EventAggregator extends Aggregator {
|
|
|
49
49
|
|
|
50
50
|
const didAdd = this.addEvent.apply(this, arguments)
|
|
51
51
|
|
|
52
|
-
if (didAdd &&
|
|
52
|
+
if (didAdd && this._items.overflow() === 0) {
|
|
53
53
|
this._metrics.getOrCreateMetric(this._metricNames.SENT).incrementCallCount()
|
|
54
54
|
} else {
|
|
55
55
|
this._metrics.getOrCreateMetric(this._metricNames.DROPPED).incrementCallCount()
|
|
@@ -129,7 +129,9 @@ class EventAggregator extends Aggregator {
|
|
|
129
129
|
const toMerge = Math.min(events.length, this.limit - this.length)
|
|
130
130
|
logger.warn(
|
|
131
131
|
'Merging %d of %d events into %s for next harvest',
|
|
132
|
-
toMerge,
|
|
132
|
+
toMerge,
|
|
133
|
+
events.length,
|
|
134
|
+
this.constructor.name
|
|
133
135
|
)
|
|
134
136
|
|
|
135
137
|
const seen = events.length
|
|
@@ -140,9 +142,7 @@ class EventAggregator extends Aggregator {
|
|
|
140
142
|
this._metrics.getOrCreateMetric(this._metricNames.SENT).incrementCallCount(sent)
|
|
141
143
|
|
|
142
144
|
if (dropped > 0) {
|
|
143
|
-
this._metrics
|
|
144
|
-
.getOrCreateMetric(this._metricNames.DROPPED)
|
|
145
|
-
.incrementCallCount(dropped)
|
|
145
|
+
this._metrics.getOrCreateMetric(this._metricNames.DROPPED).incrementCallCount(dropped)
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// merge modifies incoming events collection.
|