const { NoOpMeter, Timer } = require('measured-core');
const { SelfReportingMetricsRegistry } = require('measured-reporting');
const { validateTimerOptions } = require('measured-reporting').inputValidators;
/**
* A SignalFx Self Reporting Metrics Registry that disallows the use of meters.
* Meters don't make sense to use with SignalFx because the rate aggregations can be done within SignalFx itself.
* Meters simply waste DPM (Datapoints per Minute).
*
* @extends {SelfReportingMetricsRegistry}
*/
class SignalFxSelfReportingMetricsRegistry extends SelfReportingMetricsRegistry {
/**
* Creates a {@link Timer} or get the existing Timer for a given name and dimension combo with a NoOpMeter.
*
* @param {string} name The Metric name
* @param {Dimensions} dimensions any custom {@link Dimensions} for the Metric
* @param {number} publishingIntervalInSeconds a optional custom publishing interval
* @return {Timer}
*/
getOrCreateTimer(name, dimensions, publishingIntervalInSeconds) {
validateTimerOptions(name, dimensions, publishingIntervalInSeconds);
let timer;
if (this._registry.hasMetric(name, dimensions)) {
timer = this._registry.getMetric(name, dimensions);
} else {
timer = new Timer({ meter: new NoOpMeter() });
const key = this._registry.putMetric(name, timer, dimensions);
this._reporters.forEach(reporter => reporter.reportMetricOnInterval(key, publishingIntervalInSeconds));
}
return timer;
}
/**
* Meters are not reported to SignalFx.
* Meters do not make sense to use with SignalFx because the same values can be calculated
* using simple counters and aggregations within SignalFx itself.
*
* @param {string} name The Metric name
* @param {Dimensions} dimensions any custom {@link Dimensions} for the Metric
* @param {number} publishingIntervalInSeconds a optional custom publishing interval
* @return {NoOpMeter|*}
*/
getOrCreateMeter(name, dimensions, publishingIntervalInSeconds) {
this._log.error(
'Meters will not get reported using the SignalFx reporter as they waste DPM, please use a counter instead'
);
return new NoOpMeter();
}
/**
* Function exposes the event API of Signal Fx.
* See {@link https://github.com/signalfx/signalfx-nodejs#sending-events} for more details.
*
* @param {string} eventType The event type (name of the event time series).
* @param {SignalFxEventCategoryId} [category] the category of event. See {@link module:SignalFxEventCategories}. Value by default is USER_DEFINED.
* @param {Dimensions} [dimensions] a map of event dimensions, empty dictionary by default
* @param {Object.<string, string>} [properties] a map of extra properties on that event, empty dictionary by default
* @param {number} [timestamp] a timestamp, by default is current time.
*
* @example
* const {
* SignalFxSelfReportingMetricsRegistry,
* SignalFxMetricsReporter,
* SignalFxEventCategories
* } = require('measured-signalfx-reporter');
* const registry = new SignalFxSelfReportingMetricsRegistry(new SignalFxMetricsReporter(signalFxClient));
* registry.sendEvent('uncaughtException', SignalFxEventCategories.ALERT);
*/
sendEvent(eventType, category, dimensions, properties, timestamp) {
return Promise.all(
this._reporters.filter(reporter => typeof reporter.sendEvent === 'function').map(reporter =>
reporter.sendEvent(eventType, category, dimensions, properties, timestamp).catch(error => {
return error;
})
)
);
}
}
module.exports = SignalFxSelfReportingMetricsRegistry;