Commit 85966b64 by Alan W Szlosek Jr

### more work on timeseries logic ... still in flux

parent fb140d57
 ... ... @@ -4,8 +4,8 @@ 3. Alert when the average is over 50 4. Populate the metric with random integers every 500ms */ var Timeseries = require('./lib/timeseries'); var log = require('./lib/log')('example-timeseries', true); var Harbinger = require('../index'); var log = require('../lib/log')('example-timeseries', true); var moment = require('moment'); var redis = require('redis'); ... ... @@ -16,7 +16,7 @@ function getRandomInteger(min, max) { var redisClient = redis.createClient(6379, 'localhost'); // Instantiate a timeseries dataset called "sample" that preserves 60 seconds worth of data var metric = new Timeseries(redisClient, 'sample', 60); var metric = new Harbinger.Timeseries(redisClient, 'sample', 60); var averageInterval; ... ... @@ -43,10 +43,10 @@ var averageInterval = setInterval( done(); return; } log('Dataset spans ' + secondsSpanned + ' seconds'); log('Dataset spans ' + secondsSpanned + ' seconds. Avg: ' + avg); if (secondsSpanned == 10 && avg > 50) { log('Average above 50', avg); if (secondsSpanned == 10 && avg > 51) { log('Average above 51', avg); done(); } } ... ... @@ -60,7 +60,7 @@ var averageInterval = setInterval( var countInterval = setInterval( function() { var rand = getRandomInteger(1, 100); metric.addCount(moment().unix(), rand); metric.count(moment().unix(), rand); }, 500 ); ... ...
 var stats = require('statistics'); var log = require('./log')('timeseries', false); /* ... ... @@ -27,23 +28,6 @@ module.exports = Timeseries; // Use a zset to sum values into time buckets Timeseries.prototype.addValue = function(secondsBucket, type, value) { var self = this; var key = this.key + ':' + type + ':' + secondsBucket; log('lpush', key, value); this.redisClient.lpush( key, value, function(err) { self.redisClient.expire(key, self.cutoff); } ); }; Timeseries.prototype.addCount = function(secondsBucket, value) { this.addValue(secondsBucket, 'count', value); }; /* Still unsure how to handle multiple types yet: counters, timers, etc ... ... @@ -51,9 +35,12 @@ But this method could be used by getAverage() to get the sum and number of items type: count, timer */ Timeseries.prototype.getValues = function(startSeconds, endSeconds, type, callback) { var self = this; var earliestSeconds = Number.MAX_SAFE_INTEGER; // earliestSeconds will be repeatedly updated with the min timestamp value we encounter from Redis. // Default it to endSeconds in case there is no data var earliestSeconds = endSeconds; //Number.MAX_SAFE_INTEGER; var keys = []; for (var i = startSeconds; i <= endSeconds; i++) { keys.push( i ); ... ... @@ -97,7 +84,9 @@ Timeseries.prototype.getValues = function(startSeconds, endSeconds, type, callba Timeseries.prototype.getSum = function(startSeconds, endSeconds, type, callback) { var self = this; var earliestSeconds = Number.MAX_SAFE_INTEGER; // earliestSeconds will be repeatedly updated with the min timestamp value we encounter from Redis. // Default it to endSeconds in case there is no data var earliestSeconds = endSeconds; var keys = []; for (var i = startSeconds; i <= endSeconds; i++) { keys.push( i ); ... ... @@ -156,4 +145,105 @@ Timeseries.prototype.getCountAverage = function(startSeconds, endSeconds, callba ); }; /* METRIC TYPES For all metric types, the key prefix includes the second the values are being added Count - Believe we can use incrBy Time - Believe we need to use a list for these, so we can accurately calculate avg and other stats */ // NEW METHODS Timeseries.prototype.count = function(secondsBucket, count, callback) { var self = this; var key = this.key + ':count:' + secondsBucket; log('incrBy', key, count); self.redisClient.incrby( key, count, function(err) { self.redisClient.expire(key, self.cutoff); callback(err); } ); }; Timeseries.prototype.time = function(secondsBucket, value) { var self = this; var key = this.key + ':time:' + secondsBucket; log('lpush', key, value); this.redisClient.lpush( key, value, function(err) { self.redisClient.expire(key, self.cutoff); } ); }; // Return an array of counts for each seconds bucket from start to end Timeseries.prototype.getCounts = function(startSeconds, endSeconds, callback) { var self = this; var keys = []; for (var i = startSeconds; i <= endSeconds; i++) { keys.push( i ); } var out = []; var next = function() { var key; if (keys.length == 0) { // Done // Calculate the average now callback(null, out); return; } seconds = keys.shift(); key = self.key + ':count:' + seconds; // Fetch from redis log('fetching: ', key); // TODO: should probably use mget instead self.redisClient.get(key, function(err, value) { if (err) { callback(err); return; } if (value) { out.push( parseInt(value) ); } else { out.push(0); } next(); }); }; // Should perhaps cache the output of this so frequent pulls for this exact interval don't have to recalculate next(); }; /* Use this to get sum, mean/average, standard deviation, etc */ Timeseries.prototype.getCountStatistics = function(startSeconds, endSeconds, callback) { this.getCounts(startSeconds, endSeconds, function(err, counts) { if (err) { callback(err); return; } callback(null, counts.reduce(stats) ); }); }; /* */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!