newrelic 11.10.3 → 11.10.4

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 (57) hide show
  1. package/NEWS.md +20 -0
  2. package/README.md +3 -1
  3. package/THIRD_PARTY_NOTICES.md +22 -27
  4. package/lib/agent.js +46 -217
  5. package/lib/aggregators/base-aggregator.js +19 -4
  6. package/lib/aggregators/event-aggregator.js +4 -3
  7. package/lib/aggregators/log-aggregator.js +2 -2
  8. package/lib/aggregators/trace-aggregator.js +2 -2
  9. package/lib/collector/api.js +63 -210
  10. package/lib/collector/remote-method.js +3 -1
  11. package/lib/collector/serverless.js +5 -112
  12. package/lib/config/index.js +1 -1
  13. package/lib/custom-events/custom-event-aggregator.js +3 -5
  14. package/lib/db/query-trace-aggregator.js +2 -2
  15. package/lib/errors/error-collector.js +0 -45
  16. package/lib/errors/error-event-aggregator.js +8 -2
  17. package/lib/errors/error-trace-aggregator.js +9 -2
  18. package/lib/harvester.js +84 -0
  19. package/lib/instrumentation/express.js +67 -37
  20. package/lib/instrumentation/fastify/spec-builders.js +6 -4
  21. package/lib/instrumentation/grpc-js/grpc.js +5 -1
  22. package/lib/instrumentation/openai.js +5 -4
  23. package/lib/instrumentation/pg.js +7 -6
  24. package/lib/metrics/metric-aggregator.js +2 -2
  25. package/lib/serverless/aws-lambda.js +2 -1
  26. package/lib/shim/datastore-shim.js +1 -79
  27. package/lib/shim/message-shim/index.js +2 -1
  28. package/lib/shim/message-shim/subscribe-consume.js +7 -4
  29. package/lib/shim/shim.js +14 -228
  30. package/lib/shim/specs/class.js +91 -0
  31. package/lib/shim/specs/constants.js +16 -0
  32. package/lib/shim/specs/index.js +28 -97
  33. package/lib/shim/specs/message-subscribe.js +41 -0
  34. package/lib/shim/specs/message.js +90 -0
  35. package/lib/shim/specs/middleware-mounter.js +77 -0
  36. package/lib/shim/specs/middleware.js +149 -0
  37. package/lib/shim/specs/operation.js +59 -0
  38. package/lib/shim/specs/query.js +47 -0
  39. package/lib/shim/specs/recorder.js +123 -0
  40. package/lib/shim/specs/render.js +42 -0
  41. package/lib/shim/specs/segment.js +114 -0
  42. package/lib/shim/specs/spec.js +18 -0
  43. package/lib/shim/specs/transaction.js +52 -0
  44. package/lib/shim/specs/wrap.js +61 -0
  45. package/lib/shim/transaction-shim.js +4 -26
  46. package/lib/shim/webframework-shim/common.js +3 -0
  47. package/lib/shim/webframework-shim/index.js +8 -127
  48. package/lib/shim/webframework-shim/middleware-mounter.js +5 -3
  49. package/lib/shimmer.js +5 -4
  50. package/lib/spans/create-span-event-aggregator.js +15 -10
  51. package/lib/spans/span-event-aggregator.js +2 -2
  52. package/lib/spans/streaming-span-event-aggregator.js +3 -2
  53. package/lib/transaction/trace/aggregator.js +2 -2
  54. package/lib/transaction/trace/index.js +1 -1
  55. package/lib/transaction/transaction-event-aggregator.js +3 -3
  56. package/lib/util/properties.js +1 -1
  57. package/package.json +3 -3
package/NEWS.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### v11.10.4 (2024-02-13)
2
+
3
+ #### Bug fixes
4
+
5
+ * Resolved application logs getting blocked when an excessive payload is encountered ([#2013](https://github.com/newrelic/node-newrelic/pull/2013)) ([365ded4](https://github.com/newrelic/node-newrelic/commit/365ded432b7781ee9c896bf0e067dac8cc2c45cc))
6
+ * Updated Shim to properly calculate the `_moduleRoot` on windows environments ([#2014](https://github.com/newrelic/node-newrelic/pull/2014)) ([ab0bd7f](https://github.com/newrelic/node-newrelic/commit/ab0bd7f87a5ed6ea38f51f068a2fc066af8f8d74))
7
+
8
+ #### Code refactoring
9
+
10
+ * Abstracted registering of new aggregators into a Harvester class that is responsible for starting, stopping, updating all registered aggregators. ([#1994](https://github.com/newrelic/node-newrelic/pull/1994)) ([1fb85a6](https://github.com/newrelic/node-newrelic/commit/1fb85a6f97c522ce2951911c670fcbddaa218049))
11
+ * Refactored specs into classes for easier code navigation ([#2004](https://github.com/newrelic/node-newrelic/pull/2004)) ([4daedc0](https://github.com/newrelic/node-newrelic/commit/4daedc08c707bec22056466ef15a45b50f20026f))
12
+
13
+ #### Miscellaneous chores
14
+
15
+ * **deps:** Updated @newrelic/security agent to v1.0.1 ([#2002](https://github.com/newrelic/node-newrelic/pull/2002)) ([b460c7b](https://github.com/newrelic/node-newrelic/commit/b460c7be589dd6fa801285b756bf66f62e0f10aa))
16
+
17
+ #### Tests
18
+
19
+ * Updated smoke tests to send data to the appropriate collector method ([#2005](https://github.com/newrelic/node-newrelic/pull/2005)) ([6130486](https://github.com/newrelic/node-newrelic/commit/6130486514268b02f68dccceb9b1e29d1e99c78e))
20
+
1
21
  ### v11.10.3 (2024-02-07)
2
22
 
3
23
  #### Features
package/README.md CHANGED
@@ -242,7 +242,9 @@ To [all contributors](https://github.com/newrelic/node-newrelic/graphs/contribut
242
242
 
243
243
  ## License
244
244
 
245
- The Node.js agent is licensed under the [Apache 2.0](https://apache.org/licenses/LICENSE-2.0.txt) License.
245
+ Except as noted below, the Node.js agent is licensed under the [Apache 2.0](https://apache.org/licenses/LICENSE-2.0.txt) License.
246
+
247
+ The New Relic [security agent](https://github.com/newrelic/csec-node-agent) is licensed under the New Relic Software License v1.0. The New Relic security agent module may be integrated like the New Relic Node.js agent.
246
248
 
247
249
  The Node.js agent also uses source code from third-party libraries. You can find full details on which libraries are used and the terms under which they are licensed in [the third-party notices document](https://github.com/newrelic/node-newrelic/blob/main/THIRD_PARTY_NOTICES.md).
248
250
 
@@ -921,52 +921,47 @@ Apache License
921
921
 
922
922
  ### @newrelic/security-agent
923
923
 
924
- This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v0.7.0](https://github.com/newrelic/csec-node-agent/tree/v0.7.0)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v0.7.0/LICENSE):
924
+ This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.0.1](https://github.com/newrelic/csec-node-agent/tree/v1.0.1)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v1.0.1/LICENSE):
925
925
 
926
926
  ```
927
- ## New Relic Pre-Release Software Notice
927
+ ## New Relic Software License v1.0
928
928
 
929
929
  ### Acceptance
930
930
 
931
- This software license applies to the repositories, directories, or files that it has been associated with (referred to here as the “Pre-Release Software”). In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
932
- License
931
+ This software license applies to the repositories, directories, or files that it has been associated with (referred to here as the Software”). In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
933
932
 
934
- New Relic, Inc. (“New Relic”) grants you a license under its copyrights and patents to do everything necessary for you to use the Pre-Release Software for the Permitted Purposes and subject to your compliance with the Confidentiality terms and all other Restrictions on Use. All other uses are prohibited.
933
+ ### License
935
934
 
936
- ### Permitted Purposes
937
-
938
- The Pre-Release Software is solely for use with New Relic’s proprietary SaaS service (“New Relic Service”). To use the Pre-Release Software you must have a valid and active subscription agreement to the New Relic Service. You may not use the Pre-Release Software in conjunction with any other similar service.
939
-
940
- Use of the Pre-Release Software is limited to evaluation and feedback, including pull requests, of the pre-release features and capabilities. The use of the Pre-Release Software requires a signed New Relic Pre-Release Agreement. The New Relic Pre-Release Agreement will control in event of a conflict with this license. The Pre-Release Software is also subject to the New Relic pre-release policy. A copy of the New Relic Pre-release policy available at https://docs.newrelic.com/docs/licenses/license-information/referenced-policies/new-relic-pre-release-policy/.
935
+ New Relic grants you a license for the Software to do everything you might do with the Software that would otherwise infringe the New Relic’s copyrights or patent rights, conditional on only using the Software for Permitted Purposes and compliance with all other Restrictions on Use. All other uses are prohibited.
941
936
 
942
- ### Confidentiality
937
+ ### Permitted Purposes
943
938
 
944
- Any Pre-Release Software not posted publicly contains New Relic Trade Secrets. You may not disclose the features and capabilities of the Pre-Release Software to any third party by any means. You will use commercially reasonable measures to maintain the secrecy of the features and capabilities of the Pre-Release Software. Without limiting the permissions you receive under any open source software (“OSS”) license, you may not disclose the source code of any OSS included as part of the Pre-Release Software in a way that discloses the New Relic Trade Secrets.
939
+ The Software is solely for use with New Relic’s proprietary SaaS service (“New Relic Service”). To use the Software you must have a valid and active subscription agreement to the New Relic Service. You may not use the Software in conjunction with any other similar service.
945
940
 
946
- ### Restrictions on Use
941
+ ### Restrictions on Use
947
942
 
948
- 1. The use of the Pre-Release Software is limited to you and your organization. You cannot expose the Pre-Release Software to third parties via the network or use the Pre-Release Software on behalf of anyone else.
949
- 2. You cannot modify the Pre-Release Software. You can compile or link the Pre-Release Software into your programs as described in the New Relic Documentation, but you cannot otherwise make any derivative works of the Pre-Release Software.
950
- 3. You cannot reverse engineer or decompile the Pre-Release Software.
951
- 4. You cannot use the Pre-Release Software for competitive analysis, benchmarking, or any purposes that compete with or are intended to compete with New Relic.
952
- 5. You cannot remove or obscure any proprietary notices in the Pre-Release Software.
953
- 6. You can only copy the Software to the extent needed to use the Pre-Release Software within your organization. You cannot distribute the Software to any third parties.
954
- 7. You can only use the New Relic Services and the Pre-Release Software consistent with New Relic’s product Documentation and Acceptable Use Policy.
943
+ 1. The use of the Software is limited to you and your organization. You cannot expose the Software to third parties via the network or use the Software on behalf of anyone else.
944
+ 2. You cannot modify the Software. You can compile or link the Software into your programs as described in the New Relic Documentation, but you cannot otherwise make any derivative works of the Software.
945
+ 3. You cannot reverse engineer or decompile the Software.
946
+ 4. You cannot use the Software for competitive analysis, benchmarking, or any purposes that compete with or are intended to compete with New Relic.
947
+ 5. You cannot remove or obscure any proprietary notices in the Software.
948
+ 6. You can only copy the Software to the extent needed to use the Software within your organization. You cannot distribute the Software to any third parties.
949
+ 7. You can only use the New Relic Services and the Software consistent with your subscription agreement with New Relic, New Relic’s product Documentation and Acceptable Use Policy.
955
950
 
956
951
  ### Intellectual Property
957
952
 
958
- Any feedback provided to New Relic about the Pre-Release Software, including feedback provided as source code, comments, or other copyrightable or patentable material, is provided to New Relic under the terms of the Apache Software License, version 2. If you do not provide attribution information or a copy of the license with your feedback, you waive the performance of those requirements of the Apache License with respect to New Relic. The license grant regarding any feedback is irrevocable and persists past the termination of this license.
953
+ Any feedback provided to New Relic about the Software, including feedback provided as source code, comments, or other copyrightable or patentable material, is provided to New Relic under the terms of the Apache Software License, version 2. If you do not provide attribution information or a copy of the license with your feedback, you waive the performance of those requirements of the Apache License with respect to New Relic. The license grant regarding any feedback is irrevocable and persists past the termination of this license.
959
954
 
960
955
  ### Termination
961
956
 
962
- This license terminates when the Pre-Release Software stops being provided by New Relic or when described by the New Relic Pre-Release Agreement, whichever comes first. When this license terminates, you have a commercially reasonable time to either remove the Pre-Release Software from your systems or to upgrade to a publicly released version of the Software.
957
+ This license terminates when the Software stops being provided by New Relic or when described by the New Relic subscription agreement, whichever comes first. When this license terminates, you have a commercially reasonable time to either remove the Software from your systems.
963
958
 
964
959
  ### Other Terms
965
960
 
966
- 1. The Pre-Release Software is provided “AS IS.” New Relic disclaims all warranties, whether express, implied, statutory or otherwise, including warranties of merchantability, fitness for a particular purpose, title and noninfringement.
967
- 2. The Pre-Release Software has known flaws. You use the Pre-Release Software at your own risk.
968
- 3. To the full extent permitted by law, New Relic will have no liability arising from or related to the Pre-Release Software or from this license for any direct, indirect, special, incidental, or consequential damages of any kind, even if advised of their possibility in advance, and regardless of legal theory (whether contract, tort, negligence, strict liability or otherwise).
969
- 4. The Pre-Release Software may contain third-party software, including open source software. The third party software is governed by its own license and subject to its own terms, disclosed in the provided licensing information associated with the third party components. If a source code disclosure is required under the terms of the license covering any OSS component, the source code can be requested of New Relic by emailing opensource@newrelic.com.
961
+ 1. The Software is provided “AS IS.” New Relic disclaims all warranties, whether express, implied, statutory or otherwise, including warranties of merchantability, fitness for a particular purpose, title, and noninfringement.
962
+ 2. To the full extent permitted by law, New Relic will have no liability arising from or related to the Software or from this license for any direct, indirect, special, incidental, or consequential damages of any kind, even if advised of their possibility in advance, and regardless of legal theory (whether contract, tort, negligence, strict liability or otherwise).
963
+ 3. The Software may contain third-party software, including open source software (“OSS”). The third party software is governed by its own license and subject to its own terms, disclosed in the provided licensing information associated with the third party components. If a source code disclosure is required under the terms of the license covering any OSS component, the source code can be requested of New Relic by emailing opensource@newrelic.com.
964
+
970
965
 
971
966
  ```
972
967
 
@@ -2431,7 +2426,7 @@ THE SOFTWARE.
2431
2426
 
2432
2427
  ### eslint-plugin-jsdoc
2433
2428
 
2434
- This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v39.9.1](https://github.com/gajus/eslint-plugin-jsdoc/tree/v39.9.1)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v39.9.1/LICENSE):
2429
+ This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.0.5](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.0.5)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.0.5/LICENSE):
2435
2430
 
2436
2431
  ```
2437
2432
  Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
package/lib/agent.js CHANGED
@@ -39,6 +39,7 @@ const {
39
39
  maybeAddQueueAttributes
40
40
  } = require('./util/attributes')
41
41
  const synthetics = require('./synthetics')
42
+ const Harvester = require('./harvester')
42
43
 
43
44
  // Map of valid states to whether or not data collection is valid
44
45
  const STATES = {
@@ -77,7 +78,7 @@ function Agent(config) {
77
78
  this._state = 'stopped'
78
79
  this.config = config
79
80
  this.environment = require('./environment')
80
- this.version = this.config.version
81
+ this.version = config.version
81
82
 
82
83
  if (config.serverless_mode.enabled) {
83
84
  this.collector = new ServerlessCollector(this)
@@ -87,6 +88,7 @@ function Agent(config) {
87
88
 
88
89
  this.mapper = new MetricMapper()
89
90
  this.metricNameNormalizer = new MetricNormalizer(this.config, 'metric name')
91
+ this.harvester = new Harvester()
90
92
 
91
93
  this.metrics = new MetricAggregator(
92
94
  {
@@ -95,12 +97,13 @@ function Agent(config) {
95
97
  mapper: this.mapper,
96
98
  normalizer: this.metricNameNormalizer
97
99
  },
98
- this.collector
100
+ this.collector,
101
+ this.harvester
99
102
  )
100
103
 
101
104
  this.metrics.on('starting metric_data data send.', this._beforeMetricDataSend.bind(this))
102
105
 
103
- this.spanEventAggregator = createSpanEventAggregator(config, this.collector, this.metrics)
106
+ this.spanEventAggregator = createSpanEventAggregator(config, this)
104
107
 
105
108
  this.transactionNameNormalizer = new MetricNormalizer(this.config, 'transaction name')
106
109
  // Segment term based tx renaming for MGI mitigation.
@@ -114,45 +117,53 @@ function Agent(config) {
114
117
  this.transactionEventAggregator = new TransactionEventAggregator(
115
118
  {
116
119
  periodMs: config.event_harvest_config.report_period_ms,
117
- limit: config.event_harvest_config.harvest_limits.analytic_event_data
120
+ limit: config.event_harvest_config.harvest_limits.analytic_event_data,
121
+ config,
122
+ enabled: (config) => config.transaction_events.enabled
118
123
  },
119
- this.collector,
120
- this.metrics
124
+ this
121
125
  )
122
126
 
123
127
  this.customEventAggregator = new CustomEventAggregator(
124
128
  {
125
129
  periodMs: config.event_harvest_config.report_period_ms,
126
- limit: config.event_harvest_config.harvest_limits.custom_event_data
130
+ limit: config.event_harvest_config.harvest_limits.custom_event_data,
131
+ metricNames: NAMES.CUSTOM_EVENTS,
132
+ config,
133
+ enabled: (config) => config.custom_insights_events.enabled
127
134
  },
128
- this.collector,
129
- this.metrics
135
+ this
130
136
  )
131
137
 
132
138
  const errorTraceAggregator = new ErrorTraceAggregator(
133
139
  {
134
140
  periodMs: DEFAULT_HARVEST_INTERVAL_MS,
135
- limit: MAX_ERROR_TRACES_DEFAULT
141
+ limit: MAX_ERROR_TRACES_DEFAULT,
142
+ config,
143
+ enabled: (config) => config.error_collector.enabled && config.collect_errors
136
144
  },
137
- this.collector
145
+ this.collector,
146
+ this.harvester
138
147
  )
139
148
 
140
149
  const errorEventAggregator = new ErrorEventAggregator(
141
150
  {
142
151
  periodMs: config.event_harvest_config.report_period_ms,
143
- limit: config.event_harvest_config.harvest_limits.error_event_data
152
+ limit: config.event_harvest_config.harvest_limits.error_event_data,
153
+ config,
154
+ enabled: (config) => config.error_collector.enabled && config.error_collector.capture_events
144
155
  },
145
- this.collector,
146
- this.metrics
156
+ this
147
157
  )
148
158
 
149
159
  this.logs = new LogAggregator(
150
160
  {
151
161
  periodMs: config.event_harvest_config.report_period_ms,
152
- limit: config.event_harvest_config.harvest_limits.log_event_data
162
+ limit: config.event_harvest_config.harvest_limits.log_event_data,
163
+ config,
164
+ enabled: (config) =>
165
+ config.application_logging.enabled && config.application_logging.forwarding.enabled
153
166
  },
154
- this.collector,
155
- this.metrics,
156
167
  this
157
168
  )
158
169
 
@@ -164,11 +175,13 @@ function Agent(config) {
164
175
  this.traces = new TransactionTraceAggregator(
165
176
  {
166
177
  periodMs: DEFAULT_HARVEST_INTERVAL_MS,
167
- config: this.config,
178
+ config,
168
179
  isAsync: !config.serverless_mode.enabled,
169
- method: 'transaction_sample_data'
180
+ method: 'transaction_sample_data',
181
+ enabled: (config) => config.transaction_tracer.enabled && config.collect_traces
170
182
  },
171
- this.collector
183
+ this.collector,
184
+ this.harvester
172
185
  )
173
186
  this.transactionSampler = new AdaptiveSampler({
174
187
  agent: this,
@@ -179,12 +192,14 @@ function Agent(config) {
179
192
 
180
193
  this.queries = new QueryTraceAggregator(
181
194
  {
182
- config: this.config,
195
+ config,
183
196
  periodMs: DEFAULT_HARVEST_INTERVAL_MS,
184
197
  method: 'sql_trace_data',
185
- isAsync: !config.serverless_mode.enabled
198
+ isAsync: !config.serverless_mode.enabled,
199
+ enabled: (config) => config.slow_sql.enabled
186
200
  },
187
- this.collector
201
+ this.collector,
202
+ this.harvester
188
203
  )
189
204
 
190
205
  // Set up all the configuration events the agent needs to listen for.
@@ -276,190 +291,15 @@ Agent.prototype.start = function start(callback) {
276
291
  * @param {Function} callback The callback to invoke when all data types have been sent.
277
292
  */
278
293
  Agent.prototype.forceHarvestAll = function forceHarvestAll(callback) {
279
- const agent = this
280
- const promises = []
281
-
282
- const metricPromise = new Promise((resolve) => {
283
- agent.metrics.once('finished metric_data data send.', function onMetricsFinished() {
284
- resolve()
285
- })
286
- agent.metrics.send()
287
- })
288
-
289
- promises.push(metricPromise)
290
-
291
- // TODO: plumb config through to aggregators so they can do their own checking.
292
- if (
293
- agent.config.distributed_tracing.enabled &&
294
- agent.config.span_events.enabled &&
295
- !agent.spanEventAggregator.isStream // Not valid to send on streaming aggregator
296
- ) {
297
- const spanPromise = new Promise((resolve) => {
298
- agent.spanEventAggregator.once(
299
- 'finished span_event_data data send.',
300
- function onSpansFinished() {
301
- resolve()
302
- }
303
- )
304
- agent.spanEventAggregator.send()
305
- })
306
-
307
- promises.push(spanPromise)
308
- }
309
-
310
- if (agent.config.custom_insights_events.enabled) {
311
- const customEventPromise = new Promise((resolve) => {
312
- agent.customEventAggregator.once(
313
- 'finished custom_event_data data send.',
314
- function onCustomEventsFinished() {
315
- resolve()
316
- }
317
- )
318
- agent.customEventAggregator.send()
319
- })
320
-
321
- promises.push(customEventPromise)
322
- }
323
-
324
- if (agent.config.transaction_events.enabled) {
325
- const transactionEventPromise = new Promise((resolve) => {
326
- agent.transactionEventAggregator.once(
327
- 'finished analytic_event_data data send.',
328
- function onTransactionEventsFinished() {
329
- resolve()
330
- }
331
- )
332
- agent.transactionEventAggregator.send()
333
- })
334
-
335
- promises.push(transactionEventPromise)
336
- }
337
-
338
- if (agent.config.transaction_tracer.enabled && agent.config.collect_traces) {
339
- const transactionTracePromise = new Promise((resolve) => {
340
- agent.traces.once('finished transaction_sample_data data send.', function onTracesFinished() {
341
- resolve()
342
- })
343
- agent.traces.send()
344
- })
345
-
346
- promises.push(transactionTracePromise)
347
- }
348
-
349
- if (agent.config.slow_sql.enabled) {
350
- const sqlTracePromise = new Promise((resolve) => {
351
- agent.queries.once('finished sql_trace_data data send.', function onSqlTracesFinished() {
352
- resolve()
353
- })
354
- agent.queries.send()
355
- })
356
-
357
- promises.push(sqlTracePromise)
358
- }
359
-
360
- const errorCollectorEnabled = agent.config.error_collector && agent.config.error_collector.enabled
361
-
362
- if (errorCollectorEnabled && agent.config.collect_errors) {
363
- const errorTracePromise = new Promise((resolve) => {
364
- agent.errors.traceAggregator.once(
365
- 'finished error_data data send.',
366
- function onErrorTracesFinished() {
367
- resolve()
368
- }
369
- )
370
- agent.errors.traceAggregator.send()
371
- })
372
-
373
- promises.push(errorTracePromise)
374
- }
375
-
376
- if (errorCollectorEnabled && agent.config.error_collector.capture_events) {
377
- const errorEventPromise = new Promise((resolve) => {
378
- agent.errors.eventAggregator.once(
379
- 'finished error_event_data data send.',
380
- function onErrorEventsFinished() {
381
- resolve()
382
- }
383
- )
384
- agent.errors.eventAggregator.send()
385
- })
386
-
387
- promises.push(errorEventPromise)
388
- }
389
-
390
- if (
391
- agent.config.application_logging.enabled &&
392
- agent.config.application_logging.forwarding.enabled
393
- ) {
394
- const logEventPromise = new Promise((resolve) => {
395
- agent.logs.once('finished log_event_data data send.', function onLogEventsFinished() {
396
- resolve()
397
- })
398
- agent.logs.send()
399
- })
400
-
401
- promises.push(logEventPromise)
402
- }
403
-
404
- Promise.all(promises).then(() => {
405
- // Get out of the promise so callback errors aren't treated as
406
- // promise rejections.
407
- setImmediate(callback)
408
- })
409
- }
410
-
411
- Agent.prototype.stopAggregators = function stopAggregators() {
412
- this.metrics.stop()
413
- this.errors.stop()
414
- this.traces.stop()
415
- this.queries.stop()
416
- this.spanEventAggregator.stop()
417
- this.transactionEventAggregator.stop()
418
- this.customEventAggregator.stop()
419
- this.logs.stop()
294
+ this.harvester.clear(callback)
420
295
  }
421
296
 
422
297
  Agent.prototype.startStreaming = function startStreaming() {
423
- if (
424
- this.spanEventAggregator.isStream &&
425
- this.config.distributed_tracing.enabled &&
426
- this.config.span_events.enabled
427
- ) {
298
+ if (this.spanEventAggregator.isStream && this.spanEventAggregator.enabled) {
428
299
  this.spanEventAggregator.start()
429
300
  }
430
301
  }
431
302
 
432
- Agent.prototype.startAggregators = function startAggregators() {
433
- this.metrics.start()
434
- this.errors.start()
435
- if (this.config.transaction_tracer.enabled && this.config.collect_traces) {
436
- this.traces.start()
437
- }
438
-
439
- if (this.config.slow_sql.enabled) {
440
- this.queries.start()
441
- }
442
-
443
- if (this.config.distributed_tracing.enabled && this.config.span_events.enabled) {
444
- this.spanEventAggregator.start()
445
- }
446
-
447
- if (this.config.transaction_events.enabled) {
448
- this.transactionEventAggregator.start()
449
- }
450
-
451
- if (this.config.custom_insights_events.enabled) {
452
- this.customEventAggregator.start()
453
- }
454
-
455
- if (
456
- this.config.application_logging.enabled &&
457
- this.config.application_logging.forwarding.enabled
458
- ) {
459
- this.logs.start()
460
- }
461
- }
462
-
463
303
  /**
464
304
  * Completes any final setup upon full connection to New Relic
465
305
  * servers and sets the agent state to 'started'.
@@ -468,8 +308,7 @@ Agent.prototype.startAggregators = function startAggregators() {
468
308
  * @param {Function} callback callback function that executes after harvest completes (now if immediate, otherwise later)
469
309
  */
470
310
  Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
471
- this._reconfigureAggregators(this.config)
472
-
311
+ this.harvester.update(this.config)
473
312
  generateLoggingSupportMetrics(this)
474
313
 
475
314
  if (this.config.certificates && this.config.certificates.length > 0) {
@@ -481,20 +320,9 @@ Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callbac
481
320
  this.setState('started')
482
321
  }
483
322
 
484
- Agent.prototype._reconfigureAggregators = function _reconfigureAggregators(config) {
485
- this.metrics.reconfigure(config)
486
- this.errors.reconfigure(config)
487
- this.traces.reconfigure(config)
488
- this.queries.reconfigure(config)
489
- this.spanEventAggregator.reconfigure(config)
490
- this.transactionEventAggregator.reconfigure(config)
491
- this.customEventAggregator.reconfigure(config)
492
- this.logs.reconfigure(config)
493
- }
494
-
495
323
  Agent.prototype._scheduleHarvests = function _scheduleHarvests(shouldImmediatelyHarvest, callback) {
496
324
  if (!shouldImmediatelyHarvest) {
497
- this.startAggregators()
325
+ this.harvester.start()
498
326
  setImmediate(callback)
499
327
  return
500
328
  }
@@ -514,7 +342,7 @@ Agent.prototype._scheduleHarvests = function _scheduleHarvests(shouldImmediately
514
342
  logger.info(`Starting initial ${INITIAL_HARVEST_DELAY_MS}ms harvest.`)
515
343
 
516
344
  agent.forceHarvestAll(function afterAllAggregatorsSend() {
517
- agent.startAggregators()
345
+ agent.harvester.start()
518
346
  callback()
519
347
  })
520
348
  }, INITIAL_HARVEST_DELAY_MS)
@@ -550,7 +378,7 @@ Agent.prototype.stop = function stop(callback) {
550
378
 
551
379
  this.setState('stopping')
552
380
 
553
- this.stopAggregators()
381
+ this.harvester.stop()
554
382
 
555
383
  sampler.stop()
556
384
 
@@ -585,7 +413,8 @@ Agent.prototype._resetErrors = function resetErrors() {
585
413
 
586
414
  // TODO: is this still necessary?
587
415
  // Likely do more direct with new config
588
- this.errors.reconfigure(this.config)
416
+ this.errors.traceAggregator.reconfigure(this.config)
417
+ this.errors.eventAggregator.reconfigure(this.config)
589
418
  }
590
419
 
591
420
  /**
@@ -9,18 +9,32 @@ const EventEmitter = require('events').EventEmitter
9
9
  const logger = require('../logger').child({ component: 'base_aggregator' })
10
10
 
11
11
  class Aggregator extends EventEmitter {
12
- constructor(opts, collector) {
12
+ constructor(opts, collector, harvester) {
13
13
  super()
14
14
 
15
15
  this.defaultPeriod = this.periodMs = opts.periodMs
16
16
  this.defaultLimit = this.limit = opts.limit
17
17
  this.runId = opts.runId
18
18
  this.isAsync = opts.isAsync || false
19
+ // function to pass in to determine if we can start a given aggregator
20
+ this.isEnabled =
21
+ opts.enabled ||
22
+ function defaultEnabled() {
23
+ return true
24
+ }
25
+ this.enabled = this.isEnabled(opts.config)
19
26
  this.method = opts.method
20
-
21
27
  this.collector = collector
22
-
23
28
  this.sendTimer = null
29
+ harvester.add(this)
30
+ }
31
+
32
+ get enabled() {
33
+ return this._enabled
34
+ }
35
+
36
+ set enabled(condition) {
37
+ this._enabled = condition
24
38
  }
25
39
 
26
40
  start() {
@@ -81,7 +95,7 @@ class Aggregator extends EventEmitter {
81
95
  }
82
96
 
83
97
  // This can be synchronous for the serverless collector.
84
- this.collector[this.method](payload, (error, response) => {
98
+ this.collector.send(this.method, payload, (error, response) => {
85
99
  if (response && response.retainData) {
86
100
  this._merge(data)
87
101
  }
@@ -110,6 +124,7 @@ class Aggregator extends EventEmitter {
110
124
 
111
125
  reconfigure(config) {
112
126
  this.runId = config.run_id
127
+ this.enabled = this.isEnabled(config)
113
128
  }
114
129
  }
115
130
 
@@ -16,12 +16,13 @@ const PriorityQueue = require('../priority-queue')
16
16
  * @class
17
17
  */
18
18
  class EventAggregator extends Aggregator {
19
- constructor(opts, collector, metricsAggregator) {
20
- super(opts, collector)
19
+ constructor(opts, agent) {
20
+ const { metrics, collector, harvester } = agent
21
+ super(opts, collector, harvester)
21
22
  // EventEmitter inits an _events collection. So we have to avoid collision
22
23
  this._items = new PriorityQueue(opts.limit)
23
24
  this._metricNames = opts.metricNames
24
- this._metrics = metricsAggregator
25
+ this._metrics = metrics
25
26
  }
26
27
 
27
28
  get seen() {
@@ -17,12 +17,12 @@ const NAMES = require('../metrics/names')
17
17
  * @class
18
18
  */
19
19
  class LogAggregator extends EventAggregator {
20
- constructor(opts, collector, metrics, agent) {
20
+ constructor(opts, agent) {
21
21
  opts = opts || {}
22
22
  opts.method = opts.method || 'log_event_data'
23
23
  opts.metricNames = NAMES.LOGGING
24
24
 
25
- super(opts, collector, metrics)
25
+ super(opts, agent)
26
26
  this.agent = agent
27
27
  }
28
28
 
@@ -8,8 +8,8 @@
8
8
  const Aggregator = require('./base-aggregator')
9
9
 
10
10
  class TraceAggregator extends Aggregator {
11
- constructor(opts, collector) {
12
- super(opts, collector)
11
+ constructor(opts, collector, harvester) {
12
+ super(opts, collector, harvester)
13
13
  }
14
14
  }
15
15