"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const meter_1 = require("../utils/metrics/meter"); const counter_1 = require("../utils/metrics/counter"); const histogram_1 = require("../utils/metrics/histogram"); const serviceManager_1 = require("../serviceManager"); const constants_1 = require("../constants"); const metrics_1 = require("../services/metrics"); class MetricsFeature { constructor() { this._var = new Map(); this.defaultAggregation = 'avg'; this._started = false; this._alreadySentData = []; this.AVAILABLE_MEASUREMENTS = [ 'min', 'max', 'sum', 'count', 'variance', 'mean', 'stddev', 'median', 'p75', 'p95', 'p99', 'p999' ]; this._var = serviceManager_1.ServiceManager.get('metricsMap'); serviceManager_1.ServiceManager.set('metricService', new metrics_1.default(this)); this.metricService = serviceManager_1.ServiceManager.get('metricService'); } init(config, force) { if (this._started === false) { this._started = true; const self = this; this.timer = setInterval(function () { const data = self._cookData(self._getVar()); // don't send empty data if (Object.keys(data).length !== 0 && serviceManager_1.ServiceManager.get('transport')) { serviceManager_1.ServiceManager.get('transport').setMetrics(data); } }, constants_1.default.METRIC_INTERVAL); this.timer.unref(); } this.metricService.init(config, force); return { histogram: this.histogram, meter: this.meter, counter: this.counter, metric: this.metric }; } transpose(variableName, reporter) { if (typeof variableName === 'object') { reporter = variableName.data; variableName = variableName.name; } if (typeof reporter !== 'function') { console.error('[PM2 IO][Transpose] reporter is not a function'); return undefined; } this._var.set(variableName, { value: reporter }); } meter(opts) { if (!opts.name) { console.error('[PM2 IO][Meter] Name not defined'); return undefined; } opts.unit = opts.unit || ''; const meter = new meter_1.default(opts); this._var.set(opts.name, { value: function () { return meter.val() + `${opts.unit}`; }, type: opts.type || opts.name, historic: this._historicEnabled(opts.historic), agg_type: opts.agg_type || this.defaultAggregation, unit: opts.unit }); return meter; } counter(opts) { if (!opts.name) { console.error('[PM2 IO][Counter] Name not defined'); return undefined; } const counter = new counter_1.default(opts); this._var.set(opts.name, { value: function () { return counter.val(); }, type: opts.type || opts.name, historic: this._historicEnabled(opts.historic), agg_type: opts.agg_type || this.defaultAggregation, unit: opts.unit }); return counter; } histogram(opts) { if (!opts.name) { console.error('[PM2 IO][Histogram] Name not defined'); return undefined; } opts.measurement = opts.measurement || 'mean'; opts.unit = opts.unit || ''; if (this.AVAILABLE_MEASUREMENTS.indexOf(opts.measurement) === -1) { console.error('[PM2 IO][Histogram] Measure type %s does not exists', opts.measurement); return undefined; } const histogram = new histogram_1.default(opts); this._var.set(opts.name, { value: function () { return (Math.round(histogram.val() * 100) / 100) + `${opts.unit}`; }, type: opts.type || opts.name, historic: this._historicEnabled(opts.historic), agg_type: opts.agg_type || this.defaultAggregation, unit: opts.unit }); return histogram; } metric(opts) { if (!opts.name) { console.error('[PM2 IO][Metric] Name not defined'); return undefined; } this._var.set(opts.name, { value: opts.value || 0, type: opts.type || opts.name, historic: this._historicEnabled(opts.historic), agg_type: opts.agg_type || this.defaultAggregation, unit: opts.unit }); const self = this; return { val: function () { let value = self._var.get(opts.name).value; if (typeof (value) === 'function') { value = value(); } return value; }, set: function (dt) { if (self._var.get(opts.name)) self._var.get(opts.name).value = dt; } }; } deleteMetric(name) { this._var.delete(name); this._alreadySentData.splice(this._alreadySentData.indexOf(name), 1); } destroy() { clearInterval(this.timer); this._getVar().clear(); this._started = false; this.metricService.destroyAll(); } /** ----------------------------------------- * Private Methods * ------------------------------------------ */ /** * Check if metric is historic or not * * @param historic * @returns {boolean} * @private */ _historicEnabled(historic) { if (historic === false) { return false; } if (typeof (historic) === 'undefined') { return true; } return true; } /** * Only for tests * * @returns {Object} */ _getVar() { return this._var; } /** * Data that will be sent to Keymetrics */ _cookData(data) { const cookedData = {}; const self = this; data.forEach(function (probe, probeName) { if (typeof (data.get(probeName).value) === 'undefined') { return false; } const value = self._getValue(data.get(probeName).value); // do not send data if this is always equal to 0 // probably an initialized metric which is not "active" if ((self._alreadySentData.indexOf(probeName) === -1 && value !== 0) || self._alreadySentData.indexOf(probeName) > -1) { if (self._alreadySentData.indexOf(probeName) === -1) { self._alreadySentData.push(probeName); } cookedData[probeName] = { value: value }; /** * Attach aggregation mode */ if (data.get(probeName).agg_type && data.get(probeName).agg_type !== 'none') { cookedData[probeName].agg_type = data.get(probeName).agg_type; } cookedData[probeName].historic = data.get(probeName).historic; cookedData[probeName].type = data.get(probeName).type; cookedData[probeName].unit = data.get(probeName).unit; } }); return cookedData; } _getValue(value) { if (typeof (value) === 'function') { return value(); } return value; } } exports.default = MetricsFeature; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9mZWF0dXJlcy9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esa0RBQTBDO0FBQzFDLHNEQUE4QztBQUM5QywwREFBa0Q7QUFDbEQsc0RBQWtEO0FBQ2xELDRDQUFvQztBQUNwQyxpREFBZ0Q7QUFFaEQ7SUF1QkU7UUF0QlEsU0FBSSxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ2xDLHVCQUFrQixHQUFXLEtBQUssQ0FBQTtRQUNsQyxhQUFRLEdBQVksS0FBSyxDQUFBO1FBQ3pCLHFCQUFnQixHQUFrQixFQUFFLENBQUE7UUFJcEMsMkJBQXNCLEdBQWtCO1lBQzlDLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLE9BQU87WUFDUCxVQUFVO1lBQ1YsTUFBTTtZQUNOLFFBQVE7WUFDUixRQUFRO1lBQ1IsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsTUFBTTtTQUNQLENBQUE7UUFHQyxJQUFJLENBQUMsSUFBSSxHQUFHLCtCQUFjLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQzVDLCtCQUFjLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxJQUFJLGlCQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUM3RCxJQUFJLENBQUMsYUFBYSxHQUFHLCtCQUFjLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQzFELENBQUM7SUFFRCxJQUFJLENBQUUsTUFBTyxFQUFFLEtBQU07UUFDbkIsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRTtZQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtZQUNwQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUE7WUFFakIsSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUM7Z0JBQ3ZCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFT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RUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQTtnQkFDN0QsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQTtnQkFFckQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQTthQUN0RDtRQUNILENBQUMsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxVQUFVLENBQUE7SUFDbkIsQ0FBQztJQUVELFNBQVMsQ0FBRSxLQUFLO1FBQ2QsSUFBSSxPQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssVUFBVSxFQUFFO1lBQ2hDLE9BQU8sS0FBSyxFQUFFLENBQUE7U0FDZjtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztDQUNGO0FBNVFELGlDQTRRQyJ9