newrelic 5.3.0 → 5.6.2

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/CONTRIBUTING.md CHANGED
@@ -37,8 +37,7 @@ and not ready for general-purpose use.
37
37
 
38
38
  ### Setup
39
39
 
40
- To run the tests you need a GNU-compatible make, the openssl command-line
41
- binary, and some services:
40
+ To run the tests you need an openssl command-line binary, and some services:
42
41
 
43
42
  * Cassandra
44
43
  * Memcached
@@ -50,7 +49,7 @@ binary, and some services:
50
49
  If you have these all running locally on the standard ports, then you are good
51
50
  to go. However, the suggested path is to use [Docker](http://www.docker.com).
52
51
  If you use OS X or Windows, use Docker Machine, which can be installed as a part of
53
- [Docker Toolbox](https://www.docker.com/docker-toolbox). Then, run `make services`
52
+ [Docker Toolbox](https://www.docker.com/docker-toolbox). Then, run `npm run services`
54
53
  to start docker containers for each of the above services.
55
54
 
56
55
  If you have these services available on non-standard ports or elsewhere on your
@@ -75,7 +74,7 @@ tests if all of the unit tests pass.
75
74
  If you don't feel like dealing with the hassle of setting up the servers, just
76
75
  the unit tests can be run with:
77
76
 
78
- make unit
77
+ npm run unit
79
78
 
80
79
  ### Writing tests
81
80
 
package/NEWS.md CHANGED
@@ -1,3 +1,94 @@
1
+ ### 5.6.2 (2019-03-25):
2
+
3
+ * Agent now respects attribute type restrictions on trace/segment attributes, as
4
+ well as error event/trace attributes.
5
+
6
+ * Fixes potential for `RangeError: Maximum call stack size exceeded` error on
7
+ Transaction/Trace end.
8
+
9
+ * Custom events no longer accept attributes with invalid types.
10
+
11
+ The only attribute types accepted by the backend are `boolean`, `string`, and
12
+ `number`; any attribute assigned to a custom event outside these types would be
13
+ dropped on ingest. The agent now filters these attributes out, and logs out a
14
+ helpful message detailing the issue.
15
+
16
+ ### 5.6.1 (2019-03-11):
17
+
18
+ * Updated log message for not adding attributes and change the log level to debug.
19
+
20
+ * Fixed an issue where exclusive time would be improperly calculated in some cases.
21
+
22
+ ### 5.6.0 (2019-03-04):
23
+
24
+ * Added `product` attribute to existing datastore instrumentations.
25
+
26
+ * Added `db.collection` to datastore span event attributes.
27
+
28
+ * `trusted_account_key`, `account_id`, and `primary_application_id` may now be
29
+ configured via a configuration file while in serverless mode.
30
+
31
+ * Fixed a bug where data belonging to distributed traces starting in the Node.js
32
+ agent would be prioritized over data produced from traces starting in other
33
+ language agents.
34
+
35
+ Previously, the agent would use the same random number for both the transaction
36
+ priority (used for data sampling) and the Distributed Tracing trace sampling
37
+ decision (whether to create DT data for a given transaction). This random number
38
+ reuse resulted in a bias that caused data from distributed traces started in the
39
+ Node.js agent to be prioritized above data that belongs to distributed traces
40
+ started in other language agents. The agent now makes individual rolls for each
41
+ of these quantities (i.e. the transaction priority and trace sampling decision),
42
+ eliminating the bias.
43
+
44
+ * Optimized exclusive time duration calculator.
45
+
46
+ Previously, the agent would spend a lot of time sorting redundant arrays while
47
+ calculating the exclusive time for the segments of a trace. This has been
48
+ refactored into a single postorder traversal over the tree which will calculate
49
+ the exclusive time for all segments in the subtree rooted at a given segment.
50
+
51
+ * Prevent a split on undefined location under certain conditions in Memcached.
52
+
53
+ Special thanks to Ben Wolfe (@bwolfe) for this fix!
54
+
55
+ ### 5.4.0 (2019-02-19):
56
+
57
+ * Fixed issue where `shim.createSegment()` could result in modifying the parent
58
+ when opaque.
59
+
60
+ * Fixed issue where `http-outbound` would modify parent segments when parent is
61
+ opaque.
62
+
63
+ * Moved processing of exclusive time attribute out of `toJSON` and into `finalize`
64
+ to only be calculated once.
65
+
66
+ Previously, serializing a segment would result in calculating and caching exclusive
67
+ time which could result in issues if serialized prior to ending.
68
+
69
+ * Added `SNS` to message shim library names.
70
+
71
+ * Added check for `collect_span_events` in config sent from the server on connect.
72
+
73
+ Collection of span events can be disabled from the server configuration, but not
74
+ enabled.
75
+
76
+ * Refactored `Segment#toJSON` to be more readable.
77
+
78
+ * Added a `try/catch` to config initialization to safely handle invalid setting
79
+ combinations.
80
+
81
+ When an error is caught the agent is marked as disabled, which ultimately returns
82
+ a stub API and keeps the process running.
83
+
84
+ * String truncation is now done using a binary search over the byte length of the
85
+ string.
86
+
87
+ Previously this truncation was done using a linear search for the proper byte
88
+ length.
89
+
90
+ * Optimized segment and span attribute filtering.
91
+
1
92
  ### 5.3.0 (2019-02-12):
2
93
 
3
94
  * Added `span_events` and `transaction_segments` attribute destinations.
package/api.js CHANGED
@@ -9,6 +9,7 @@ const hashes = require('./lib/util/hashes')
9
9
  const properties = require('./lib/util/properties')
10
10
  const stringify = require('json-stringify-safe')
11
11
  const shimmer = require('./lib/shimmer')
12
+ const isValidType = require('./lib/util/attribute-types')
12
13
  const TransactionShim = require('./lib/shim/transaction-shim')
13
14
  const TransactionHandle = require('./lib/transaction/handle')
14
15
  const AwsLambda = require('./lib/serverless/aws-lambda')
@@ -16,7 +17,6 @@ const AwsLambda = require('./lib/serverless/aws-lambda')
16
17
  const ATTR_DEST = require('./lib/config/attribute-filter').DESTINATIONS
17
18
  const MODULE_TYPE = require('./lib/shim/constants').MODULE_TYPE
18
19
  const NAMES = require('./lib/metrics/names')
19
-
20
20
  /*
21
21
  *
22
22
  * CONSTANTS
@@ -365,7 +365,13 @@ API.prototype.noticeError = function noticeError(error, customAttributes) {
365
365
  }
366
366
  const transaction = this.agent.tracer.getTransaction()
367
367
 
368
- this.agent.errors.addUserError(transaction, error, customAttributes)
368
+ // Filter all object type valued attributes out
369
+ let filteredAttributes = customAttributes
370
+ if (customAttributes) {
371
+ filteredAttributes = _filterAttributes(customAttributes, 'noticeError')
372
+ }
373
+
374
+ this.agent.errors.addUserError(transaction, error, filteredAttributes)
369
375
  }
370
376
 
371
377
  /**
@@ -1067,6 +1073,9 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
1067
1073
  return
1068
1074
  }
1069
1075
 
1076
+ // Filter all object type valued attributes out
1077
+ const filteredAttributes = _filterAttributes(attributes, `${eventType} custom event`)
1078
+
1070
1079
  var instrinics = {
1071
1080
  type: eventType,
1072
1081
  timestamp: Date.now()
@@ -1074,7 +1083,7 @@ API.prototype.recordCustomEvent = function recordCustomEvent(eventType, attribut
1074
1083
 
1075
1084
  var tx = this.agent.getTransaction()
1076
1085
  var priority = tx && tx.priority || Math.random()
1077
- this.agent.customEvents.add([instrinics, attributes], priority)
1086
+ this.agent.customEvents.add([instrinics, filteredAttributes], priority)
1078
1087
  }
1079
1088
 
1080
1089
  /**
@@ -1390,4 +1399,19 @@ API.prototype.setLambdaHandler = function setLambdaHandler(handler) {
1390
1399
  return this.awsLambda.patchLambdaHandler(handler)
1391
1400
  }
1392
1401
 
1402
+ function _filterAttributes(attributes, name) {
1403
+ const filteredAttributes = Object.create(null)
1404
+ Object.keys(attributes).forEach((attributeKey) => {
1405
+ if (!isValidType(attributes[attributeKey])) {
1406
+ logger.info(
1407
+ `Omitting attribute ${attributeKey} from ${name} call, type must ` +
1408
+ 'be boolean, number, or string'
1409
+ )
1410
+ return
1411
+ }
1412
+ filteredAttributes[attributeKey] = attributes[attributeKey]
1413
+ })
1414
+ return filteredAttributes
1415
+ }
1416
+
1393
1417
  module.exports = API
package/index.js CHANGED
@@ -34,8 +34,8 @@ if (require.cache.__NR_cache) {
34
34
 
35
35
  function initialize() {
36
36
  logger.debug('Loading agent from %s', __dirname)
37
- var agent = null
38
- var message = null
37
+ let agent = null
38
+ let message = null
39
39
 
40
40
  try {
41
41
  logger.debug(
@@ -45,8 +45,8 @@ function initialize() {
45
45
 
46
46
  // TODO: Update this check when Node v6 is deprecated.
47
47
  if (psemver.satisfies('<6.0.0')) {
48
- message = "New Relic for Node.js requires a version of Node equal to or\n" +
49
- "greater than 6.0.0. Not starting!"
48
+ message = 'New Relic for Node.js requires a version of Node equal to or\n' +
49
+ 'greater than 6.0.0. Not starting!'
50
50
 
51
51
  logger.error(message)
52
52
  throw new Error(message)
@@ -59,24 +59,24 @@ function initialize() {
59
59
  )
60
60
  }
61
61
 
62
- logger.debug("Current working directory at module load is %s.", process.cwd())
63
- logger.debug("Process title is %s.", process.title)
64
- logger.debug("Application was invoked as %s.", process.argv.join(' '))
62
+ logger.debug('Current working directory at module load is %s.', process.cwd())
63
+ logger.debug('Process title is %s.', process.title)
64
+ logger.debug('Application was invoked as %s.', process.argv.join(' '))
65
65
 
66
- var config = require('./lib/config').getOrCreateInstance()
66
+ const config = require('./lib/config').getOrCreateInstance()
67
67
 
68
68
  // Get the initialized logger as we likely have a bootstrap logger which
69
69
  // just pipes to stdout.
70
70
  logger = require('./lib/logger')
71
71
 
72
72
  if (!config || !config.agent_enabled) {
73
- logger.info("Module not enabled in configuration; not starting.")
73
+ logger.info('Module not enabled in configuration; not starting.')
74
74
  } else {
75
75
  agent = createAgent(config)
76
76
  addStartupSupportabilities(agent)
77
77
  }
78
78
  } catch (error) {
79
- message = "New Relic for Node.js was unable to bootstrap itself due to an error:"
79
+ message = 'New Relic for Node.js was unable to bootstrap itself due to an error:'
80
80
  logger.error(error, message)
81
81
 
82
82
  /* eslint-disable no-console */
@@ -85,7 +85,7 @@ function initialize() {
85
85
  /* eslint-enable no-console */
86
86
  }
87
87
 
88
- var API = null
88
+ let API = null
89
89
  if (agent) {
90
90
  API = require('./api')
91
91
  } else {
@@ -97,7 +97,7 @@ function initialize() {
97
97
  // If we loaded an agent, record a startup time for the agent.
98
98
  // NOTE: Metrics are recorded in seconds, so divide the value by 1000.
99
99
  if (agent) {
100
- var initDuration = (Date.now() - agentStart) / 1000
100
+ const initDuration = (Date.now() - agentStart) / 1000
101
101
  agent.recordSupportability('Nodejs/Application/Opening/Duration', preAgentTime)
102
102
  agent.recordSupportability('Nodejs/Application/Initialization/Duration', initDuration)
103
103
  agent.once('started', function timeAgentStart() {
@@ -117,9 +117,9 @@ function createAgent(config) {
117
117
  * multiple times, with undefined results. New Relic's instrumentation
118
118
  * can't be enabled or disabled without an application restart.
119
119
  */
120
- var Agent = require('./lib/agent')
121
- var agent = new Agent(config)
122
- var appNames = agent.config.applications()
120
+ const Agent = require('./lib/agent')
121
+ const agent = new Agent(config)
122
+ const appNames = agent.config.applications()
123
123
 
124
124
  if (config.logging.diagnostics) {
125
125
  logger.warn(
@@ -128,7 +128,7 @@ function createAgent(config) {
128
128
  }
129
129
 
130
130
  if (appNames.length < 1) {
131
- var message =
131
+ const message =
132
132
  'New Relic requires that you name this application!\n' +
133
133
  'Set app_name in your newrelic.js file or set environment variable\n' +
134
134
  'NEW_RELIC_APP_NAME. Not starting!'
@@ -136,17 +136,17 @@ function createAgent(config) {
136
136
  throw new Error(message)
137
137
  }
138
138
 
139
- var shimmer = require('./lib/shimmer')
139
+ const shimmer = require('./lib/shimmer')
140
140
  shimmer.patchModule(agent)
141
141
  shimmer.bootstrapInstrumentation(agent)
142
142
 
143
143
  // Check for already loaded modules and warn about them.
144
- var uninstrumented = require('./lib/uninstrumented')
144
+ const uninstrumented = require('./lib/uninstrumented')
145
145
  uninstrumented.check(shimmer.registeredInstrumentations)
146
146
 
147
147
  agent.start(function afterStart(error) {
148
148
  if (error) {
149
- var errorMessage = 'New Relic for Node.js halted startup due to an error:'
149
+ const errorMessage = 'New Relic for Node.js halted startup due to an error:'
150
150
  logger.error(error, errorMessage)
151
151
 
152
152
  /* eslint-disable no-console */
@@ -165,15 +165,15 @@ function createAgent(config) {
165
165
 
166
166
  function addStartupSupportabilities(agent) {
167
167
  // TODO: As new versions come out, make sure to update Angler metrics.
168
- var nodeMajor = /^v?(\d+)/.exec(process.version)
168
+ const nodeMajor = /^v?(\d+)/.exec(process.version)
169
169
  agent.recordSupportability(
170
170
  'Nodejs/Version/' + ((nodeMajor && nodeMajor[1]) || 'unknown')
171
171
  )
172
172
 
173
- var configFlags = Object.keys(agent.config.feature_flag)
174
- for (var i = 0; i < configFlags.length; ++i) {
175
- var flag = configFlags[i]
176
- var enabled = agent.config.feature_flag[flag]
173
+ const configFlags = Object.keys(agent.config.feature_flag)
174
+ for (let i = 0; i < configFlags.length; ++i) {
175
+ const flag = configFlags[i]
176
+ const enabled = agent.config.feature_flag[flag]
177
177
 
178
178
  if (enabled !== featureFlags[flag]) {
179
179
  agent.recordSupportability(
@@ -8,7 +8,7 @@ class AdaptiveSampler {
8
8
  this._samplingPeriod = 0
9
9
  this._samplingTarget = opts.target
10
10
  this._maxSamples = 2 * opts.target
11
- this._minSampledPriority = 0
11
+ this._samplingThreshold = 0
12
12
  this._resetCount = 0
13
13
  this._resetInterval = null
14
14
 
@@ -24,8 +24,8 @@ class AdaptiveSampler {
24
24
  return this._sampled
25
25
  }
26
26
 
27
- get minimumPriority() {
28
- return this._minSampledPriority
27
+ get samplingThreshold() {
28
+ return this._samplingThreshold
29
29
  }
30
30
 
31
31
  get samplingTarget() {
@@ -73,14 +73,13 @@ class AdaptiveSampler {
73
73
  * Determines if an object should be sampled based on the object's priority and
74
74
  * the number of objects sampled in this window.
75
75
  *
76
- * @param {object} obj - The object to check for sampleability.
77
- * @param {number} obj.priority - The priority of this object.
76
+ * @param {number} roll - The number to compare against the threshold
78
77
  *
79
78
  * @return {bool} True if the object should be sampled.
80
79
  */
81
- shouldSample(obj) {
80
+ shouldSample(roll) {
82
81
  ++this._seen
83
- if (obj.priority >= this._minSampledPriority) {
82
+ if (roll >= this._samplingThreshold) {
84
83
  this._incrementSampled()
85
84
  return true
86
85
  }
@@ -100,7 +99,7 @@ class AdaptiveSampler {
100
99
  }
101
100
 
102
101
  /**
103
- * Increments the sampled counter and adjusted the minimum priority to maintain
102
+ * Increments the sampled counter and adjusted the sampling threshold to maintain
104
103
  * a steady sample rate.
105
104
  */
106
105
  _incrementSampled() {
@@ -126,7 +125,7 @@ class AdaptiveSampler {
126
125
  _adjustStats(target) {
127
126
  if (this._seen) {
128
127
  const ratio = Math.min(target / this._seen, 1)
129
- this._minSampledPriority = 1 - ratio
128
+ this._samplingThreshold = 1 - ratio
130
129
  }
131
130
  }
132
131
  }
package/lib/attributes.js CHANGED
@@ -1,6 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const Config = require('./config')
3
4
  const logger = require('./logger').child({component: 'attributes'})
5
+ const isValidType = require('./util/attribute-types')
4
6
  const byteUtils = require('./util/byte-limit')
5
7
  const properties = require('./util/properties')
6
8
 
@@ -9,9 +11,17 @@ const properties = require('./util/properties')
9
11
  * @private
10
12
  */
11
13
  class Attributes {
12
- constructor(opts = Object.create(null)) {
13
- this.filter = opts.filter
14
- this.limit = opts.limit || Infinity
14
+ /**
15
+ * @param {string} scope
16
+ * The scope of the attributes this will collect. Must be `transaction` or
17
+ * `segment`.
18
+ *
19
+ * @param {number} [limit=Infinity]
20
+ * The maximum number of attributes to retrieve for each destination.
21
+ */
22
+ constructor(scope, limit = Infinity) {
23
+ this.filter = makeFilter(scope)
24
+ this.limit = limit
15
25
  this.attributes = Object.create(null)
16
26
  }
17
27
 
@@ -21,7 +31,7 @@ class Attributes {
21
31
  * @param {string} str - Object key name or value
22
32
  */
23
33
  isValidLength(str) {
24
- return byteUtils.isValidLength(str, 256)
34
+ return typeof str === 'number' || byteUtils.isValidLength(str, 255)
25
35
  }
26
36
 
27
37
  /**
@@ -87,15 +97,20 @@ class Attributes {
87
97
  * Adds given key-value pair to destination's agent attributes,
88
98
  * if it passes filtering rules.
89
99
  *
90
- * @param {string} scope - Attribute scope ('transaction' or 'segment')
91
100
  * @param {DESTINATIONS} destinations - The default destinations for this key.
92
101
  * @param {string} key - The attribute name.
93
102
  * @param {string} value - The attribute value.
94
- * @param {boolean} [truncateExempt=false] - Flag marking value exempt from truncation
103
+ * @param {boolean} [truncateExempt=false] - Flag marking value exempt from truncation
95
104
  */
96
- addAttribute(scope, destinations, key, value, truncateExempt = false) {
105
+ addAttribute(destinations, key, value, truncateExempt = false) {
97
106
  if (!isValidType(value)) {
98
- return logger.warn('Not adding attribute %s with %s value type', key, typeof value)
107
+ return logger.debug(
108
+ 'Not adding attribute %s with %s value type. This is expected for undefined' +
109
+ 'attributes and only an issue if an attribute is not expected to be undefined' +
110
+ 'or not of the type expected.',
111
+ key,
112
+ typeof value
113
+ )
99
114
  }
100
115
 
101
116
  if (!this.isValidLength(key)) {
@@ -106,38 +121,42 @@ class Attributes {
106
121
  }
107
122
 
108
123
  // Only set the attribute if at least one destination passed
109
- destinations = this.filter.filter(scope, destinations, key)
110
- if (destinations) {
111
- this._set(destinations, key, value, truncateExempt)
124
+ const validDestinations = this.filter(destinations, key)
125
+ if (validDestinations) {
126
+ this._set(validDestinations, key, value, truncateExempt)
112
127
  }
113
128
  }
114
129
 
115
130
  /**
116
131
  * Passthrough method for adding multiple unknown attributes at once.
117
132
  *
118
- * @param {string} scope - 'transaction' or 'segment'
119
133
  * @param {DESTINATIONS} destinations - The default destinations for these attributes.
120
134
  * @param {object} attrs - The attributes to add.
121
135
  */
122
- addAttributes(scope, destinations, attrs) {
136
+ addAttributes(destinations, attrs) {
123
137
  for (let key in attrs) {
124
138
  if (properties.hasOwn(attrs, key)) {
125
- this.addAttribute(scope, destinations, key, attrs[key])
139
+ this.addAttribute(destinations, key, attrs[key])
126
140
  }
127
141
  }
128
142
  }
129
143
  }
130
144
 
131
145
  /**
132
- * Checks incoming attribute value against valid types:
133
- * string, number, & boolean.
146
+ * Creates a filter function for the given scope.
134
147
  *
135
- * @param {*} val
148
+ * @param {string} scope - The scope of the filter to make.
136
149
  *
137
- * @return {boolean}
150
+ * @return {function} A function that performs attribute filtering for the given
151
+ * scope.
138
152
  */
139
- function isValidType(val) {
140
- return typeof val !== 'object' && val !== undefined
153
+ function makeFilter(scope) {
154
+ const {attributeFilter} = Config.getInstance()
155
+ if (scope === 'transaction') {
156
+ return (d, k) => attributeFilter.filterTransaction(d, k)
157
+ } else if (scope === 'segment') {
158
+ return (d, k) => attributeFilter.filterSegment(d, k)
159
+ }
141
160
  }
142
161
 
143
162
  module.exports = Attributes
@@ -88,8 +88,13 @@ function getAllIPAddresses() {
88
88
  const interfaceAddresses = interfaces[key].map(function getAddress(inter) {
89
89
  return inter.address
90
90
  })
91
- Array.prototype.push.apply(addresses, interfaceAddresses)
91
+
92
+ for (let index = 0; index < interfaceAddresses.length; index++) {
93
+ const address = interfaceAddresses[index]
94
+ addresses.push(address)
95
+ }
92
96
  }
97
+
93
98
  return addresses
94
99
  }, [])
95
100
  }
@@ -169,7 +169,7 @@ RemoteMethod.prototype._safeRequest = function _safeRequest(options) {
169
169
  const maxPayloadSize = this._config.max_payload_size_in_bytes
170
170
  var level = 'trace'
171
171
 
172
- if (!isValidLength(options.body, maxPayloadSize + 1)) {
172
+ if (!isValidLength(options.body, maxPayloadSize)) {
173
173
  logger.warn(
174
174
  'The payload size %d being sent to method %s exceeded the maximum size of %d',
175
175
  Buffer.byteLength(options.body, 'utf8'),
@@ -40,11 +40,6 @@ const SEGMENT_SCOPE_DETAILS = [
40
40
 
41
41
  const DESTINATION_DETAILS = [...TRANS_SCOPE_DETAILS, ...SEGMENT_SCOPE_DETAILS]
42
42
 
43
- const SCOPES = {
44
- segment: SEGMENT_SCOPE_DETAILS,
45
- transaction: TRANS_SCOPE_DETAILS
46
- }
47
-
48
43
  module.exports = exports = AttributeFilter
49
44
  exports.DESTINATIONS = DESTINATIONS
50
45
 
@@ -84,16 +79,53 @@ function AttributeFilter(config) {
84
79
  this.update()
85
80
  }
86
81
 
82
+ /**
83
+ * Tests a given key against the global and destination transaction filters.
84
+ *
85
+ * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
86
+ * @param {string} key - The name of the attribute to test.
87
+ *
88
+ * @return {DESTINATIONS} The destinations the attribute should be put.
89
+ */
90
+ AttributeFilter.prototype.filterTransaction = filterTransaction
91
+ function filterTransaction(destinations, key) {
92
+ return this._filter(TRANS_SCOPE_DETAILS, destinations, key)
93
+ }
94
+
95
+ /**
96
+ * Tests a given key against the global and destination segment filters.
97
+ *
98
+ * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
99
+ * @param {string} key - The name of the attribute to test.
100
+ *
101
+ * @return {DESTINATIONS} The destinations the attribute should be put.
102
+ */
103
+ AttributeFilter.prototype.filterSegment = function filterSegment(destinations, key) {
104
+ return this._filter(SEGMENT_SCOPE_DETAILS, destinations, key)
105
+ }
106
+
107
+ /**
108
+ * Tests a given key against all global and destination filters.
109
+ *
110
+ * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
111
+ * @param {string} key - The name of the attribute to test.
112
+ *
113
+ * @return {DESTINATIONS} The destinations the attribute should be put.
114
+ */
115
+ AttributeFilter.prototype.filterAll = function filterSegment(destinations, key) {
116
+ return this._filter(DESTINATION_DETAILS, destinations, key)
117
+ }
118
+
87
119
  /**
88
120
  * Tests a given key against the global and destination filters.
89
121
  *
90
- * @param {array} scope - 'transaction' or 'segment'.
91
- * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
92
- * @param {string} key - The name of the attribute to test.
122
+ * @param {array} scope - The destination details for filtering.
123
+ * @param {DESTINATIONS} destinations - The locations the attribute wants to be put.
124
+ * @param {string} key - The name of the attribute to test.
93
125
  *
94
126
  * @return {DESTINATIONS} The destinations the attribute should be put.
95
127
  */
96
- AttributeFilter.prototype.filter = function test(scope, destinations, key) {
128
+ AttributeFilter.prototype._filter = function _filter(scope, destinations, key) {
97
129
  // This method could be easily memoized since for a given destination and key
98
130
  // the result will always be the same until a configuration update happens. A
99
131
  // given application will also have a controllable set of destinations and
@@ -104,15 +136,13 @@ AttributeFilter.prototype.filter = function test(scope, destinations, key) {
104
136
  return DESTINATIONS.NONE
105
137
  }
106
138
 
107
- const scopeDetails = SCOPES[scope] || DESTINATION_DETAILS
108
-
109
139
  // These are lazy computed to avoid calculating them for cached results.
110
140
  var globalInclude = null
111
141
  var globalExclude = null
112
142
 
113
143
  // Iterate over each desination and see if the rules apply.
114
- for (var i = 0; i < scopeDetails.length; ++i) {
115
- var dest = scopeDetails[i]
144
+ for (var i = 0; i < scope.length; ++i) {
145
+ var dest = scope[i]
116
146
  var destId = dest.id
117
147
  var destName = dest.name
118
148
  if (!(this._enabledDestinations & destId)) {
@@ -88,6 +88,10 @@ exports.config = () => ({
88
88
  * @env NEW_RELIC_PROXY_PASS
89
89
  */
90
90
  proxy_pass: '',
91
+ // Serverless DT config defaults
92
+ trusted_account_key: null,
93
+ primary_application_id: null,
94
+ account_id: null,
91
95
  /**
92
96
  * Custom SSL certificates
93
97
  *
@@ -881,5 +885,5 @@ exports.config = () => ({
881
885
  * loop data.
882
886
  */
883
887
  native_metrics: {enabled: true}
884
- }
888
+ },
885
889
  })
package/lib/config/env.js CHANGED
@@ -137,7 +137,7 @@ const ENV_MAPPING = {
137
137
  enabled: 'NEW_RELIC_SERVERLESS_MODE_ENABLED'
138
138
  },
139
139
  trusted_account_key: 'NEW_RELIC_TRUSTED_ACCOUNT_KEY',
140
- application_id: 'NEW_RELIC_APPLICATION_ID',
140
+ primary_application_id: 'NEW_RELIC_PRIMARY_APPLICATION_ID',
141
141
  account_id: 'NEW_RELIC_ACCOUNT_ID'
142
142
  }
143
143