File: //home/arjun/.pm2/modules/pm2-logrotate/node_modules/pmx/lib/utils/alert.js
var Notify = require('../notify.js');
var Sample = require('./sample.js');
var Histogram = require('./probes/Histogram.js');
var debug = require('debug')('axm:alert:checker');
/**
* Required:
* opts.mode
* opts.value
*
* Optional:
* extra.name
* opts.cmp
* opts.interval
* opts.msg
* opts.sample
*/
var Alert = function(opts, extra) {
var self = this;
var cmp;
if (typeof(opts.mode) === 'undefined')
return console.error('[Probe][Metric] Mode undefined!');
if (typeof(opts.cmp) === 'string') {
switch(opts.cmp) {
case '>':
cmp = function(a,b) {
return (a > b);
};
break;
case '<':
cmp = function(a, b) {
return (a < b);
};
break;
case '=':
cmp = function(a,b) {
return (a === b);
};
break;
default:
return console.error('[Probe][Metric] Mode does not exist!');
}
self.cmp_mode = opts.cmp;
opts.cmp = null;
}
else {
cmp = function(a,b) {
return (a > b);
};
self.cmp_mode = '>';
}
switch(opts.mode) {
case 'threshold':
if (typeof(opts.value) === 'undefined')
return console.error('[Probe][Metric][threshold] Val undefined!');
this.cmp = opts.cmp || function(a,b) {
return cmp(parseFloat(a), b);
};
break;
case 'threshold-avg':
if (typeof(opts.value) === 'undefined')
return console.error('[Probe][Metric][threshold-avg] Val undefined!');
this.sample = new Sample(opts.interval || 180);
this.cmp = function(value, threshold) {
this.sample.update(parseFloat(value));
if (this.start) {
if (typeof(opts.cmp) !== 'undefined' && opts.cmp !== null)
return opts.cmp(this.sample.getMean(), threshold);
return cmp(this.sample.getMean(), threshold);
}
};
break;
case 'smart':
this.sample = new Sample(opts.interval || 300);
this.small = new Sample(opts.sample || 30);
this.cmp = function(value, threshold) {
if (value !== null) {
this.sample.update(parseFloat(value));
this.small.update(parseFloat(value));
//debug('Check', value, Math.exp(- Math.pow(value - this.sample.getMean(), 2) / (2 * this.sample.getVariance())) / (Math.sqrt(2 * Math.PI) * this.sample.getStddev()));
if (this.start)
//return false
return (Math.exp(- Math.pow(value - this.sample.getMean(), 2) / (2 * this.sample.getVariance())) / (Math.sqrt(2 * Math.PI) * this.sample.getStddev()) < 0.00000001)
}
return false;
};
break;
default:
return console.error('[Probe][Metric] Mode does not exist!');
}
this.mode = opts.mode;
this.start = false;
//Start the data checking after 30s (default)
setTimeout(function() {
self.start = true;
}, opts.timeout || 30000);
this.reached = 0;
this.nullCheck = 0;
this.value = opts.value || null;
this.msg = opts.msg || ((extra && extra.name) ? ('Probe ' + extra.name + ' has reached value') : 'Alert value reached');
this.func = opts.func || opts.action || null;
};
Alert.prototype.tick = function(value) {
var self = this;
if (this.reached === 0) {
//Need 10 times null to trigger alert
if (value === null && this.nullCheck < 10) {
this.nullCheck += 1;
}
else if (this.cmp(value, this.value)) {
Notify.notify(this.msg + ' ' + this.value);
// Delay a bit call to custom function to allow PM2 to receive notify msg
if (this.func) setTimeout(function() {self.func(value)}, 50);
this.reached = 1;
this.nullCheck = 0;
}
}
else if (typeof(this.reached) !== 'undefined') {
if (!this.cmp(value, this.value))
this.reached = 0;
}
};
Alert.prototype.serialize = function() {
var self = this;
var ret = {
mode : self.mode
};
if (this.mode == 'threshold') {
ret.value = self.value;
ret.cmp = self.cmp_mode;
}
if (this.mode == 'threshold-avg') {
ret.value = self.value;
ret.interval = self.sample._size;
ret.cmp = self.cmp_mode;
}
return ret;
};
module.exports = Alert;