Skip to content

Commit

Permalink
getting sensor charts to work
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffsu committed Aug 31, 2012
1 parent 00c0c17 commit 1856996
Show file tree
Hide file tree
Showing 29 changed files with 12,919 additions and 1,170 deletions.
44 changes: 15 additions & 29 deletions lib/sensor.ms
@@ -1,5 +1,6 @@
var strategies = require('./strategies');
var tempo = require('tempo');
var Stats = require('./stats');

export class Sensor {
include $m.EventEmitter;
Expand Down Expand Up @@ -34,10 +35,7 @@ export class Sensor {

this.stacked = 0; // number of stacked up requests

this.min = tempo.min();
this.hour = tempo.hour();
this.day = tempo.day();
this.week = tempo.week();
this.stats = new Stats({ strategy: 'sensor' });

this.status = 'paused';
this.isHealthy = null;
Expand All @@ -47,41 +45,29 @@ export class Sensor {
this.setEvents();
}

function sync(redis, name, cb) {
this.stats.sync(redis, name, cb);
}

function getTempo(time) {
return this[time || 'day'];
return this.stats.getTempo(time);
}

function getAverageTimes(time) {
var tempo = this.getTempo(time);
return {
fail: tempo.getAverageHistory('fail-time', 'fail-count'),
pass: tempo.getAverageHistory('pass-time', 'pass-count')
};
function getData(time) {
return this.stats.getData(time);
}

function setEvents() {
this.on('fail', #(time) {
self.min.inc("fail-count");
self.hour.inc("fail-count");
self.day.inc("fail-count");
self.week.inc("fail-count");

self.min.inc("fail-time", time);
self.hour.inc("fail-time", time);
self.day.inc("fail-time", time);
self.week.inc("fail-time", time);
self.stats.inc("fail");
self.stats.inc("total");
self.stats.inc("time", time);
});

this.on('pass', #(time) {
self.min.inc("pass-count");
self.hour.inc("pass-count");
self.day.inc("pass-count");
self.week.inc("pass-count");

self.min.inc("pass-time", time);
self.hour.inc("pass-time", time);
self.day.inc("pass-time", time);
self.week.inc("pass-time", time);
self.stats.inc("pass");
self.stats.inc("total");
self.stats.inc("time", time);
});
}

Expand Down
35 changes: 31 additions & 4 deletions lib/server.ms
Expand Up @@ -25,6 +25,19 @@ export class Server {
return services;
}

function sync(redis) {
for (var serviceName in this.services) {
var service = this.services[serviceName];
for (var sensorName in service.sensors) {
var sensor = service.sensors[sensorName];
sensor.sync(redis, "upbeat:services:" + serviceName + ":" + sensorName);
}
}

for (var k in this.stats)
this.stats[k].sync(redis, k);
}

function run() {
if (this.status == 'running') return;
this.status = 'running';
Expand All @@ -51,20 +64,34 @@ export class Server {

if (config.redis)
this.buildRedis(config.redis);

if (this.redis || config.save)
this.setSave();
}

function setSave() {
setInterval(#{ self.save() }, 3000);
}

function save() {
for (var k in this.services) {
var service = this.services[k];
for (var name in service.sensors) {
var sensor = service.sensors[name];
}
}
}

function buildRedis(config) {
if (!config) return;
var redis = require('redis').createClient(config);
var stop = true;
redis.on('error', #{ stop = true; console.log('hi') });
redis.on('error', #{ stop = true; });
redis.on('connect', #{ stop = false; });

setInterval(#{
if (stop) return;
for (var k in self.stats) {
self.stats[k].sync(redis, k);
}
self.sync(redis);
}, config.interval || 3000);
}

Expand Down
24 changes: 19 additions & 5 deletions lib/stats.ms
Expand Up @@ -2,19 +2,23 @@ var tempo = require('tempo');

// TODO expand this out into other classes
export class Stats {
private {
var HOUR = 1000 * 60 * 60;
}

function initialize(config) {
this.config = config;
this.config = config || {};

this.min = tempo.min();
this.day = tempo.day();
this.hour = tempo.hour();
this.week = tempo.week();
this.day = tempo.day();
this.week = new tempo.TimedCounter({ per: HOUR * 4, buckets: 7 * 6 });
}

function inc(name, n) {
this.min.inc(name, n);
this.day.inc(name, n);
this.hour.inc(name, n);
this.day.inc(name, n);
this.week.inc(name, n);
}

Expand All @@ -26,8 +30,8 @@ export class Stats {
}

this.min.sync(redis, name + ':min', onFin);
this.day.sync(redis, name + ':day', onFin);
this.hour.sync(redis, name + ':hour', onFin);
this.day.sync(redis, name + ':day', onFin);
this.week.sync(redis, name + ':week', onFin);
}

Expand All @@ -38,9 +42,19 @@ export class Stats {
return this.counter(tempo);
} else if (this.config.strategy == 'average') {
return this.average(tempo);
} else if (this.config.strategy == 'sensor') {
return this.sensor(tempo);
}
}

function sensor(tempo) {
return {
response: tempo.getAverageHistory('time', 'total'),
pass: tempo.getHistory('pass'),
fail: tempo.getHistory('fail')
};
}

function average(tempo) {
return { average: tempo.getAverageHistory('sum', 'count') };
}
Expand Down
18 changes: 9 additions & 9 deletions mock/example.yml
@@ -1,22 +1,22 @@
services:
web-site:
slow-call:
slow:
good:
strategy: http
url: http://localhost:3001/slow/good
url: http://localhost:3001/fast/good
timeout: 300
interval: 5000
average-call:
average:
strategy: http
url: http://localhost:3001/fast/average
timeout: 100
timeout: 300
interval: 5000
average-call:
perfect:
strategy: http
url: http://localhost:3001/fast/average
timeout: 100
url: http://localhost:3001/fast/perfect
timeout: 300
interval: 5000

web-site2:
fast:
http:
strategy: http
url: http://localhost:3001/fast/bad
Expand Down
3 changes: 0 additions & 3 deletions mock/setup.js
Expand Up @@ -7,6 +7,3 @@ var upbeat = cp.fork(__dirname + '/upbeat-server.js');

console.log('forking test server');
var myServer = cp.fork(__dirname + '/my-server.js');

console.log('starting redis');
cp.exec('redis-server');
84 changes: 66 additions & 18 deletions www/app.ms
Expand Up @@ -3,6 +3,33 @@
* Module dependencies.
*/

var LABELS = {
min: [],
hour: [],
day: [],
week: []
};

var SUFFIXES = {
min: 'seconds ago',
hour: 'minutes ago',
day: 'hours ago',
week: 'days ago'
};

for (var i=0; i<12; i++) {
LABELS.min.push(i * 5);
LABELS.hour.push(i * 5);
}

for (var i=0; i<24; i++) LABELS.day.push(i);
for (var i=0; i<7; i++) {
for (var j=0; j<6; j++) {
if (i>0 && j==0) LABELS.week.push(i);
else LABELS.week.push('');
}
}

module.exports = #(server, config) {

var express = require('express')
Expand Down Expand Up @@ -31,7 +58,7 @@ module.exports = #(server, config) {
'<span style="color: red">' + (down || 'down') + '</span>';
};

app.locals.TIMES = [ 'min', 'hour', 'day', 'week' ];
app.locals.suffixes = SUFFIXES;

app.configure(function(){
app.set('port', process.env.PORT || 3000);
Expand All @@ -41,6 +68,20 @@ module.exports = #(server, config) {
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());

app.use(#(req, res, next) {
var locals = res.locals;
req.query.time = req.query.time || 'min';
if (!locals) return next();
locals.server = server;
locals.services = server.services;
locals.stats = server.stats;
locals.params = req.params;
locals.self = getResource(req);
locals.path = req.path;
next();
});

app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
Expand All @@ -51,35 +92,42 @@ module.exports = #(server, config) {
});

app.get('/', #(req, res, next) {
res.render('index', { params: req.params, server: server });
res.render('index', {});
});

app.get('/stats/:stats/:time.:format?', #(req, res, next) {
var stats = getResource(req.params);
app.get('/services/:service', #(req, res, next) {
var params = req.params;
var query = req.query;
res.render('service', { params: req.params, service: getResource(req.params), query: query });
});

app.get('/services', #(req, res, next) {
res.render('services');
});


app.get('/stats', #(req, res, next) {
res.render('stats');
});

app.get('/stats/:stats.:format?', #(req, res, next) {
var time = req.query.time;
var stats = getResource(req.params);
var strategy = stats.config.strategy;

if (req.params.format == 'json') {
res.json(stats.getData(req.params.time));
} else {
res.render('stats/' + strategy, { config: config, stats: stats, params: req.params });
}
});

app.get('/services', #(req, res, next) {
res.render('services', { params: req.params, services: server.services });
});

app.get('/services/:service/:time.:format?', #(req, res, next) {
app.get('/services/:service/sensors/:sensor.:format?', #(req, res, next) {
var query = req.query;
if (req.params.format == 'json')
res.json(getResource(req.params).getAverageTimes(params.time));
else
res.render('service', { params: req.params, server: server, service: getResource(req.params) });
});

app.get('/services/:service/sensors/:sensor/:time.:format?', #(req, res, next) {
if (req.params.format == 'json')
res.json(getResource(req.params).getAverageTimes(req.params.time));
res.json({ data: getResource(req.params).getData(query.time), labels: LABELS[query.time] });
else
res.render('sensor', { params: req.params, sensor: getResource(req.params) });
res.render('sensor', { params: req.params, sensor: getResource(req.params), query: query });
});

app.get('/services/:service/sensors/:sensor/health', #(req, res, next) {
Expand Down

0 comments on commit 1856996

Please sign in to comment.