Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Document emitted events #2561

Merged
merged 1 commit into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 117 additions & 3 deletions lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,94 @@
const INITIAL_HARVEST_DELAY_MS = 1000
const DEFAULT_HARVEST_INTERVAL_MS = 60000

/**
* Indicates that the agent has finished connecting. It is preceded by
* {@link Agent#event:connecting}.
*
* @event Agent#connected
*/

/**
* Indicates that the agent is in the connecting state. That is, it is
* communicating with the New Relic data collector and performing requisite
* operations before the agent is ready to collect and send data.
*
* @event Agent#connecting
*/

/**
* Indicates that the agent has terminated, or lost, its connection to the
* New Relic data collector.
*
* @event Agent#disconnected
*/

/**
* Indicates that the agent has encountered, or generated, some error that
* prevents it from operating correctly. The agent state will be set to
* "errored."
*
* @event Agent#errored
*/

/**
* Indicates that the synchronous harvest cycle has completed. This will be
* prefaced by the {@link Agent#event:harvestStarted} event. It is only fired
* in a serverless context.
*
* @event Agent#harvestFinished
*/

/**
* Indicates that a synchronous harvest cycle (collecting data from the various
* aggregators and sending said data to the New Relic data collector) has
* started. This is only fired in a serverless context.
*
* @event Agent#harvestStarted
*/

/**
* Indicates that the agent state has entered the "started" state. That is,
* the agent has finished bootstrapping and is collecting and sending data.
*
* @event Agent#started
*/

/**
* Indicates that the agent is starting. This is typically the first event
* emitted by the agent.
*
* @event Agent#starting
*/

/**
* Indicates that the agent state has changed to the "stopped" state. That is,
* the agent is no longer collecting or sending data.
*
* @event Agent#stopped
*/

/**
* Indicates that the agent is entering its shutdown process.
*
* @event Agent#stopping
*/

/**
* Indicates that the transaction has begun recording data.
*
* @event Agent#transactionStarted
* @param {Transaction} currentTransaction
*/

/**
* Indicates that the transaction has stopped recording data and has been
* closed.
*
* @event Agent#transactionFinished
* @param {Transaction} currentTransaction
*/

/**
* There's a lot of stuff in this constructor, due to Agent acting as the
* orchestrator for New Relic within instrumented applications.
Expand Down Expand Up @@ -101,7 +189,7 @@
this.harvester
)

this.metrics.on('starting metric_data data send.', this._beforeMetricDataSend.bind(this))
this.metrics.on('starting_data_send-metric_data', this._beforeMetricDataSend.bind(this))

this.spanEventAggregator = createSpanEventAggregator(config, this)

Expand All @@ -119,7 +207,7 @@
periodMs: config.event_harvest_config.report_period_ms,
limit: config.event_harvest_config.harvest_limits.analytic_event_data,
config,
enabled: (config) => config.transaction_events.enabled

Check warning on line 210 in lib/agent.js

View workflow job for this annotation

GitHub Actions / lint (lts/*)

'config' is already declared in the upper scope on line 158 column 16
},
this
)
Expand All @@ -130,7 +218,7 @@
limit: config.event_harvest_config.harvest_limits.custom_event_data,
metricNames: NAMES.CUSTOM_EVENTS,
config,
enabled: (config) => config.custom_insights_events.enabled

Check warning on line 221 in lib/agent.js

View workflow job for this annotation

GitHub Actions / lint (lts/*)

'config' is already declared in the upper scope on line 158 column 16
},
this
)
Expand All @@ -140,7 +228,7 @@
periodMs: DEFAULT_HARVEST_INTERVAL_MS,
limit: MAX_ERROR_TRACES_DEFAULT,
config,
enabled: (config) => config.error_collector.enabled && config.collect_errors

Check warning on line 231 in lib/agent.js

View workflow job for this annotation

GitHub Actions / lint (lts/*)

'config' is already declared in the upper scope on line 158 column 16
},
this.collector,
this.harvester
Expand All @@ -151,7 +239,7 @@
periodMs: config.event_harvest_config.report_period_ms,
limit: config.event_harvest_config.harvest_limits.error_event_data,
config,
enabled: (config) => config.error_collector.enabled && config.error_collector.capture_events

Check warning on line 242 in lib/agent.js

View workflow job for this annotation

GitHub Actions / lint (lts/*)

'config' is already declared in the upper scope on line 158 column 16
},
this
)
Expand Down Expand Up @@ -226,6 +314,12 @@
*
* @param {Function} callback Continuation and error handler.
* @returns {void}
*
* @fires Agent#errored When configuration is not sufficient for operations or
* cannot establish a connection to the data collector.
* @fires Agent#starting
* @fires Agent#stopped When configuration indicates that the agent should be
* disabled.
*/
Agent.prototype.start = function start(callback) {
if (!callback) {
Expand Down Expand Up @@ -306,6 +400,8 @@
*
* @param {boolean} shouldImmediatelyHarvest Whether we should immediately schedule a harvest, or wait a cycle
* @param {Function} callback callback function that executes after harvest completes (now if immediate, otherwise later)
*
* @fires Agent#started
*/
Agent.prototype.onConnect = function onConnect(shouldImmediatelyHarvest, callback) {
this.harvester.update(this.config)
Expand Down Expand Up @@ -368,6 +464,11 @@
* current instrumentation and patch to the module loader.
*
* @param {Function} callback callback function to invoke after agent stop
*
* @fires Agent#errored When disconnecting from the data collector has resulted
* in some error.
* @fires Agent#stopped
* @fires Agent#stopping
*/
Agent.prototype.stop = function stop(callback) {
if (!callback) {
Expand Down Expand Up @@ -432,9 +533,13 @@
}

/**
* This method invokes a harvest synchronously.
* This method invokes a harvest synchronously, i.e. sends all data to the
* New Relic collector in a blocking fashion.
*
* NOTE: this doesn't currently work outside serverless mode.
*
* NOTE: this doesn't currently work outside of serverless mode.
* @fires Agent#harvestStarted
* @fires Agent#harvestFinished
*/
Agent.prototype.harvestSync = function harvestSync() {
logger.trace('Peparing to harvest.')
Expand Down Expand Up @@ -518,6 +623,15 @@
* creation of Transactions.
*
* @param {string} newState The new state of the agent.
*
* @fires Agent#connected
* @fires Agent#connecting
* @fires Agent#disconnected
* @fires Agent#errored
* @fires Agent#started
* @fires Agent#starting
* @fires Agent#stopped
* @fires Agent#stopping
*/
Agent.prototype.setState = function setState(newState) {
if (!STATES.hasOwnProperty(newState)) {
Expand Down
185 changes: 182 additions & 3 deletions lib/aggregators/base-aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,152 @@
const EventEmitter = require('events').EventEmitter
const logger = require('../logger').child({ component: 'base_aggregator' })

/**
* Triggered when the aggregator has finished sending data to the
* `analytic_event_data` collector endpoint.
*
* @event Aggregator#finished_data_send-analytic_event_data
*/

/**
* Triggered when an aggregator is sending data to the `analytic_event_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-analytic_event_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `custom_event_data` collector endpoint.
*
* @event Aggregator#finished_data_send-custom_event_data
*/

/**
* Triggered when an aggregator is sending data to the `custom_event_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-custom_event_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `error_data` collector endpoint.
*
* @event Aggregator#finished_data_send-error_data
*/

/**
* Triggered when an aggregator is sending data to the `error_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-error_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `error_event_data` collector endpoint.
*
* @event Aggregator#finished_data_send-error_event_data
*/

/**
* Triggered when an aggregator is sending data to the `error_event_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-error_event_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `log_event_data` collector endpoint.
*
* @event Aggregator#finished_data_send-log_event_data
*/

/**
* Triggered when an aggregator is sending data to the `log_event_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-log_event_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `metric_data` collector endpoint.
*
* @event Aggregator#finished_data_send-metric_data
*/

/**
* Triggered when an aggregator is sending data to the `metric_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-metric_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `span_event_data` collector endpoint.
*
* @event Aggregator#finished_data_send-span_event_data
*/

/**
* Triggered when an aggregator is sending data to the `span_event_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-span_event_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `sql_trace_data` collector endpoint.
*
* @event Aggregator#finished_data_send-sql_trace_data
*/

/**
* Triggered when an aggregator is sending data to the `sql_trace_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-sql_trace_data
*/

/**
* Triggered when the aggregator has finished sending data to the
* `transaction_sample_data` collector endpoint.
*
* @event Aggregator#finished_data_send-transaction_sample_data
*/

/**
* Triggered when an aggregator is sending data to the `transaction_sample_data`
* collector endpoint.
*
* @event Aggregator#starting_data_send-transaction_sample_data
*/

/**
* Baseline data aggregator that is used to ship data to the New Relic
* data collector. Specific data aggregators, e.g. an errors aggregator,
* extend this base object.
*
* Aggregators fire of several events. The events are named according to the
* pattern `<finished|starting>_data_send-<endpoint_name>`. As an example,
* if the aggregator is collecting data to send to the `error_event_data`
* endpoint, there will be two events:
*
* + `starting_data_send-error_event_data`
* + `finished_data_send-error_event_data`
*
* For a list of possible endpoints, see
* {@link https://source.datanerd.us/agents/agent-specs/tree/main/endpoints/protocol-version-17}.
*
* Note: effort has been made to document the events for every endpoint this
* agent interacts with, but due to the dynamic nature of the event names we
* may have missed some.
*/
class Aggregator extends EventEmitter {
constructor(opts, collector, harvester) {
super()
Expand All @@ -23,6 +169,16 @@ class Aggregator extends EventEmitter {
return true
}
this.enabled = this.isEnabled(opts.config)

/**
* The name of the collector endpoint that the
* aggregator will communicate with.
*
* @see https://source.datanerd.us/agents/agent-specs/tree/main/endpoints/protocol-version-17
*
* @type {string}
* @memberof Aggregator
*/
this.method = opts.method
this.collector = collector
this.sendTimer = null
Expand Down Expand Up @@ -90,7 +246,7 @@ class Aggregator extends EventEmitter {
_runSend(data, payload) {
if (!payload) {
this._afterSend(false)
this.emit(`finished ${this.method} data send.`)
this.emit(`finished_data_send-${this.method}`)
return
}

Expand All @@ -102,13 +258,36 @@ class Aggregator extends EventEmitter {

// TODO: Log?
this._afterSend(true)
this.emit(`finished ${this.method} data send.`)
this.emit(`finished_data_send-${this.method}`)
})
}

/**
* Serialize all collected data and ship it off to the New Relic data
* collector. The target endpoint is defined by {@link Aggregator#method}.
*
* @fires Aggregator#finished_data_send-analytic_event_data
* @fires Aggregator#starting_data_send-analytic_event_data
* @fires Aggregator#finished_data_send-custom_event_data
* @fires Aggregator#starting_data_send-custom_event_data
* @fires Aggregator#finished_data_send-error_data
* @fires Aggregator#starting_data_send-error_data
* @fires Aggregator#finished_data_send-error_event_data
* @fires Aggregator#starting_data_send-error_event_data
* @fires Aggregator#finished_data_send-log_event_data
* @fires Aggregator#starting_data_send-log_event_data
* @fires Aggregator#finished_data_send-metric_data
* @fires Aggregator#starting_data_send-metric_data
* @fires Aggregator#finished_data_send-span_event_data
* @fires Aggregator#starting_data_send-span_event_data
* @fires Aggregator#finished_data_send-sql_trace_data
* @fires Aggregator#starting_data_send-sql_trace_data
* @fires Aggregator#finished_data_send-transaction_sample_data
* @fires Aggregator#starting_data_send-transaction_sample_data
*/
send() {
logger.debug(`${this.method} Aggregator data send.`)
this.emit(`starting ${this.method} data send.`)
this.emit(`starting_data_send-${this.method}`)

const data = this._getMergeData()
if (this.isAsync) {
Expand Down
Loading
Loading