newrelic 6.3.0 → 6.5.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.
Files changed (39) hide show
  1. package/{.eslintrc → .eslintrc.js} +4 -2
  2. package/.travis.yml +0 -1
  3. package/NEWS.md +136 -0
  4. package/README.md +1 -0
  5. package/api.js +75 -4
  6. package/bin/publish-docs.sh +1 -1
  7. package/bin/travis-node.sh +4 -1
  8. package/index.js +3 -3
  9. package/lib/aggregators/base-aggregator.js +1 -1
  10. package/lib/attributes.js +15 -6
  11. package/lib/config/default.js +11 -1
  12. package/lib/config/env.js +3 -1
  13. package/lib/config/hsm.js +6 -1
  14. package/lib/config/index.js +29 -8
  15. package/lib/config/lasp.js +16 -1
  16. package/lib/errors/error-collector.js +51 -90
  17. package/lib/errors/helper.js +13 -13
  18. package/lib/errors/index.js +36 -18
  19. package/lib/feature_flags.js +3 -3
  20. package/lib/header-processing.js +75 -0
  21. package/lib/instrumentation/core/child_process.js +12 -0
  22. package/lib/instrumentation/core/http-outbound.js +6 -28
  23. package/lib/instrumentation/core/http.js +100 -170
  24. package/lib/instrumentation/hapi/hapi-17.js +10 -3
  25. package/lib/metrics/names.js +1 -0
  26. package/lib/serverless/aws-lambda.js +79 -33
  27. package/lib/serverless/event-sources.json +128 -0
  28. package/lib/shim/transaction-shim.js +10 -33
  29. package/lib/spans/span-event-aggregator.js +2 -2
  30. package/lib/spans/span-event.js +33 -11
  31. package/lib/transaction/handle.js +73 -4
  32. package/lib/transaction/index.js +182 -34
  33. package/lib/transaction/trace/index.js +6 -5
  34. package/lib/transaction/trace/segment.js +12 -1
  35. package/lib/transaction/tracecontext.js +409 -163
  36. package/lib/util/get.js +16 -0
  37. package/lib/util/hashes.js +55 -6
  38. package/package.json +8 -10
  39. package/stub_api.js +5 -0
@@ -4,6 +4,7 @@ const errorsModule = require('./index')
4
4
 
5
5
  const logger = require('../logger').child({component: 'error_tracer'})
6
6
  const urltils = require('../util/urltils')
7
+ const Exception = require('../errors').Exception
7
8
  const errorHelper = require('./helper')
8
9
  const createError = errorsModule.createError
9
10
  const createEvent = errorsModule.createEvent
@@ -129,7 +130,7 @@ class ErrorCollector {
129
130
  if (transaction.userErrors.length) {
130
131
  for (let i = 0; i < transaction.userErrors.length; i++) {
131
132
  const exception = transaction.userErrors[i]
132
- if (this._collect(transaction, exception[0], exception[1], exception[2])) {
133
+ if (this.collect(transaction, exception)) {
133
134
  ++collectedErrors
134
135
  }
135
136
  }
@@ -145,13 +146,13 @@ class ErrorCollector {
145
146
  if (transaction.exceptions.length) {
146
147
  for (let i = 0; i < transaction.exceptions.length; i++) {
147
148
  const exception = transaction.exceptions[i]
148
- if (this.collect(transaction, exception[0], exception[1], exception[2])) {
149
+ if (this.collect(transaction, exception)) {
149
150
  ++collectedErrors
150
151
  // if we could collect it, then check if expected
151
152
  if (isExpectedErrorStatusCode ||
152
153
  errorHelper.isExpectedException(
153
154
  transaction,
154
- exception[0],
155
+ exception.error,
155
156
  this.config,
156
157
  urltils
157
158
  )
@@ -178,31 +179,32 @@ class ErrorCollector {
178
179
  }
179
180
 
180
181
  /**
181
- * This function collects the error right away when transaction is not supplied.
182
- * Otherwise it delays collecting the error until the transaction ends.
182
+ * This function collects the error right away when transaction is not supplied. Otherwise it
183
+ * delays collecting the error until the transaction ends.
183
184
  *
184
185
  * NOTE: this interface is unofficial and may change in future.
185
186
  *
186
- * @param {?Transaction} transaction
187
- * Transaction associated with the error.
188
- *
189
- * @param {Error} exception
190
- * The error to be traced.
191
- *
192
- * @param {object} customAttributes
193
- * Any custom attributes associated with the request (optional).
187
+ * @param {?Transaction} transaction Transaction associated with the error.
188
+ * @param {Error} error The error to be traced.
189
+ * @param {?object} customAttributes Custom attributes associated with the request (optional).
194
190
  */
195
- add(transaction, exception, customAttributes) {
196
- if (!exception) {
191
+ add(transaction, error, customAttributes) {
192
+ if (!error) {
193
+ return
194
+ }
195
+
196
+ if (errorHelper.shouldIgnoreError(transaction, error, this.config)) {
197
+ logger.trace('Ignoring error')
197
198
  return
198
199
  }
199
200
 
200
201
  const timestamp = Date.now()
202
+ const exception = new Exception({error, timestamp, customAttributes})
201
203
 
202
204
  if (transaction) {
203
- transaction.addException(exception, customAttributes, timestamp)
205
+ transaction.addException(exception)
204
206
  } else {
205
- this.collect(transaction, exception, customAttributes, timestamp)
207
+ this.collect(transaction, exception)
206
208
  }
207
209
  }
208
210
 
@@ -217,95 +219,54 @@ class ErrorCollector {
217
219
  *
218
220
  * NOTE: this interface is unofficial and may change in future.
219
221
  *
220
- * @param {?Transaction} transaction
221
- * Transaction associated with the error.
222
- *
223
- * @param {Error} exception
224
- * The error to be traced.
225
- *
226
- * @param {object} [customAttributes=null]
227
- * Any custom attributes associated with the request (optional).
222
+ * @param {?Transaction} transaction Transaction associated with the error.
223
+ * @param {Exception} exception The Exception to be traced.
228
224
  */
229
- addUserError(transaction, exception, customAttributes) {
230
- if (!exception) return
225
+ addUserError(transaction, error, customAttributes) {
226
+ if (!error) return
231
227
 
232
- var timestamp = Date.now()
228
+ const timestamp = Date.now()
229
+ const exception = new Exception({error, timestamp, customAttributes})
233
230
 
234
231
  if (transaction) {
235
- transaction.addUserError(exception, customAttributes, timestamp)
232
+ transaction.addUserError(exception)
236
233
  } else {
237
- this._collect(transaction, exception, customAttributes, timestamp)
238
- }
239
- }
240
-
241
- /**
242
- * Wrapper for _collect, include logic for whether an error should
243
- * be ignored or not. Exists to allow userErrors to bypass ignore
244
- * logic.
245
- *
246
- * NOTE: this interface is unofficial and may change in future.
247
- *
248
- * @param {?Transaction} transaction
249
- * Transaction associated with the error.
250
- *
251
- * @param {?Error} exception
252
- * The error to be traced.
253
- *
254
- * @param {?object} customAttributes
255
- * Any custom attributes associated with the request.
256
- *
257
- * @param {number} timestamp
258
- *
259
- * @return {bool} True if the error was collected.
260
- */
261
- collect(transaction, exception, customAttributes, timestamp) {
262
- if (errorHelper.shouldIgnoreError(transaction, exception, this.config)) {
263
- logger.trace("Ignoring error")
264
- return
234
+ this.collect(transaction, exception)
265
235
  }
266
- return this._collect(transaction, exception, customAttributes, timestamp)
267
236
  }
268
237
 
269
238
  /**
270
239
  * Collects the error and also creates the error event.
271
240
  *
272
- * @private
273
- *
274
- * This function uses an array of seen exceptions to ensure errors don't get
275
- * double-counted. It can also be used as an unofficial means of marking that
276
- * user errors shouldn't be traced.
241
+ * This function uses an array of seen exceptions to ensure errors don't get double-counted. It
242
+ * can also be used as an unofficial means of marking that user errors shouldn't be traced.
277
243
  *
278
- * For an error to be traced, at least one of the transaction or the error
279
- * must be present.
244
+ * For an error to be traced, at least one of the transaction or the error must be present.
280
245
  *
281
246
  * NOTE: this interface is unofficial and may change in future.
282
247
  *
283
- * @param {?Transaction} transaction
284
- * Transaction associated with the error.
285
- *
286
- * @param {?Error} exception
287
- * The error to be traced.
288
- *
289
- * @param {?object} customAttributes
290
- * Any custom attributes associated with the request.
291
- *
292
- * @param {number} timestamp
293
- *
294
- * @return {bool} True if the error was collected.
248
+ * @param {?Transaction} transaction Transaction associated with the error.
249
+ * @param {?Exception} exception The Exception object to be traced.
250
+ * @return {bool} True if the error was collected.
295
251
  */
296
- _collect(transaction, exception, customAttributes, timestamp) {
297
- if (exception) {
298
- if (this._haveSeen(transaction, exception)) {
252
+ collect(transaction, exception) {
253
+ if (!exception) {
254
+ exception = new Exception({})
255
+ }
256
+
257
+ if (exception.error) {
258
+ if (this._haveSeen(transaction, exception.error)) {
299
259
  return false
300
260
  }
301
261
 
302
- if (typeof exception !== 'string' && !exception.message && !exception.stack) {
303
- logger.trace(exception, 'Got error that is not an instance of Error or string.')
304
- exception = null
262
+ const error = exception.error
263
+ if (typeof error !== 'string' && !error.message && !error.stack) {
264
+ logger.trace(error, 'Got error that is not an instance of Error or string.')
265
+ exception.error = null
305
266
  }
306
267
  }
307
268
 
308
- if (!exception && (!transaction || !transaction.statusCode || transaction.error)) {
269
+ if (!exception.error && (!transaction || !transaction.statusCode || transaction.error)) {
309
270
  return false
310
271
  }
311
272
 
@@ -321,13 +282,13 @@ class ErrorCollector {
321
282
  return false
322
283
  }
323
284
 
324
- if (exception) {
325
- logger.trace(exception, 'Got exception to trace:')
285
+ if (exception.error) {
286
+ logger.trace(exception.error, 'Got exception to trace:')
326
287
  }
327
288
 
328
- const error = createError(transaction, exception, customAttributes, this.config)
289
+ const errorTrace = createError(transaction, exception, this.config)
329
290
 
330
- const isExpectedError = true === error[4].intrinsics['error.expected']
291
+ const isExpectedError = true === errorTrace[4].intrinsics['error.expected']
331
292
 
332
293
  if (isExpectedError) {
333
294
  this.metrics.getOrCreateMetric(NAMES.ERRORS.EXPECTED).incrementCallCount()
@@ -343,11 +304,11 @@ class ErrorCollector {
343
304
  }
344
305
  }
345
306
 
346
- this.traceAggregator.add(error)
307
+ this.traceAggregator.add(errorTrace)
347
308
 
348
309
  if (this.config.error_collector.capture_events === true) {
349
310
  const priority = transaction && transaction.priority || Math.random()
350
- const event = createEvent(transaction, error, timestamp, this.config)
311
+ const event = createEvent(transaction, errorTrace, exception.timestamp, this.config)
351
312
  this.eventAggregator.add(event, priority)
352
313
  }
353
314
 
@@ -48,7 +48,7 @@ module.exports = {
48
48
 
49
49
  extractErrorInformation: function extractErrorInformation(
50
50
  transaction,
51
- exception,
51
+ error,
52
52
  config,
53
53
  urltils
54
54
  ) {
@@ -58,21 +58,21 @@ module.exports = {
58
58
 
59
59
  // String errors do not provide us with as much information to provide to the
60
60
  // user, but it is a common pattern.
61
- if (typeof exception === 'string') {
62
- message = exception
61
+ if (typeof error === 'string') {
62
+ message = error
63
63
  } else if (
64
- exception !== null &&
65
- typeof exception === 'object' &&
66
- exception.message &&
64
+ error !== null &&
65
+ typeof error === 'object' &&
66
+ error.message &&
67
67
  !config.high_security &&
68
68
  !config.strip_exception_messages.enabled
69
69
  ) {
70
- message = exception.message
70
+ message = error.message
71
71
 
72
- if (exception.name) {
73
- type = exception.name
74
- } else if (exception.constructor && exception.constructor.name) {
75
- type = exception.constructor.name
72
+ if (error.name) {
73
+ type = error.name
74
+ } else if (error.constructor && error.constructor.name) {
75
+ type = error.constructor.name
76
76
  }
77
77
  } else if (transaction && transaction.statusCode &&
78
78
  urltils.isError(config, transaction.statusCode)) {
@@ -95,9 +95,9 @@ module.exports = {
95
95
  }
96
96
  },
97
97
 
98
- shouldIgnoreError: function shouldIgnoreError(transaction, exception, config) {
98
+ shouldIgnoreError: function shouldIgnoreError(transaction, error, config) {
99
99
  // extract _just_ the error information, not transaction stuff
100
- let errorInfo = this.extractErrorInformation(null, exception, config, null)
100
+ let errorInfo = this.extractErrorInformation(null, error, config, null)
101
101
 
102
102
  return this.shouldIgnoreErrorClass(errorInfo, config) ||
103
103
  this.shouldIgnoreErrorMessage(errorInfo, config) ||
@@ -6,8 +6,18 @@ var props = require('../util/properties')
6
6
  var urltils = require('../util/urltils')
7
7
  const errorHelper = require('../errors/helper')
8
8
 
9
- module.exports.createError = createError
10
- module.exports.createEvent = createEvent
9
+ class Exception {
10
+ constructor({error, timestamp, customAttributes, agentAttributes}) {
11
+ this.error = error
12
+ this.timestamp = timestamp || 0
13
+ this.customAttributes = customAttributes || {}
14
+ this.agentAttributes = agentAttributes || {}
15
+ }
16
+
17
+ getErrorDetails(config) {
18
+ return errorHelper.extractErrorInformation(null, this.error, config)
19
+ }
20
+ }
11
21
 
12
22
  /**
13
23
  * Given either or both of a transaction and an exception, generate an error
@@ -17,21 +27,20 @@ module.exports.createEvent = createEvent
17
27
  * handler, which traps actual instances of Error, try to set sensible
18
28
  * defaults for everything.
19
29
  *
20
- * @param {Transaction} transaction The agent transaction, presumably
21
- * coming out of the instrumentation.
22
- * @param {Error} exception Something trapped by an error listener.
23
- * @param {object} customAttributes Any custom attributes associated with
24
- * the request (optional).
30
+ * @param {Transaction} transaction The agent transaction, coming from the instrumentatation
31
+ * @param {Exception} exception An custom Exception object with the error and other information
32
+ * @param {object} config The configuration to use when creating the object
25
33
  */
26
- function createError(transaction, exception, customAttributes, config) {
34
+ function createError(transaction, exception, config) {
35
+ const error = exception.error
27
36
  let {name, message, type} = errorHelper.extractErrorInformation(
28
37
  transaction,
29
- exception,
38
+ error,
30
39
  config,
31
40
  urltils
32
41
  )
33
42
 
34
- var params = {
43
+ let params = {
35
44
  userAttributes: Object.create(null),
36
45
  agentAttributes: Object.create(null),
37
46
  intrinsics: Object.create(null)
@@ -39,20 +48,26 @@ function createError(transaction, exception, customAttributes, config) {
39
48
 
40
49
  if (transaction) {
41
50
  // Copy all of the parameters off of the transaction.
42
- params.agentAttributes = transaction.trace.attributes.get(DESTINATIONS.ERROR_EVENT)
43
51
  params.intrinsics = transaction.getIntrinsicAttributes()
52
+ let transactionAgentAttributes = transaction.trace.attributes.get(DESTINATIONS.ERROR_EVENT)
53
+ transactionAgentAttributes = transactionAgentAttributes || {}
54
+
55
+ // Merge the agent attributes specific to this error event with the transaction attributes
56
+ const agentAttributes = Object.assign(exception.agentAttributes, transactionAgentAttributes)
57
+ params.agentAttributes = agentAttributes
44
58
 
45
59
  // There should be no attributes to copy in HSM, but check status anyway
46
60
  if (!config.high_security) {
47
- var custom = transaction.trace.custom.get(DESTINATIONS.ERROR_EVENT)
61
+ const custom = transaction.trace.custom.get(DESTINATIONS.ERROR_EVENT)
48
62
  urltils.overwriteParameters(custom, params.userAttributes)
49
63
  }
50
64
  }
51
65
 
66
+ const customAttributes = exception.customAttributes
52
67
  if (!config.high_security && config.api.custom_attributes_enabled && customAttributes) {
53
- for (var key in customAttributes) {
68
+ for (let key in customAttributes) {
54
69
  if (props.hasOwn(customAttributes, key)) {
55
- var dest = config.attributeFilter.filterTransaction(
70
+ const dest = config.attributeFilter.filterTransaction(
56
71
  DESTINATIONS.ERROR_EVENT,
57
72
  key
58
73
  )
@@ -63,12 +78,11 @@ function createError(transaction, exception, customAttributes, config) {
63
78
  }
64
79
  }
65
80
 
66
-
67
- var stack = exception && exception.stack
81
+ const stack = exception.error && exception.error.stack
68
82
  if (stack) {
69
83
  params.stack_trace = ('' + stack).split(/[\n\r]/g)
70
84
  if (config.high_security || config.strip_exception_messages.enabled) {
71
- params.stack_trace[0] = exception.name + ': <redacted>'
85
+ params.stack_trace[0] = exception.error.name + ': <redacted>'
72
86
  }
73
87
  }
74
88
 
@@ -77,7 +91,7 @@ function createError(transaction, exception, customAttributes, config) {
77
91
  params.intrinsics['error.expected'] = true
78
92
  }
79
93
 
80
- var res = [0, name, message, type, params]
94
+ let res = [0, name, message, type, params]
81
95
  if (transaction) {
82
96
  res.transaction = transaction.id
83
97
  }
@@ -180,3 +194,7 @@ function _getErrorEventIntrinsicAttrs(
180
194
 
181
195
  return attributes
182
196
  }
197
+
198
+ module.exports.createError = createError
199
+ module.exports.createEvent = createEvent
200
+ module.exports.Exception = Exception
@@ -6,8 +6,7 @@ exports.prerelease = {
6
6
  await_support: true,
7
7
  serverless_mode: true,
8
8
  promise_segments: false,
9
- reverse_naming_rules: false,
10
- dt_format_w3c: false
9
+ reverse_naming_rules: false
11
10
  }
12
11
 
13
12
  // flags that are no longer used for released features
@@ -20,7 +19,8 @@ exports.released = [
20
19
  'native_metrics',
21
20
  'protocol_17',
22
21
  'send_request_uri_attribute',
23
- 'synthetics'
22
+ 'synthetics',
23
+ 'dt_format_w3c'
24
24
  ]
25
25
 
26
26
  // flags that are no longer used for unreleased features
@@ -0,0 +1,75 @@
1
+ 'use strict'
2
+
3
+ const REQUEST_START_HEADER = 'x-request-start'
4
+ const QUEUE_HEADER = 'x-queue-start'
5
+ const CONTENT_LENGTH_REGEX = /^Content-Length$/i
6
+
7
+ /**
8
+ * Extracts queue time from the incoming request headers.
9
+ *
10
+ * Queue time is provided by certain providers by stamping the request
11
+ * header with the time the request arrived at the router.
12
+ * @param {*} logger
13
+ * @param {*} requestHeaders
14
+ */
15
+ function getQueueTime(logger, requestHeaders) {
16
+ const headerValue = requestHeaders[REQUEST_START_HEADER] || requestHeaders[QUEUE_HEADER]
17
+ if (!headerValue) {
18
+ return null
19
+ }
20
+
21
+ const split = headerValue.split('=')
22
+ const rawQueueTime = split.length > 1 ? split[1] : headerValue
23
+
24
+ const parsedQueueTime = parseFloat(rawQueueTime)
25
+ if (isNaN(parsedQueueTime)) {
26
+ logger.warn('Queue time header parsed as NaN. See trace level log for value.')
27
+
28
+ // This header can hold up to 4096 bytes which could quickly fill up logs.
29
+ // Do not log a level higher than debug.
30
+ logger.trace('Queue time: %s', rawQueueTime)
31
+
32
+ return null
33
+ }
34
+
35
+ const convertedQueueTime = convertUnit(parsedQueueTime)
36
+ return convertedQueueTime
37
+ }
38
+
39
+ function convertUnit(time) {
40
+ let convertedTime = time
41
+ if (convertedTime > 1e18) {
42
+ // nano seconds
43
+ convertedTime = convertedTime / 1e6
44
+ } else if (convertedTime > 1e15) {
45
+ // micro seconds
46
+ convertedTime = convertedTime / 1e3
47
+ } else if (convertedTime < 1e12) {
48
+ // seconds
49
+ convertedTime = convertedTime * 1e3
50
+ }
51
+
52
+ return convertedTime
53
+ }
54
+
55
+ /**
56
+ * Returns the value of the Content-Length header
57
+ *
58
+ * If no header is found, returns -1
59
+ *
60
+ * @param {*} headers
61
+ */
62
+ function getContentLengthFromHeaders(headers) {
63
+ let contentLength = -1
64
+ for (const [headerName, headerValue] of Object.entries(headers)) {
65
+ if (CONTENT_LENGTH_REGEX.test(headerName)) {
66
+ return headerValue
67
+ }
68
+ }
69
+ return contentLength
70
+ }
71
+
72
+ module.exports = {
73
+ getQueueTime,
74
+ getContentLengthFromHeaders
75
+ }
@@ -33,8 +33,20 @@ function initialize(agent, childProcess, moduleName, shim) {
33
33
  const args = shim.argsToArray.apply(shim, arguments)
34
34
  const cbIndex = args.length - 1
35
35
 
36
+ const originalListener = args[cbIndex]
37
+ if (!shim.isFunction(originalListener)) {
38
+ return fn.apply(this, arguments)
39
+ }
40
+
36
41
  shim.bindSegment(args, cbIndex)
37
42
 
43
+ // Leverage events.removeListener() mechanism that checks listener
44
+ // property to allow our wrapped listeners to match and remove appropriately.
45
+ // Avoids having to instrument removeListener() and potentially doubling
46
+ // lookup. Since our wrapping will only be referenced by the events
47
+ // collection, we should not need to unwrap.
48
+ args[cbIndex].listener = originalListener
49
+
38
50
  return fn.apply(this, args)
39
51
  }
40
52
  }
@@ -17,7 +17,6 @@ const DEFAULT_PORT = 80
17
17
  const DEFAULT_SSL_PORT = 443
18
18
 
19
19
  const NEWRELIC_ID_HEADER = 'x-newrelic-id'
20
- const NEWRELIC_TRACE_HEADER = 'newrelic'
21
20
  const NEWRELIC_TRANSACTION_HEADER = 'x-newrelic-transaction'
22
21
  const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
23
22
 
@@ -92,11 +91,9 @@ module.exports = function instrumentOutbound(agent, opts, makeRequest) {
92
91
  // TODO: abstract header logic shared with TransactionShim#insertCATRequestHeaders
93
92
  if (agent.config.distributed_tracing.enabled) {
94
93
  if (opts.headers && opts.headers[SHIM_SYMBOLS.DISABLE_DT]) {
95
- logger.trace('DT disabled by instrumentation.')
96
- } else if (agent.config.feature_flag.dt_format_w3c) {
97
- _addTraceContextHeaders(transaction, outboundHeaders)
94
+ logger.trace('Distributed tracing disabled by instrumentation.')
98
95
  } else {
99
- _addDistributedHeaders(transaction, outboundHeaders)
96
+ transaction.insertDistributedTraceHeaders(outboundHeaders)
100
97
  }
101
98
  } else if (agent.config.cross_application_tracer.enabled) {
102
99
  if (agent.config.encoding_key) {
@@ -198,6 +195,10 @@ function handleError(segment, req, error) {
198
195
  * @param {http.IncomingMessage} res
199
196
  */
200
197
  function handleResponse(segment, hostname, req, res) {
198
+ // Add response attributes for spans
199
+ segment.addAttribute('http.statusCode', res.statusCode)
200
+ segment.addAttribute('http.statusText', res.statusMessage)
201
+
201
202
  // If CAT is enabled, grab those headers!
202
203
  const agent = segment.transaction.agent
203
204
  if (
@@ -276,29 +277,6 @@ function _makeNonEnumerable(obj, prop) {
276
277
  }
277
278
  }
278
279
 
279
- function _addDistributedHeaders(tx, outboundHeaders) {
280
- try {
281
- const txData = tx.createDistributedTracePayload().httpSafe()
282
- outboundHeaders[NEWRELIC_TRACE_HEADER] = txData
283
-
284
- logger.trace(
285
- 'Added outbound request distributed tracing headers in transaction %s',
286
- tx.id
287
- )
288
- } catch (err) {
289
- logger.trace(err, 'Failed to create distributed trace payload')
290
- }
291
- }
292
-
293
- function _addTraceContextHeaders(tx, outboundHeaders) {
294
- tx.traceContext.addTraceContextHeaders(outboundHeaders)
295
-
296
- logger.trace(
297
- 'Added outbound request w3c trace context headers in transaction %s',
298
- tx.id
299
- )
300
- }
301
-
302
280
  function _addCATHeaders(agent, tx, outboundHeaders) {
303
281
  if (agent.config.obfuscatedId) {
304
282
  outboundHeaders[NEWRELIC_ID_HEADER] = agent.config.obfuscatedId