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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
const a = require('async')
|
|
8
|
-
const logger = require('../../logger').child({component: 'Transaction Trace Aggregator'})
|
|
8
|
+
const logger = require('../../logger').child({ component: 'Transaction Trace Aggregator' })
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
*
|
|
@@ -32,23 +32,22 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
32
32
|
|
|
33
33
|
super(opts, collector)
|
|
34
34
|
/*
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
* From
|
|
36
|
+
*
|
|
37
|
+
* https://newrelic.atlassian.net/wiki/display/eng/Transaction+Trace+Collection+Improvements
|
|
38
|
+
*
|
|
39
|
+
* 5 Transaction Trace Guarantee
|
|
40
|
+
*
|
|
41
|
+
* For the initial experience problem, the Agent will sample up to 1
|
|
42
|
+
* transaction per minute until it has sampled 5 transactions. This
|
|
43
|
+
* guarantees that the agent will always report some transaction traces.
|
|
44
|
+
* There is no time out for this sampling period - the agent always
|
|
45
|
+
* samples until it has collected 5 transactions. The agent doesn't
|
|
46
|
+
* simply report the first 5 transactions that it sees because it's
|
|
47
|
+
* likely (particularly for a local dev test) that all 5 transactions
|
|
48
|
+
* would be associated with one request (a single web page and its
|
|
49
|
+
* resources).
|
|
50
|
+
*/
|
|
52
51
|
|
|
53
52
|
const config = opts.config
|
|
54
53
|
this.reported = 0
|
|
@@ -56,8 +55,7 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
56
55
|
|
|
57
56
|
// Setting up top n capacity.
|
|
58
57
|
this.capacity = 1
|
|
59
|
-
if (config.transaction_tracer &&
|
|
60
|
-
config.transaction_tracer.top_n) {
|
|
58
|
+
if (config.transaction_tracer && config.transaction_tracer.top_n) {
|
|
61
59
|
this.capacity = config.transaction_tracer.top_n
|
|
62
60
|
}
|
|
63
61
|
|
|
@@ -69,22 +67,22 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
* For every five harvest cycles (or "minutes"), if no new slow transactions
|
|
71
|
+
* have been added, reset the requestTime match and allow a new set of five
|
|
72
|
+
* to start populating the Top N Slow Trace list.
|
|
73
|
+
*/
|
|
76
74
|
resetTimingTracker() {
|
|
77
75
|
this.requestTimes = Object.create(null)
|
|
78
76
|
this.noTraceSubmitted = 0
|
|
79
77
|
}
|
|
80
78
|
|
|
81
79
|
/**
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
* Add a trace to the slow trace list, if and only if it fulfills the necessary
|
|
81
|
+
* criteria.
|
|
82
|
+
*
|
|
83
|
+
* @param {Transaction} transaction The transaction, which we need to check
|
|
84
|
+
* apdexT, as well as getting the trace.
|
|
85
|
+
*/
|
|
88
86
|
add(transaction) {
|
|
89
87
|
if (!transaction) {
|
|
90
88
|
return
|
|
@@ -124,8 +122,8 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
/**
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
* Reset the trace diversity settings.
|
|
126
|
+
*/
|
|
129
127
|
clear() {
|
|
130
128
|
this.trace = null
|
|
131
129
|
this.syntheticsTraces = []
|
|
@@ -184,10 +182,7 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
184
182
|
return null
|
|
185
183
|
}
|
|
186
184
|
|
|
187
|
-
return [
|
|
188
|
-
this.runId,
|
|
189
|
-
traces.map((trace) => trace.generateJSONSync())
|
|
190
|
-
]
|
|
185
|
+
return [this.runId, traces.map((trace) => trace.generateJSONSync())]
|
|
191
186
|
}
|
|
192
187
|
|
|
193
188
|
_toPayload(callback) {
|
|
@@ -209,75 +204,85 @@ class TransactionTraceAggregator extends TraceAggregator {
|
|
|
209
204
|
}
|
|
210
205
|
|
|
211
206
|
/**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
207
|
+
* Determine whether a new trace is more worth keeping than an old one.
|
|
208
|
+
* This gets called on every single transactionFinished event, so return as
|
|
209
|
+
* quickly as possible and call as few external functions as possible. On the
|
|
210
|
+
* converse, there's some complicated logic here, so spell things out.
|
|
211
|
+
*
|
|
212
|
+
* All specifications are from
|
|
213
|
+
* https://newrelic.atlassian.net/wiki/display/eng/Transaction+Trace+Collection+Improvements
|
|
214
|
+
*
|
|
215
|
+
* @param {string} name Name of this transaction's key metric.
|
|
216
|
+
* @param {number} duration Time the transaction took, in milliseconds.
|
|
217
|
+
* @param {number} apdexT Apdex tolerating threshold, in seconds.
|
|
218
|
+
*/
|
|
224
219
|
isBetter(name, duration, apdexT) {
|
|
225
220
|
/* 1. If the transaction duration is below the tracing threshold, the
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
221
|
+
* transaction is skipped.
|
|
222
|
+
*
|
|
223
|
+
* The threshold for slow traces defaults to apdex_f, which is 4 * apdex_t.
|
|
224
|
+
*/
|
|
230
225
|
const config = this.config.transaction_tracer
|
|
231
226
|
let isOverThreshold
|
|
232
227
|
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
228
|
+
if (
|
|
229
|
+
config &&
|
|
230
|
+
config.transaction_threshold != null &&
|
|
231
|
+
config.transaction_threshold !== 'apdex_f' &&
|
|
232
|
+
typeof config.transaction_threshold === 'number'
|
|
233
|
+
) {
|
|
237
234
|
isOverThreshold = duration >= config.transaction_threshold * TO_MILLIS
|
|
238
235
|
} else {
|
|
239
236
|
isOverThreshold = duration >= 4 * TO_MILLIS * apdexT
|
|
240
237
|
}
|
|
241
|
-
if (!isOverThreshold)
|
|
238
|
+
if (!isOverThreshold) {
|
|
239
|
+
return false
|
|
240
|
+
}
|
|
242
241
|
|
|
243
242
|
/* 2. If the transaction duration is less than the duration of the current
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
* slow transaction, the transaction is skipped.
|
|
244
|
+
*/
|
|
246
245
|
let slowerThanExisting = true
|
|
247
246
|
if (this.trace) {
|
|
248
247
|
slowerThanExisting = this.trace.getDurationInMillis() < duration
|
|
249
248
|
}
|
|
250
|
-
if (!slowerThanExisting)
|
|
249
|
+
if (!slowerThanExisting) {
|
|
250
|
+
return false
|
|
251
|
+
}
|
|
251
252
|
|
|
252
253
|
/* We always gather some slow transactions at the start, regardless of
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
* the size of Top N. This changes the behavior of the rest of the
|
|
255
|
+
* decision-making process in some subtle ways.
|
|
256
|
+
*/
|
|
256
257
|
const hasMetGuarantee = this.reported >= 5
|
|
257
258
|
|
|
258
259
|
/* 3. If the transaction's name is in the transaction map and its duration
|
|
259
|
-
|
|
260
|
-
|
|
260
|
+
* is less than the response time in the map, it is skipped.
|
|
261
|
+
*/
|
|
261
262
|
let slowerThanCaptured = true
|
|
262
263
|
if (hasMetGuarantee) {
|
|
263
264
|
if (this.requestTimes[name]) {
|
|
264
265
|
slowerThanCaptured = this.requestTimes[name] < duration
|
|
265
266
|
}
|
|
266
267
|
}
|
|
267
|
-
if (!slowerThanCaptured)
|
|
268
|
+
if (!slowerThanCaptured) {
|
|
269
|
+
return false
|
|
270
|
+
}
|
|
268
271
|
|
|
269
272
|
/* Not part of enumerated rules, but necessary for Top N support:
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
* Ensure this name is either already in the request time map
|
|
274
|
+
* or that the map still hasn't hit capacity.
|
|
275
|
+
*/
|
|
276
|
+
if (
|
|
277
|
+
hasMetGuarantee &&
|
|
278
|
+
!this.requestTimes[name] &&
|
|
279
|
+
Object.keys(this.requestTimes).length >= this.capacity
|
|
280
|
+
) {
|
|
276
281
|
return false
|
|
277
282
|
}
|
|
278
283
|
|
|
279
284
|
/* 4. The transaction is held as the slowest transaction.
|
|
280
|
-
|
|
285
|
+
*/
|
|
281
286
|
return true
|
|
282
287
|
}
|
|
283
288
|
}
|
|
@@ -60,7 +60,7 @@ class ExclusiveCalculator {
|
|
|
60
60
|
// of children left to process is 0).
|
|
61
61
|
while (--parent.childrenLeft === 0) {
|
|
62
62
|
// pull off the finished parent and assign the exclusive duration
|
|
63
|
-
const {segment: finishedParent, childPairs} = this.parentStack.pop()
|
|
63
|
+
const { segment: finishedParent, childPairs } = this.parentStack.pop()
|
|
64
64
|
const timer = finishedParent.timer
|
|
65
65
|
const finishedEnd = timer.getDurationInMillis() + timer.start
|
|
66
66
|
let duration = finishedParent.getDurationInMillis()
|
|
@@ -109,14 +109,11 @@ function merge(first, second) {
|
|
|
109
109
|
// N.B. this is destructive, it will be updating the end times for range arrays in
|
|
110
110
|
// the input arrays. If we need to reuse these arrays for anything, this behavior
|
|
111
111
|
// must be changed.
|
|
112
|
-
var currInterval =
|
|
113
|
-
? first[firstIdx++]
|
|
114
|
-
: second[secondIdx++]
|
|
112
|
+
var currInterval =
|
|
113
|
+
first[firstIdx][0] < second[secondIdx][0] ? first[firstIdx++] : second[secondIdx++]
|
|
115
114
|
|
|
116
115
|
while (firstIdx < first.length && secondIdx < second.length) {
|
|
117
|
-
var next = first[firstIdx][0] < second[secondIdx][0]
|
|
118
|
-
? first[firstIdx++]
|
|
119
|
-
: second[secondIdx++]
|
|
116
|
+
var next = first[firstIdx][0] < second[secondIdx][0] ? first[firstIdx++] : second[secondIdx++]
|
|
120
117
|
if (next[0] <= currInterval[1]) {
|
|
121
118
|
// if the segment overlaps, update the end of the current merged segment
|
|
122
119
|
currInterval[1] = Math.max(next[1], currInterval[1])
|
|
@@ -127,7 +124,6 @@ function merge(first, second) {
|
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
|
|
130
|
-
|
|
131
127
|
const firstIsRemainder = firstIdx !== first.length
|
|
132
128
|
const remainder = firstIsRemainder ? first : second
|
|
133
129
|
let remainderIdx = firstIsRemainder ? firstIdx : secondIdx
|
|
@@ -140,7 +136,7 @@ function merge(first, second) {
|
|
|
140
136
|
res[resIdx++] = currInterval
|
|
141
137
|
|
|
142
138
|
// append the remaining non-overlapping ranges
|
|
143
|
-
for (;remainderIdx < remainder.length; ++remainderIdx) {
|
|
139
|
+
for (; remainderIdx < remainder.length; ++remainderIdx) {
|
|
144
140
|
res[resIdx++] = remainder[remainderIdx]
|
|
145
141
|
}
|
|
146
142
|
|
|
@@ -7,11 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
var codec = require('../../util/codec')
|
|
9
9
|
var Segment = require('./segment')
|
|
10
|
-
var {Attributes, MAXIMUM_CUSTOM_ATTRIBUTES} = require('../../attributes')
|
|
11
|
-
var logger = require('../../logger').child({component: 'trace'})
|
|
10
|
+
var { Attributes, MAXIMUM_CUSTOM_ATTRIBUTES } = require('../../attributes')
|
|
11
|
+
var logger = require('../../logger').child({ component: 'trace' })
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
var {DESTINATIONS} = require('../../config/attribute-filter')
|
|
13
|
+
var { DESTINATIONS } = require('../../config/attribute-filter')
|
|
15
14
|
var FROM_MILLIS = 1e-3
|
|
16
15
|
const ATTRIBUTE_SCOPE = 'transaction'
|
|
17
16
|
|
|
@@ -25,7 +24,9 @@ const UNKNOWN_URI_PLACEHOLDER = '/Unknown'
|
|
|
25
24
|
* @param {Transaction} transaction The transaction bound to the trace.
|
|
26
25
|
*/
|
|
27
26
|
function Trace(transaction) {
|
|
28
|
-
if (!transaction)
|
|
27
|
+
if (!transaction) {
|
|
28
|
+
throw new Error('All traces must be associated with a transaction.')
|
|
29
|
+
}
|
|
29
30
|
|
|
30
31
|
this.transaction = transaction
|
|
31
32
|
|
|
@@ -43,11 +44,7 @@ function Trace(transaction) {
|
|
|
43
44
|
var displayName = transaction.agent.config.getDisplayHost()
|
|
44
45
|
var hostName = transaction.agent.config.getHostnameSafe()
|
|
45
46
|
if (displayName !== hostName) {
|
|
46
|
-
this.attributes.addAttribute(
|
|
47
|
-
DESTINATIONS.TRANS_COMMON,
|
|
48
|
-
'host.displayName',
|
|
49
|
-
displayName
|
|
50
|
-
)
|
|
47
|
+
this.attributes.addAttribute(DESTINATIONS.TRANS_COMMON, 'host.displayName', displayName)
|
|
51
48
|
|
|
52
49
|
this.displayName = displayName
|
|
53
50
|
}
|
|
@@ -198,7 +195,6 @@ Trace.prototype.getExclusiveDurationInMillis = function getExclusiveDurationInMi
|
|
|
198
195
|
return this.root.getExclusiveDurationInMillis()
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
|
|
202
198
|
/**
|
|
203
199
|
* The duration of all segments in a transaction trace. The root is not
|
|
204
200
|
* accounted for, since it doesn't represent a unit of work.
|
|
@@ -207,8 +203,12 @@ Trace.prototype.getExclusiveDurationInMillis = function getExclusiveDurationInMi
|
|
|
207
203
|
* milliseconds
|
|
208
204
|
*/
|
|
209
205
|
Trace.prototype.getTotalTimeDurationInMillis = function getTotalTimeDurationInMillis() {
|
|
210
|
-
if (this.totalTimeCache !== null)
|
|
211
|
-
|
|
206
|
+
if (this.totalTimeCache !== null) {
|
|
207
|
+
return this.totalTimeCache
|
|
208
|
+
}
|
|
209
|
+
if (this.root.children.length === 0) {
|
|
210
|
+
return 0
|
|
211
|
+
}
|
|
212
212
|
var segments = this.root.getChildren()
|
|
213
213
|
var totalTimeInMillis = 0
|
|
214
214
|
|
|
@@ -218,7 +218,9 @@ Trace.prototype.getTotalTimeDurationInMillis = function getTotalTimeDurationInMi
|
|
|
218
218
|
segments = segments.concat(segment.getChildren())
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
if (!this.transaction.isActive())
|
|
221
|
+
if (!this.transaction.isActive()) {
|
|
222
|
+
this.totalTimeCache = totalTimeInMillis
|
|
223
|
+
}
|
|
222
224
|
return totalTimeInMillis
|
|
223
225
|
}
|
|
224
226
|
|
|
@@ -299,15 +301,15 @@ Trace.prototype._generatePayload = function _generatePayload(data) {
|
|
|
299
301
|
|
|
300
302
|
return [
|
|
301
303
|
this.root.timer.start, // start
|
|
302
|
-
this.transaction.getResponseTimeInMillis(),
|
|
303
|
-
this.transaction.getFullName(),
|
|
304
|
-
requestUri,
|
|
305
|
-
data,
|
|
306
|
-
this.transaction.id,
|
|
307
|
-
null,
|
|
308
|
-
false,
|
|
309
|
-
null,
|
|
310
|
-
syntheticsResourceId
|
|
304
|
+
this.transaction.getResponseTimeInMillis(), // response time
|
|
305
|
+
this.transaction.getFullName(), // path
|
|
306
|
+
requestUri, // request.uri
|
|
307
|
+
data, // encodedCompressedData
|
|
308
|
+
this.transaction.id, // guid
|
|
309
|
+
null, // reserved for future use
|
|
310
|
+
false, // forcePersist
|
|
311
|
+
null, // xraySessionId
|
|
312
|
+
syntheticsResourceId // synthetics resource id
|
|
311
313
|
]
|
|
312
314
|
}
|
|
313
315
|
|
|
@@ -353,7 +355,7 @@ Trace.prototype._serializeTrace = function _serializeTrace() {
|
|
|
353
355
|
}, // moved to userAttributes
|
|
354
356
|
this.root.toJSON(),
|
|
355
357
|
attributes,
|
|
356
|
-
[]
|
|
358
|
+
[] // FIXME: parameter groups
|
|
357
359
|
]
|
|
358
360
|
}
|
|
359
361
|
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const {DESTINATIONS} = require('../../config/attribute-filter')
|
|
9
|
-
const logger = require('../../logger').child({component: 'segment'})
|
|
8
|
+
const { DESTINATIONS } = require('../../config/attribute-filter')
|
|
9
|
+
const logger = require('../../logger').child({ component: 'segment' })
|
|
10
10
|
const Timer = require('../../timer')
|
|
11
11
|
const urltils = require('../../util/urltils')
|
|
12
12
|
const hashes = require('../../util/hashes')
|
|
13
13
|
|
|
14
|
-
const {Attributes} = require('../../attributes')
|
|
14
|
+
const { Attributes } = require('../../attributes')
|
|
15
15
|
const ExclusiveCalculator = require('./exclusive-time-calculator')
|
|
16
16
|
const SpanContext = require('../../spans/span-context')
|
|
17
17
|
|
|
@@ -23,7 +23,6 @@ const STATE = {
|
|
|
23
23
|
}
|
|
24
24
|
const ATTRIBUTE_SCOPE = 'segment'
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
/**
|
|
28
27
|
* Initializes the segment and binds the recorder to itself, if provided.
|
|
29
28
|
*
|
|
@@ -93,32 +92,20 @@ TraceSegment.prototype.getSpanContext = function getSpanContext() {
|
|
|
93
92
|
return this._spanContext
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
TraceSegment.prototype.addAttribute =
|
|
97
|
-
|
|
98
|
-
this.attributes.addAttribute(
|
|
99
|
-
DESTINATIONS.SEGMENT_SCOPE,
|
|
100
|
-
key,
|
|
101
|
-
value,
|
|
102
|
-
truncateExempt
|
|
103
|
-
)
|
|
95
|
+
TraceSegment.prototype.addAttribute = function addAttribute(key, value, truncateExempt = false) {
|
|
96
|
+
this.attributes.addAttribute(DESTINATIONS.SEGMENT_SCOPE, key, value, truncateExempt)
|
|
104
97
|
}
|
|
105
98
|
|
|
106
|
-
TraceSegment.prototype.addSpanAttribute =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
truncateExempt
|
|
113
|
-
)
|
|
99
|
+
TraceSegment.prototype.addSpanAttribute = function addSpanAttribute(
|
|
100
|
+
key,
|
|
101
|
+
value,
|
|
102
|
+
truncateExempt = false
|
|
103
|
+
) {
|
|
104
|
+
this.attributes.addAttribute(DESTINATIONS.SPAN_EVENT, key, value, truncateExempt)
|
|
114
105
|
}
|
|
115
106
|
|
|
116
|
-
TraceSegment.prototype.addSpanAttributes =
|
|
117
|
-
|
|
118
|
-
this.attributes.addAttributes(
|
|
119
|
-
DESTINATIONS.SPAN_EVENT,
|
|
120
|
-
attributes
|
|
121
|
-
)
|
|
107
|
+
TraceSegment.prototype.addSpanAttributes = function addSpanAttributes(attributes) {
|
|
108
|
+
this.attributes.addAttributes(DESTINATIONS.SPAN_EVENT, attributes)
|
|
122
109
|
}
|
|
123
110
|
|
|
124
111
|
TraceSegment.prototype.getAttributes = function getAttributes() {
|
|
@@ -157,7 +144,7 @@ function captureDBInstanceAttributes(host, port, database) {
|
|
|
157
144
|
if (database !== false && dsTracerConf.database_name_reporting.enabled) {
|
|
158
145
|
this.addAttribute(
|
|
159
146
|
'database_name',
|
|
160
|
-
typeof database === 'number' ? database :
|
|
147
|
+
typeof database === 'number' ? database : database || INSTANCE_UNKNOWN
|
|
161
148
|
)
|
|
162
149
|
}
|
|
163
150
|
|
|
@@ -168,7 +155,8 @@ function captureDBInstanceAttributes(host, port, database) {
|
|
|
168
155
|
if (host && urltils.isLocalhost(host)) {
|
|
169
156
|
host = config.getHostnameSafe(host)
|
|
170
157
|
}
|
|
171
|
-
if (!host || host === 'UNKNOWN_BOX') {
|
|
158
|
+
if (!host || host === 'UNKNOWN_BOX') {
|
|
159
|
+
// Config's default name of a host.
|
|
172
160
|
host = INSTANCE_UNKNOWN
|
|
173
161
|
}
|
|
174
162
|
|
|
@@ -187,11 +175,10 @@ TraceSegment.prototype.isInCallbackState = function isInCallbackState() {
|
|
|
187
175
|
|
|
188
176
|
TraceSegment.prototype.probe = function probe(action) {
|
|
189
177
|
if (this.transaction.traceStacks) {
|
|
190
|
-
this.transaction.probe(action, {segment: this.name})
|
|
178
|
+
this.transaction.probe(action, { segment: this.name })
|
|
191
179
|
}
|
|
192
180
|
}
|
|
193
181
|
|
|
194
|
-
|
|
195
182
|
/**
|
|
196
183
|
* For use when a transaction is ending. The transaction segment should
|
|
197
184
|
* be named after the transaction it belongs to (which is only known by
|
|
@@ -243,7 +230,6 @@ function overwriteDurationInMillis(duration, start) {
|
|
|
243
230
|
this.timer.overwriteDurationInMillis(duration, start)
|
|
244
231
|
}
|
|
245
232
|
|
|
246
|
-
|
|
247
233
|
TraceSegment.prototype.start = function start() {
|
|
248
234
|
this.timer.begin()
|
|
249
235
|
}
|
|
@@ -252,7 +238,9 @@ TraceSegment.prototype.start = function start() {
|
|
|
252
238
|
* Stop timing the related action.
|
|
253
239
|
*/
|
|
254
240
|
TraceSegment.prototype.end = function end() {
|
|
255
|
-
if (!this.timer.isActive())
|
|
241
|
+
if (!this.timer.isActive()) {
|
|
242
|
+
return
|
|
243
|
+
}
|
|
256
244
|
this.probe('Ended')
|
|
257
245
|
this.timer.end()
|
|
258
246
|
this._updateRootTimer()
|
|
@@ -266,10 +254,7 @@ TraceSegment.prototype.finalize = function finalize() {
|
|
|
266
254
|
this.name = NAMES.TRUNCATED.PREFIX + this.name
|
|
267
255
|
}
|
|
268
256
|
|
|
269
|
-
this.addAttribute(
|
|
270
|
-
'nr_exclusive_duration_millis',
|
|
271
|
-
this.getExclusiveDurationInMillis()
|
|
272
|
-
)
|
|
257
|
+
this.addAttribute('nr_exclusive_duration_millis', this.getExclusiveDurationInMillis())
|
|
273
258
|
}
|
|
274
259
|
|
|
275
260
|
/**
|
|
@@ -279,11 +264,7 @@ TraceSegment.prototype.finalize = function finalize() {
|
|
|
279
264
|
TraceSegment.prototype._updateRootTimer = function _updateRootTimer() {
|
|
280
265
|
var root = this.transaction.trace.root
|
|
281
266
|
if (this.timer.endsAfter(root.timer)) {
|
|
282
|
-
var newDuration = (
|
|
283
|
-
this.timer.start +
|
|
284
|
-
this.getDurationInMillis() -
|
|
285
|
-
root.timer.start
|
|
286
|
-
)
|
|
267
|
+
var newDuration = this.timer.start + this.getDurationInMillis() - root.timer.start
|
|
287
268
|
root.overwriteDurationInMillis(newDuration)
|
|
288
269
|
}
|
|
289
270
|
}
|
|
@@ -400,8 +381,12 @@ TraceSegment.prototype.getCollectedChildren = function getCollectedChildren() {
|
|
|
400
381
|
*/
|
|
401
382
|
TraceSegment.prototype._getChildPairs = function _getChildPairs(end) {
|
|
402
383
|
// quick optimization
|
|
403
|
-
if (this.children.length < 1)
|
|
404
|
-
|
|
384
|
+
if (this.children.length < 1) {
|
|
385
|
+
return []
|
|
386
|
+
}
|
|
387
|
+
if (!end) {
|
|
388
|
+
end = Infinity
|
|
389
|
+
}
|
|
405
390
|
|
|
406
391
|
var children = this.getChildren()
|
|
407
392
|
var childPairs = []
|
|
@@ -409,7 +394,9 @@ TraceSegment.prototype._getChildPairs = function _getChildPairs(end) {
|
|
|
409
394
|
var child = children.pop()
|
|
410
395
|
var pair = child.timer.toRange()
|
|
411
396
|
|
|
412
|
-
if (pair[0] >= end)
|
|
397
|
+
if (pair[0] >= end) {
|
|
398
|
+
continue
|
|
399
|
+
}
|
|
413
400
|
|
|
414
401
|
children = children.concat(child.getChildren())
|
|
415
402
|
|
|
@@ -450,13 +437,15 @@ TraceSegment.prototype.toJSON = function toJSON() {
|
|
|
450
437
|
const resultDest = []
|
|
451
438
|
// array of objects relating a segment and the destination for its
|
|
452
439
|
// serialized data.
|
|
453
|
-
const segmentsToProcess = [
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
440
|
+
const segmentsToProcess = [
|
|
441
|
+
{
|
|
442
|
+
segment: this,
|
|
443
|
+
destination: resultDest
|
|
444
|
+
}
|
|
445
|
+
]
|
|
457
446
|
|
|
458
447
|
while (segmentsToProcess.length !== 0) {
|
|
459
|
-
const {segment, destination} = segmentsToProcess.pop()
|
|
448
|
+
const { segment, destination } = segmentsToProcess.pop()
|
|
460
449
|
|
|
461
450
|
const start = segment.timer.startedRelativeTo(segment.transaction.trace.root.timer)
|
|
462
451
|
const duration = segment.getDurationInMillis()
|
|
@@ -465,13 +454,7 @@ TraceSegment.prototype.toJSON = function toJSON() {
|
|
|
465
454
|
const childArray = []
|
|
466
455
|
|
|
467
456
|
// push serialized data into the specified destination
|
|
468
|
-
destination.push([
|
|
469
|
-
start,
|
|
470
|
-
start + duration,
|
|
471
|
-
segment.name,
|
|
472
|
-
segment.getAttributes(),
|
|
473
|
-
childArray
|
|
474
|
-
])
|
|
457
|
+
destination.push([start, start + duration, segment.name, segment.getAttributes(), childArray])
|
|
475
458
|
|
|
476
459
|
if (segmentChildren.length) {
|
|
477
460
|
// push the children and the parent's children array into the stack.
|