File: //home/arjun/.pm2/modules/pm2-logrotate/node_modules/pmx/lib/utils/datachecker.js
var probe = require('../Probe.js');
var Histogram = require('./probes/Histogram.js');
var debug = require('debug')('axm:smart:checker');
/**
* new smart({
* refresh : function, Returns monitored value
* callback : function, Called when error is detected
* dev : 0.2, Deviation that triggers the error
* timer : 100<ms>, Value refresh interval
* launch : 10000<ms>, Timelength after which monitoring begins
* ceil : 5 Number of times an error is detected before triggering callback
* calcDEv : mean How to compute the deviation
* });
*/
function dataChecker(opts) {
var self = this;
this._counter = 0;
opts = opts || {};
if (typeof(opts.refresh) !== 'function')
throw new Error('Refresh not defined or not a function');
this._refresh = opts.refresh;
this._monitored = false;
this._launch = opts.launch || 10000;
this._ceil = opts.ceil || 5;
this._timer = opts.timer || 1000;
this._dev = opts.dev || 0.2;
this._callback = opts.callback || null;
this._histogram = new Histogram();
this._calcDev = opts.calcDev || 'ema';
/*
* Select function to compute deviation
*/
var func = {
ema : this.normalDev,
mean : this.medianDev
}
this.computeDev = func[this._calcDev];
/**
* Display some probe if we need to debug
*/
if (opts.debug === true) {
if (opts.probes.indexOf('val') != -1) {
this._metric2 = new probe.metric({
name : 'Value',
value : function() {
return self._refresh();
}
});
}
if (opts.probes.indexOf('ema') != -1) {
this._metric3 = new probe.metric({
name : 'EMA',
value : function() {
return self._histogram.getEma();
}
});
}
}
/**
* Delay before monitoring starts
*/
setTimeout(function() {
self._monitored = true;
}, this._launch);
this.start();
};
//Calculate deviation of current value compared to EMA
dataChecker.prototype.normalDev = function() {
return ((this._refresh() - this._histogram.getEma()) / this._histogram.getEma() > this._dev);
}
//Calculate deviation of current EMA compared to Mean
dataChecker.prototype.medianDev = function() {
return ((this._histogram.getEma() - this._histogram._calculateMean()) / this._histogram._calculateMean() > this._dev);
}
dataChecker.prototype.stop = function() {
clearInterval(this._interval_timer);
};
dataChecker.prototype.start = function() {
var self = this;
debug('Checker started');
this._interval_timer = setInterval(function() {
self._histogram.update(self._refresh());
debug('Check', self._refresh(), self._histogram._calculateMean(), self._histogram.getEma());
if (self._monitored === true && self.computeDev() === true) {
self._counter++;
/**
* Triggers callback after N consecutive errors, then resets the counter
*/
if (self._counter >= self._ceil) {
debug('Anomaly detected', self._histogram.getEma(), self._refresh());
self._callback();
self.counter = 0;
}
}
else
self._counter = 0;
}, self._timer);
this._interval_timer.unref();
};
module.exports = dataChecker;