newrelic 4.5.0 → 4.8.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 +153 -1
- package/api.js +8 -1
- package/bin/compare-bench-results.js +159 -0
- package/bin/run-bench.js +87 -44
- package/index.js +16 -8
- package/lib/agent.js +1 -1
- package/lib/collector/remote-method.js +12 -0
- package/lib/config/default.js +17 -0
- package/lib/config/env.js +4 -0
- package/lib/config/index.js +3 -0
- package/lib/db/tracer.js +15 -6
- package/lib/environment.js +1 -1
- package/lib/errors/index.js +1 -1
- package/lib/feature_flags.js +0 -1
- package/lib/harvest.js +36 -18
- package/lib/instrumentation/core/crypto.js +2 -1
- package/lib/instrumentation/core/fs.js +7 -2
- package/lib/instrumentation/core/globals.js +17 -1
- package/lib/instrumentation/core/http-outbound.js +102 -3
- package/lib/instrumentation/core/http.js +6 -96
- package/lib/instrumentation/mongodb.js +158 -115
- package/lib/metrics/recorders/http.js +1 -1
- package/lib/metrics/recorders/other.js +1 -1
- package/lib/priority-queue.js +5 -2
- package/lib/shim/message-shim.js +5 -4
- package/lib/shim/shim.js +14 -3
- package/lib/shim/specs/index.js +1 -0
- package/lib/shim/transaction-shim.js +3 -3
- package/lib/shimmer.js +3 -0
- package/lib/transaction/dt-payload.js +16 -0
- package/lib/transaction/handle.js +1 -1
- package/lib/transaction/index.js +8 -4
- package/lib/transaction/trace/index.js +31 -38
- package/package.json +3 -2
- package/.npmignore +0 -4
package/lib/db/tracer.js
CHANGED
|
@@ -46,27 +46,36 @@ QueryTracer.prototype.merge = function merge(tracer) {
|
|
|
46
46
|
|
|
47
47
|
QueryTracer.prototype.addQuery = function addQuery(segment, type, query, trace) {
|
|
48
48
|
const ttConfig = this.config.transaction_tracer
|
|
49
|
-
if (segment.getDurationInMillis() < ttConfig.explain_threshold) {
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
const slowQuery = new SlowQuery(segment, type, query, trace)
|
|
53
49
|
|
|
50
|
+
// If DT is enabled and the segment is part of a sampled transaction
|
|
51
|
+
// (i.e. we are creating a span event for this segment), then we need
|
|
52
|
+
// to collect the sql trace.
|
|
53
|
+
var slowQuery
|
|
54
54
|
switch (ttConfig.record_sql) {
|
|
55
55
|
case 'raw':
|
|
56
|
+
slowQuery = new SlowQuery(segment, type, query, trace)
|
|
56
57
|
logger.trace('recording raw sql')
|
|
57
58
|
segment.parameters.sql = slowQuery.query
|
|
58
59
|
break
|
|
59
60
|
case 'obfuscated':
|
|
61
|
+
slowQuery = new SlowQuery(segment, type, query, trace)
|
|
60
62
|
logger.trace('recording obfuscated sql')
|
|
61
63
|
segment.parameters.sql_obfuscated = slowQuery.obfuscated
|
|
62
64
|
break
|
|
63
65
|
default:
|
|
64
66
|
logger.trace(
|
|
65
|
-
'not
|
|
67
|
+
'not recording sql statement, transaction_tracer.record_sql was set to %s',
|
|
66
68
|
ttConfig.record_sql
|
|
67
69
|
)
|
|
68
70
|
return
|
|
69
71
|
}
|
|
72
|
+
|
|
73
|
+
if (segment.getDurationInMillis() < ttConfig.explain_threshold) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
slowQuery = slowQuery || new SlowQuery(segment, type, query, trace)
|
|
78
|
+
|
|
70
79
|
segment.parameters.backtrace = slowQuery.trace
|
|
71
80
|
|
|
72
81
|
if (!this.config.slow_sql.enabled) {
|
|
@@ -158,7 +167,7 @@ QuerySample.prototype.getParams = function getParams() {
|
|
|
158
167
|
params.database_name = segmentParams.database_name
|
|
159
168
|
}
|
|
160
169
|
|
|
161
|
-
if (this.tracer.config.
|
|
170
|
+
if (this.tracer.config.distributed_tracing.enabled) {
|
|
162
171
|
this.trace.segment.transaction.addDistributedTraceIntrinsics(params)
|
|
163
172
|
}
|
|
164
173
|
|
package/lib/environment.js
CHANGED
|
@@ -305,7 +305,7 @@ function getGlobalPackages(cb) {
|
|
|
305
305
|
* package appears at most once, with all the versions joined into a
|
|
306
306
|
* comma-delimited list.
|
|
307
307
|
*
|
|
308
|
-
* @return {Array.<
|
|
308
|
+
* @return {Array.<string[]>} Sorted list of [name, version] pairs.
|
|
309
309
|
*/
|
|
310
310
|
function flattenVersions(packages) {
|
|
311
311
|
var info = Object.create(null)
|
package/lib/errors/index.js
CHANGED
|
@@ -170,7 +170,7 @@ function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, timestam
|
|
|
170
170
|
attributes["nr.syntheticsMonitorId"] = transaction.syntheticsData.monitorId
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
if (transaction.agent.config.
|
|
173
|
+
if (transaction.agent.config.distributed_tracing.enabled) {
|
|
174
174
|
transaction.addDistributedTraceIntrinsics(attributes)
|
|
175
175
|
} else {
|
|
176
176
|
attributes['nr.referringTransactionGuid'] = transaction.referringTransactionGuid
|
package/lib/feature_flags.js
CHANGED
package/lib/harvest.js
CHANGED
|
@@ -76,7 +76,9 @@ class Harvest {
|
|
|
76
76
|
if (this._events) {
|
|
77
77
|
for (let i = 0; i < this._events.length; ++i) {
|
|
78
78
|
if (this._events[i]) {
|
|
79
|
-
this.agent.events.merge(
|
|
79
|
+
this.agent.events.merge(
|
|
80
|
+
this._events[i].toMerge
|
|
81
|
+
)
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -359,7 +361,8 @@ class Harvest {
|
|
|
359
361
|
|
|
360
362
|
const self = this
|
|
361
363
|
const agent = this.agent
|
|
362
|
-
a.eachOfSeries(this._events, function sendEachPayload(
|
|
364
|
+
a.eachOfSeries(this._events, function sendEachPayload(obj, i, cb) {
|
|
365
|
+
const payload = obj.payload
|
|
363
366
|
agent.collector.analyticsEvents(payload, function onAnalyticsEvents(err) {
|
|
364
367
|
if (self._shouldClearData(err, 'events')) {
|
|
365
368
|
self._events[i] = null
|
|
@@ -469,7 +472,7 @@ class Harvest {
|
|
|
469
472
|
|
|
470
473
|
_sendSpanEvents(callback) {
|
|
471
474
|
const config = this.agent.config
|
|
472
|
-
if (!config.span_events.enabled || !config.
|
|
475
|
+
if (!config.span_events.enabled || !config.distributed_tracing.enabled) {
|
|
473
476
|
logger.debug('Span events collection disabled.')
|
|
474
477
|
this._spanEventsQueues = null
|
|
475
478
|
return setImmediate(callback)
|
|
@@ -519,28 +522,43 @@ class Harvest {
|
|
|
519
522
|
return []
|
|
520
523
|
}
|
|
521
524
|
if (queue.length < queue.limit / 3) {
|
|
522
|
-
return [
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
525
|
+
return [{
|
|
526
|
+
toMerge: queue,
|
|
527
|
+
payload: [
|
|
528
|
+
this.agent.config.run_id,
|
|
529
|
+
{reservoir_size: queue.limit, events_seen: queue.seen},
|
|
530
|
+
queue.toArray()
|
|
531
|
+
]
|
|
532
|
+
}]
|
|
527
533
|
}
|
|
528
534
|
|
|
529
535
|
// Our payload is large, so split it in half.
|
|
530
|
-
|
|
536
|
+
// TODO: update this to pull the priority off the event when DT is released
|
|
537
|
+
const events = queue.getRawEvents()
|
|
531
538
|
const size = Math.floor(queue.length / 2)
|
|
532
539
|
const limit = Math.floor(queue.limit / 2)
|
|
533
540
|
const seen = Math.floor(queue.seen / 2)
|
|
541
|
+
const firstHalf = events.splice(0, size)
|
|
534
542
|
|
|
535
|
-
return [
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
543
|
+
return [{
|
|
544
|
+
toMerge: firstHalf,
|
|
545
|
+
payload: [
|
|
546
|
+
this.agent.config.run_id,
|
|
547
|
+
{reservoir_size: limit, events_seen: seen},
|
|
548
|
+
firstHalf.map(rawEventsToValues)
|
|
549
|
+
]
|
|
550
|
+
}, {
|
|
551
|
+
toMerge: events,
|
|
552
|
+
payload: [
|
|
553
|
+
this.agent.config.run_id,
|
|
554
|
+
{reservoir_size: queue.limit - limit, events_seen: queue.seen - seen},
|
|
555
|
+
events.map(rawEventsToValues)
|
|
556
|
+
]
|
|
557
|
+
}]
|
|
558
|
+
|
|
559
|
+
function rawEventsToValues(ev) {
|
|
560
|
+
return ev.value
|
|
561
|
+
}
|
|
544
562
|
}
|
|
545
563
|
}
|
|
546
564
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
var record = require('../../metrics/recorders/generic
|
|
4
|
-
var NAMES = require('../../metrics/names
|
|
3
|
+
var record = require('../../metrics/recorders/generic')
|
|
4
|
+
var NAMES = require('../../metrics/names')
|
|
5
5
|
var wrap = require('../../shimmer').wrapMethod
|
|
6
6
|
|
|
7
7
|
module.exports = initialize
|
|
@@ -46,6 +46,7 @@ function initialize(agent, fs) {
|
|
|
46
46
|
]
|
|
47
47
|
|
|
48
48
|
wrap(fs, 'fs', methods, segment)
|
|
49
|
+
wrap(fs.realpath, 'fs.realpath', 'native', wrapRealPathNative)
|
|
49
50
|
wrap(fs, 'fs', uninstrumented, agent.tracer.wrapFunctionNoSegment.bind(agent.tracer))
|
|
50
51
|
wrap(fs, 'fs', ['watch'], wrapWatch)
|
|
51
52
|
wrap(fs, 'fs', ['watchFile'], wrapWatchFile)
|
|
@@ -54,6 +55,10 @@ function initialize(agent, fs) {
|
|
|
54
55
|
return agent.tracer.wrapFunctionLast(NAMES.FS.PREFIX + method, record, fn)
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
function wrapRealPathNative(fn) {
|
|
59
|
+
return segment(fn, 'realpath.native')
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
function wrapWatch(fn) {
|
|
58
63
|
return function wrappedWatch() {
|
|
59
64
|
var args = agent.tracer.slice(arguments)
|
|
@@ -8,6 +8,8 @@ module.exports = initialize
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
function initialize(agent) {
|
|
11
|
+
let exceptionCallbackRegistered = false
|
|
12
|
+
|
|
11
13
|
// `_fatalException` is an undocumented feature of domains, introduced in
|
|
12
14
|
// Node.js v0.8. We use `_fatalException` because wrapping it will not
|
|
13
15
|
// potentially change the behavior of the server unlike listening for
|
|
@@ -16,7 +18,7 @@ function initialize(agent) {
|
|
|
16
18
|
return function wrappedFatalException(error) {
|
|
17
19
|
// Only record the error if we are not currently within an instrumented
|
|
18
20
|
// domain.
|
|
19
|
-
if (!process.domain) {
|
|
21
|
+
if (!process.domain && !exceptionCallbackRegistered) {
|
|
20
22
|
agent.errors.add(null, error)
|
|
21
23
|
agent.tracer.segment = null
|
|
22
24
|
}
|
|
@@ -45,6 +47,20 @@ function initialize(agent) {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
|
|
50
|
+
shimmer.wrapMethod(
|
|
51
|
+
process,
|
|
52
|
+
'process',
|
|
53
|
+
'setUncaughtExceptionCaptureCallback',
|
|
54
|
+
wrapUncaughtExceptionCallback
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
function wrapUncaughtExceptionCallback(original) {
|
|
58
|
+
return function wrapped(fn) {
|
|
59
|
+
exceptionCallbackRegistered = fn !== null
|
|
60
|
+
return original.apply(this, arguments)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
// This will initialize the most optimal native-promise instrumentation that
|
|
49
65
|
// we have available.
|
|
50
66
|
asyncHooks(agent)
|
|
@@ -6,11 +6,19 @@ var urltils = require('../../util/urltils')
|
|
|
6
6
|
var hashes = require('../../util/hashes')
|
|
7
7
|
var logger = require('../../logger').child({component: 'outbound'})
|
|
8
8
|
var shimmer = require('../../shimmer')
|
|
9
|
+
var util = require('util')
|
|
10
|
+
var url = require('url')
|
|
11
|
+
var copy = require('../../util/copy')
|
|
9
12
|
|
|
10
13
|
const DEFAULT_HOST = 'localhost'
|
|
11
14
|
const DEFAULT_PORT = 80
|
|
12
15
|
const DEFAULT_SSL_PORT = 443
|
|
13
16
|
|
|
17
|
+
const NEWRELIC_ID_HEADER = 'x-newrelic-id'
|
|
18
|
+
const NEWRELIC_TRACE_HEADER = 'newrelic'
|
|
19
|
+
const NEWRELIC_TRANSACTION_HEADER = 'x-newrelic-transaction'
|
|
20
|
+
const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
|
|
21
|
+
|
|
14
22
|
/**
|
|
15
23
|
* Instruments an outbound HTTP request.
|
|
16
24
|
*
|
|
@@ -21,6 +29,12 @@ const DEFAULT_SSL_PORT = 443
|
|
|
21
29
|
* @return {http.ClientRequest} The instrumented outbound request.
|
|
22
30
|
*/
|
|
23
31
|
module.exports = function instrumentOutbound(agent, opts, makeRequest) {
|
|
32
|
+
if (typeof opts === 'string') {
|
|
33
|
+
opts = url.parse(opts)
|
|
34
|
+
} else {
|
|
35
|
+
opts = copy.shallow(opts)
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
let hostname = opts.hostname || opts.host || DEFAULT_HOST
|
|
25
39
|
let port = opts.port || opts.defaultPort
|
|
26
40
|
if (!port) {
|
|
@@ -32,7 +46,7 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
|
|
|
32
46
|
'Invalid host name (%s) or port (%s) for outbound request.',
|
|
33
47
|
hostname, port
|
|
34
48
|
)
|
|
35
|
-
return makeRequest()
|
|
49
|
+
return makeRequest(opts)
|
|
36
50
|
}
|
|
37
51
|
|
|
38
52
|
// Technically we shouldn't append the port if this is an https request on 443
|
|
@@ -54,8 +68,48 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
|
|
|
54
68
|
)
|
|
55
69
|
|
|
56
70
|
function instrumentRequest(segment) {
|
|
71
|
+
const transaction = segment.transaction
|
|
72
|
+
const outboundHeaders = Object.create(null)
|
|
73
|
+
|
|
74
|
+
// FLAG: synthetics
|
|
75
|
+
if (
|
|
76
|
+
agent.config.feature_flag.synthetics &&
|
|
77
|
+
agent.config.encoding_key &&
|
|
78
|
+
transaction.syntheticsHeader
|
|
79
|
+
) {
|
|
80
|
+
outboundHeaders[NEWRELIC_SYNTHETICS_HEADER] = transaction.syntheticsHeader
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// If CAT is enabled, inject the transaction header.
|
|
84
|
+
// TODO: abstract header logic shared with TransactionShim#insertCATRequestHeaders
|
|
85
|
+
if (agent.config.cross_application_tracer.enabled) {
|
|
86
|
+
if (agent.config.distributed_tracing.enabled) {
|
|
87
|
+
_addDistributedHeaders(transaction, outboundHeaders)
|
|
88
|
+
} else if (agent.config.encoding_key) {
|
|
89
|
+
_addCATHeaders(agent, transaction, outboundHeaders)
|
|
90
|
+
} else {
|
|
91
|
+
logger.trace('No encoding key found, not adding CAT headers')
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (util.isArray(opts.headers)) {
|
|
96
|
+
opts.headers = opts.headers.slice()
|
|
97
|
+
Array.prototype.push.apply(
|
|
98
|
+
opts.headers,
|
|
99
|
+
Object.keys(outboundHeaders).map(function getHeaderTuples(key) {
|
|
100
|
+
return [key, outboundHeaders[key]]
|
|
101
|
+
})
|
|
102
|
+
)
|
|
103
|
+
} else {
|
|
104
|
+
opts.headers = Object.assign(
|
|
105
|
+
Object.create(null),
|
|
106
|
+
opts.headers,
|
|
107
|
+
outboundHeaders
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
57
111
|
segment.start()
|
|
58
|
-
const request = makeRequest()
|
|
112
|
+
const request = makeRequest(opts)
|
|
59
113
|
const parsed = urltils.scrubAndParseParameters(request.path)
|
|
60
114
|
const proto = parsed.protocol || opts.protocol || 'http:'
|
|
61
115
|
segment.name += parsed.path
|
|
@@ -129,7 +183,7 @@ function handleResponse(segment, hostname, req, res) {
|
|
|
129
183
|
const agent = segment.transaction.agent
|
|
130
184
|
if (
|
|
131
185
|
agent.config.cross_application_tracer.enabled &&
|
|
132
|
-
!agent.config.
|
|
186
|
+
!agent.config.distributed_tracing.enabled
|
|
133
187
|
) {
|
|
134
188
|
pullCatHeaders(agent.config, segment, hostname, res.headers['x-newrelic-app-data'])
|
|
135
189
|
}
|
|
@@ -202,3 +256,48 @@ function _makeNonEnumerable(obj, prop) {
|
|
|
202
256
|
logger.debug(e, 'Failed to make %s non enumerable.', prop)
|
|
203
257
|
}
|
|
204
258
|
}
|
|
259
|
+
|
|
260
|
+
function _addDistributedHeaders(tx, outboundHeaders) {
|
|
261
|
+
try {
|
|
262
|
+
const txData = tx.createDistributedTracePayload().httpSafe()
|
|
263
|
+
outboundHeaders[NEWRELIC_TRACE_HEADER] = txData
|
|
264
|
+
|
|
265
|
+
logger.trace(
|
|
266
|
+
'Added outbound request distributed tracing headers in transaction %s',
|
|
267
|
+
tx.id
|
|
268
|
+
)
|
|
269
|
+
} catch (err) {
|
|
270
|
+
logger.trace(err, 'Failed to create distributed trace payload')
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function _addCATHeaders(agent, tx, outboundHeaders) {
|
|
275
|
+
if (agent.config.obfuscatedId) {
|
|
276
|
+
outboundHeaders[NEWRELIC_ID_HEADER] = agent.config.obfuscatedId
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
var pathHash = hashes.calculatePathHash(
|
|
280
|
+
agent.config.applications()[0],
|
|
281
|
+
tx.getFullName() || '',
|
|
282
|
+
tx.referringPathHash
|
|
283
|
+
)
|
|
284
|
+
tx.pushPathHash(pathHash)
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
let txData = JSON.stringify([
|
|
288
|
+
tx.id,
|
|
289
|
+
false,
|
|
290
|
+
tx.tripId || tx.id,
|
|
291
|
+
pathHash
|
|
292
|
+
])
|
|
293
|
+
txData = hashes.obfuscateNameUsingKey(txData, agent.config.encoding_key)
|
|
294
|
+
outboundHeaders[NEWRELIC_TRANSACTION_HEADER] = txData
|
|
295
|
+
|
|
296
|
+
logger.trace(
|
|
297
|
+
'Added outbound request CAT headers in transaction %s',
|
|
298
|
+
tx.id
|
|
299
|
+
)
|
|
300
|
+
} catch (err) {
|
|
301
|
+
logger.trace(err, 'Failed to create CAT payload')
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -11,7 +11,6 @@ var url = require('url')
|
|
|
11
11
|
var urltils = require('../../util/urltils')
|
|
12
12
|
var properties = require('../../util/properties')
|
|
13
13
|
var psemver = require('../../util/process-version')
|
|
14
|
-
var copy = require('../../util/copy')
|
|
15
14
|
|
|
16
15
|
const NAMES = require('../../metrics/names')
|
|
17
16
|
const DESTS = require('../../config/attribute-filter').DESTINATIONS
|
|
@@ -206,7 +205,7 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
|
|
|
206
205
|
}
|
|
207
206
|
}
|
|
208
207
|
if (agent.config.cross_application_tracer.enabled) {
|
|
209
|
-
if (agent.config.
|
|
208
|
+
if (agent.config.distributed_tracing.enabled) {
|
|
210
209
|
const payload = request.headers[NEWRELIC_TRACE_HEADER]
|
|
211
210
|
if (payload) {
|
|
212
211
|
logger.trace(
|
|
@@ -499,54 +498,10 @@ function wrapRequest(agent, request) {
|
|
|
499
498
|
|
|
500
499
|
const args = agent.tracer.slice(arguments)
|
|
501
500
|
const context = this
|
|
502
|
-
const outboundHeaders = Object.create(null)
|
|
503
|
-
|
|
504
|
-
// FLAG: synthetics
|
|
505
|
-
if (
|
|
506
|
-
agent.config.feature_flag.synthetics &&
|
|
507
|
-
agent.config.encoding_key &&
|
|
508
|
-
transaction.syntheticsHeader
|
|
509
|
-
) {
|
|
510
|
-
outboundHeaders[NEWRELIC_SYNTHETICS_HEADER] = transaction.syntheticsHeader
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// If CAT is enabled, inject the transaction header.
|
|
514
|
-
// TODO: abstract header logic shared with TransactionShim#insertCATRequestHeaders
|
|
515
|
-
if (agent.config.cross_application_tracer.enabled) {
|
|
516
|
-
if (agent.config.feature_flag.distributed_tracing) {
|
|
517
|
-
_addDistributedHeaders(transaction, outboundHeaders)
|
|
518
|
-
} else if (agent.config.encoding_key) {
|
|
519
|
-
_addCATHeaders(agent, transaction, outboundHeaders)
|
|
520
|
-
} else {
|
|
521
|
-
logger.trace('No encoding key found, not adding CAT headers')
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
if (typeof options === 'string') {
|
|
526
|
-
options = url.parse(options)
|
|
527
|
-
} else {
|
|
528
|
-
options = copy.shallow(options)
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
if (util.isArray(options.headers)) {
|
|
532
|
-
options.headers = options.headers.slice()
|
|
533
|
-
Array.prototype.push.apply(
|
|
534
|
-
options.headers,
|
|
535
|
-
Object.keys(outboundHeaders).map(function getHeaderTuples(key) {
|
|
536
|
-
return [key, outboundHeaders[key]]
|
|
537
|
-
})
|
|
538
|
-
)
|
|
539
|
-
} else {
|
|
540
|
-
options.headers = Object.assign(
|
|
541
|
-
Object.create(null),
|
|
542
|
-
options.headers,
|
|
543
|
-
outboundHeaders
|
|
544
|
-
)
|
|
545
|
-
}
|
|
546
|
-
args[0] = options
|
|
547
501
|
|
|
548
502
|
// hostname & port logic pulled directly from node's 0.10 lib/http.js
|
|
549
|
-
return instrumentOutbound(agent, options, function makeRequest() {
|
|
503
|
+
return instrumentOutbound(agent, options, function makeRequest(opts) {
|
|
504
|
+
args[0] = opts
|
|
550
505
|
return request.apply(context, args)
|
|
551
506
|
})
|
|
552
507
|
}
|
|
@@ -738,7 +693,7 @@ module.exports = function initialize(agent, http, moduleName) {
|
|
|
738
693
|
*
|
|
739
694
|
* @param {string} header - The raw X-NewRelic-Synthetics header
|
|
740
695
|
* @param {string} encKey - Encoding key handed down from the server
|
|
741
|
-
* @param {
|
|
696
|
+
* @param {Array.<number>} trustedIds - Array of accounts to trust the header from.
|
|
742
697
|
* @param {Transaction} transaction - Where the synthetics data is attached to.
|
|
743
698
|
*/
|
|
744
699
|
function handleSyntheticsHeader(header, encKey, trustedIds, transaction) {
|
|
@@ -756,8 +711,8 @@ function handleSyntheticsHeader(header, encKey, trustedIds, transaction) {
|
|
|
756
711
|
*
|
|
757
712
|
* @param {string} header - The raw X-NewRelic-Synthetics header
|
|
758
713
|
* @param {string} encKey - Encoding key handed down from the server
|
|
759
|
-
* @param {
|
|
760
|
-
* @return {Object
|
|
714
|
+
* @param {Array.<number>} trustedIds - Array of accounts to trust the header from.
|
|
715
|
+
* @return {Object|null} - On successful parse and verification an object of
|
|
761
716
|
* synthetics data is returned, otherwise null is
|
|
762
717
|
* returned.
|
|
763
718
|
*/
|
|
@@ -877,48 +832,3 @@ function _collectHeaders(headers, nameMap, prefix, tx) {
|
|
|
877
832
|
}
|
|
878
833
|
}
|
|
879
834
|
}
|
|
880
|
-
|
|
881
|
-
function _addDistributedHeaders(tx, outboundHeaders) {
|
|
882
|
-
try {
|
|
883
|
-
const txData = tx.createDistributedTracePayload().httpSafe()
|
|
884
|
-
outboundHeaders[NEWRELIC_TRACE_HEADER] = txData
|
|
885
|
-
|
|
886
|
-
logger.trace(
|
|
887
|
-
'Added outbound request distributed tracing headers in transaction %s',
|
|
888
|
-
tx.id
|
|
889
|
-
)
|
|
890
|
-
} catch (err) {
|
|
891
|
-
logger.trace(err, 'Failed to create distributed trace payload')
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
function _addCATHeaders(agent, tx, outboundHeaders) {
|
|
896
|
-
if (agent.config.obfuscatedId) {
|
|
897
|
-
outboundHeaders[NEWRELIC_ID_HEADER] = agent.config.obfuscatedId
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
var pathHash = hashes.calculatePathHash(
|
|
901
|
-
agent.config.applications()[0],
|
|
902
|
-
tx.getFullName() || '',
|
|
903
|
-
tx.referringPathHash
|
|
904
|
-
)
|
|
905
|
-
tx.pushPathHash(pathHash)
|
|
906
|
-
|
|
907
|
-
try {
|
|
908
|
-
let txData = JSON.stringify([
|
|
909
|
-
tx.id,
|
|
910
|
-
false,
|
|
911
|
-
tx.tripId || tx.id,
|
|
912
|
-
pathHash
|
|
913
|
-
])
|
|
914
|
-
txData = hashes.obfuscateNameUsingKey(txData, agent.config.encoding_key)
|
|
915
|
-
outboundHeaders[NEWRELIC_TRANSACTION_HEADER] = txData
|
|
916
|
-
|
|
917
|
-
logger.trace(
|
|
918
|
-
'Added outbound request CAT headers in transaction %s',
|
|
919
|
-
tx.id
|
|
920
|
-
)
|
|
921
|
-
} catch (err) {
|
|
922
|
-
logger.trace(err, 'Failed to create CAT payload')
|
|
923
|
-
}
|
|
924
|
-
}
|