%PDF- %PDF-
Direktori : /lib/node_modules/pm2/node_modules/tx2/src/ |
Current File : //lib/node_modules/pm2/node_modules/tx2/src/metrics.js |
var Counter = require('./utils/probes/Counter.js') var Histogram = require('./utils/probes/Histogram.js') var Meter = require('./utils/probes/Meter.js') function getValue(value) { if (typeof(value) == 'function') return value() return value } const DEFAULT_AGGREGATION = 'avg' const AVAILABLE_AGG_TYPES = ['avg', 'min', 'max', 'sum', 'none'] const AVAILABLE_MEASUREMENTS = ['min', 'max','sum','count','variance','mean','stddev','median','p75','p95','p99','p999'] module.exports = { _metrics: {}, prepareData: function() { var cooked_data = {} Object.keys(this._metrics).forEach((probe_name) => { if (typeof(this._metrics[probe_name].value) == 'undefined') return false cooked_data[probe_name] = { value: getValue(this._metrics[probe_name].value) } if (this._metrics[probe_name].unit) cooked_data[probe_name].unit = this._metrics[probe_name].unit /** * Attach aggregation mode */ if (this._metrics[probe_name].agg_type && this._metrics[probe_name].agg_type != 'none') cooked_data[probe_name].agg_type = this._metrics[probe_name].agg_type if (this._metrics[probe_name].unit) cooked_data[probe_name].unit = this._metrics[probe_name].unit }) return cooked_data }, /** * This reflect data to keymetrics * pmx.transpose('prop name', fn) * * or * * pmx.transpose({ * name : 'variable name', * data : function() { return value } * }) */ transpose : function(variable_name, reporter) { if (typeof variable_name === 'object') { reporter = variable_name.data variable_name = variable_name.name } if (typeof reporter !== 'function') { return console.error('[PMX] reporter is not a function') } this._metrics[variable_name] = { value: reporter } }, metricExists: function(metric_name) { return !!this._metrics[metric_name] }, /** * @typedef {Object} Metric * @property {function} val Return the current value * @property {function} set Set value */ /** * Expose a Metric * @memberof TX2 * @param {string} name Name of the metric * @param {function} [function] Optional function to trigger every second to retrieve updated value * @returns {Metric} A metrics object * @example * tx2.metric('metric_name', () => obj.value) * @example * tx2.metric('metric_name', 'unit', () => obj.value) * @example * let mn = tx2.metric('metric_name') * mn.set(20) */ metric : function(opts, unit, val) { let name, value // tx2.metric('metric-name', 'unit', () => variable) if (typeof(opts) == 'string' && typeof(unit) == 'string') { name = opts unit = unit value = val } else if (typeof(opts) == 'string' && typeof(unit) == 'function') { name = opts value = unit } else if (typeof(opts) == 'string' && typeof(unit) == 'number') { name = opts value = unit } else if (typeof(opts) === 'object') { name = opts.name value = opts.val || opts.value unit = opts.unit || null } if (!name) return console.error('[PX2][Metric] Name not defined') this._metrics[name] = { value: value, unit: unit } return { val : () => { var value = this._metrics[name].value if (typeof(value) == 'function') value = value() return value }, set : (dt) => { this._metrics[name].value = dt } } }, /** * Expose a Metric of type Histogram. This computes a value accross based on the measurement option and will return a value accordingly @private * @memberof TX2 * @param {string} [opts.name] Metric Name * @param {string} [opts.measurement] Measurement made on time period, can be 'min', 'max','sum','count','variance','mean','stddev','median','p75','p95','p99','p999' * @param {function} [opts.value] Function to call to retrieve new value every second * @returns {} */ histogram : function(opts) { if (!opts.name) return console.error('[Metric][Histogram] Name not defined') opts.measurement = opts.measurement || 'mean' opts.unit = opts.unit || '' if (AVAILABLE_MEASUREMENTS.indexOf(opts.measurement) == -1) return console.error('[Metric][Histogram] Measure type %s does not exists', opts.measurement) var histogram = new Histogram(opts) this._metrics[opts.name] = { value: () => { if (opts.val || opts.value) { var value = opts.val || opts.value if (typeof(value) == 'function') value = value() histogram.update(value) } return (Math.round(histogram.val() * 100) / 100) }, unit : opts.unit } return histogram }, /** * Expose a Metric of type: Meter. This (???) * @private * @param {string} opts.name Name of the Metric * @returns {} */ meter : function(opts) { if (!opts.name) return console.error('[Metric][Meter] Name not defined') opts.unit = opts.unit || '' var meter = new Meter(opts) this._metrics[opts.name] = { value: function() { return meter.val() + '' + opts.unit }, unit : opts.unit } return meter }, /** * Expose a metric of type: Counter. * @typedef {object} Counter * @property {function} inc Increment value * @property {function} dev Decrement value */ /** * Expose a Metric of type: Counter. By calling .inc() or .dec() you update that value * @memberof TX2 * @param {string} name Name of the Metric * @returns {Counter} */ counter : function(opts) { let name, unit, agg_type = DEFAULT_AGGREGATION if (typeof(opts) == 'string') name = opts else { name = opts.name unit = opts.unit } if (!name) return console.error('[Metric][Counter] Name not defined') var counter = new Counter() this._metrics[name] = { value: function() { return counter.val() }, agg_type: agg_type, unit : unit || null } return counter } }