All Downloads are FREE. Search and download functionalities are using the official Maven repository.

app.services.monitor.js Maven / Gradle / Ivy

The newest version!
define([
  'angular',
  'lodash',
  'underscore.string',
  'simple_statistics'
],
function (angular, _, str, ss) {
  'use strict';

  var module = angular.module('kibana.services');

  module.service('monitor', function() {

    var self = this;

    this.check = function(data, title, threshold) {
      var ret, latestId;
      latestId = _.max(_.keys(data));
      if (threshold) {
        ret = data[latestId] - threshold > 0 ? true : false;
      } else {
        ret = detect(data);
      };
      if (ret) {
        self.notify(title, data[latestId]);
      };
    };

    var detect = function(data) {
      var timeSeries = _.pairs(data);
      var duration = (new Date().getTime() - parseInt(timeSeries[0][0]))/3600000;
      if (duration < 1 ) {
        return false;
      }
      var count = 0;
      _.each([grubbs, histogram_bins, first_hour_average, stddev_from_average, stddev_from_moving_average, mean_subtraction_cumulation, median_absolute_deviation, least_squares], function(f) {
        if (f(timeSeries)) {
          count += 1;
        };
      }); 
      if (count > 5) {
        return true;
      } else {
        return false;
      }
    };

    // ema from Gauss.js
    var ema = function(vector, period) {
      var ratio = 2 / (period + 1);
      var sum = ss.sum(vector.slice(0, period));
      var ema = [sum / period];
      for (var i = 1; i < vector.length - period + 1; i++) {
        ema.push(
          ratio * (vector[i + period - 1] - ema[i - 1]) + ema[i - 1]
        );
      }
      return ema;
    };

    // Perl5's Statistics::Distributions
    var SIGNIFICANT = 5;
    var _subu = function(p) {
      var y = 0 - Math.log(4 * p * (1 - p));
      var x = Math.sqrt(
        y * (1.570796288
        + y * (.03706987906
          + y * (-.8364353589E-3
          + y * (-.2250947176E-3
            + y * (.6841218299E-5
            + y * (0.5824238515E-5
              + y * (-.104527497E-5
              + y * (.8360937017E-7
                + y * (-.3231081277E-8
                + y * (.3657763036E-10
                  + y *.6936233982E-12)))))))))));
      if (p>0.5) {
        x = -x;
      };
      return x;
    };
    var _subt = function(n, p) {
      if (p >= 1 || p <= 0) {
        alert("Invalid p: "+p);
      }
      if (p == 0.5) {
        return 0;
      } else if (p < 0.5) {
        return 0 - _subt(n, 1 - p);
      }
 
      var u = _subu(p);
      var u2 = Math.pow(u, 2);
      var a = (u2 + 1) / 4;
      var b = ((5 * u2 + 16) * u2 + 3) / 96;
      var c = (((3 * u2 + 19) * u2 + 17) * u2 - 15) / 384;
      var d = ((((79 * u2 + 776) * u2 + 1482) * u2 - 1920) * u2 - 945) / 92160;
      var e = (((((27 * u2 + 339) * u2 + 930) * u2 - 1782) * u2 - 765) * u2 + 17955) / 368640;
      var x = u * (1 + (a + (b + (c + (d + e / n) / n) / n) / n) / n);
      if (n <= Math.pow((Math.log(p)/Math.log(10)), 2) + 3) {
        var round;
        do { 
          var p1 = _subtprob(n, x);
          var n1 = n + 1;
          var delta = (p1 - p) 
          / Math.exp((n1 * Math.log(n1 / (n + x * x)) 
          + Math.log(n/n1/2/Math.PI) - 1 
          + (1/n1 - 1/n) / 6) / 2);
          x += delta;
          round = str.sprintf("%."+Math.abs(parseInt((Math.log(Math.abs(x))/Math.log(10)) -4))+"f", delta);
        } while ((x) && (round != 0));
      }
      return x;
    };
    var _subtprob = function(n, x) {
      var a, b;
      var w = Math.atan2(x / Math.sqrt(n), 1);
      var z = Math.pow(Math.cos(w), 2);
      var y = 1;
 
      for (var i = n-2; i >= 2; i -= 2) {
        y = 1 + (i-1) / i * z * y;
      } 
 
      if (n % 2 == 0) {
        a = Math.sin(w)/2;
        b = 0.5;
      } else {
        a = (n == 1) ? 0 : Math.sin(w)*Math.cos(w)/Math.PI;
        b= 0.5 + w/Math.PI;
      }
      return _.max(0, 1 - b - a * y);
    };
    var precision = function(x) {
      return Math.abs(parseInt((Math.log(Math.abs(x))/Math.log(10)) - SIGNIFICANT));
    };
    var precision_string = function(x) {
      if (x) {
        return str.sprintf("%." + precision(x) + "f", x);
      } else {
        return "0";
      }
    };

    var tdistr = function(p, df) {
      if (df <= 0 || Math.abs(df) - Math.abs(parseInt(df)) != 0) {
        alert("Invalid df: "+df);
      }
      if (p <= 0 || p >= 1) {
        alert("Invalid p: "+p);
      }
      return precision_string(_subt(df, p));
    };

    //Etsy's Skyline
    var grubbs = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      var mean = ss.mean(vector);
      var stdDev = ss.standard_deviation(vector);
      var z_score = ss.z_score(vector, mean, stdDev);
      var len_series = _.size(vector);
      var threshold = tdistr( 0.05/(2*len_series), len_series-2 );
      var threshold_squared = threshold * threshold;
      var grubbs_score = ( ( len_series - 1 ) / Math.sqrt(len_series) ) * Math.sqrt( threshold_squared / ( len_series - 2 + threshold_squared ) );
      return z_score > grubbs_score;
    };

    var histogram_bins = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      var min = ss.min(vector);
      var max = ss.max(vector);
      var bins = parseInt((max - min) / 15);
      var hist = _.range(min, max, bins);
      var histogram = {};
      var last = _.last(vector);
      var lasthis;
      _.each(vector, function(i) {
        var his = _.first(_.first(hist, function(h) {
          return i > h;
        }));
        histogram[his]++;
        if( i === last ) {
          lasthis = histogram[his];
        };
      });
      return lasthis <= 20;
    };

    var first_hour_average = function(timeSeries) {
      var firstHour = parseInt(timeSeries[0][0]) + 3600000;
      var fvector = _.map(timeSeries, function(item) {
        if (item[0] < firstHour) {
          return item[1];
        };
      });
      return Math.abs(parseInt(_.last(timeSeries)[1]) - ss.mean(fvector))  > 3 * ss.standard_deviation(fvector);
    };

    var stddev_from_average = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      return Math.abs(parseInt(_.last(vector)) - ss.mean(vector))  > 3 * ss.standard_deviation(vector);
    };

    var stddev_from_moving_average = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      var mvector = ema(vector, 10);
      return Math.abs(parseInt(_.last(vector)) - _.last(mvector))  > 3 * mvector.stdev;
    };

    var mean_subtraction_cumulation = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      var mean = ss.mean(vector);
      vector = _.map(vector, function(i) { return i - mean });
      return Math.abs(_.last(vector))  > 3 * ss.standard_deviation(vector);
    };

    var median_absolute_deviation = function(timeSeries) {
      var vector = _.map(timeSeries, function(item) {return item[1]});
      var median = ss.median(vector);
      vector = _.map(vector, function(i) { return Math.abs(i - median) });
      return _.last(vector)  > 6 * ss.median(vector);
    };

    var least_squares = function(timeSeries) {
      var y = ss.linear_regression().data(timeSeries).line();
      var yvector = _.map(timeSeries, function(i) {
        return y(i[0]);
      });
      return Math.abs(_.last(yvector)) > 3 * ss.standard_deviation(yvector);
    };

    this.notify = function(title, msg) {
      if(!("Notification" in window)){
        console.log("not support notification");
      }
      else if (Notification.permission === 'granted') {
        var notification = new Notification(title, {
          body: msg,
          dir : 'rtl',
          lang: 'zh-guoyu',
        });
        notification.onshow = function() {
          setTimeout(notification.close, 1000);
        };
      }
      else if (Notification.permission !== 'denied') {
        Notification.requestPermission(function(permission){
          if (!('permission' in Notification)) {
            Notification.permission = permission;
          }
          if (permission === 'granted') {
            var notification = new Notification("Notify begin", {
              body: 'kibana histogram panel notification'
            });
          }
        });
      };
    };

  });

});




© 2015 - 2025 Weber Informatics LLC | Privacy Policy