Skip to content

Commit

Permalink
chore: Document emitted events (#2561)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsumners-nr committed Sep 11, 2024
1 parent d534ba6 commit 8ff0ef3
Show file tree
Hide file tree
Showing 18 changed files with 438 additions and 34 deletions.
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 MAX_ERROR_TRACES_DEFAULT = 20
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 @@ function Agent(config) {
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 Down Expand Up @@ -226,6 +314,12 @@ util.inherits(Agent, EventEmitter)
*
* @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 @@ Agent.prototype.startStreaming = function startStreaming() {
*
* @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 @@ Agent.prototype._serverlessModeStart = function _serverlessModeStart(callback) {
* 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 @@ Agent.prototype._resetCustomEvents = function resetCustomEvents() {
}

/**
* 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 @@ Agent.prototype.reconfigure = function reconfigure(configuration) {
* 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

0 comments on commit 8ff0ef3

Please sign in to comment.