UNPKG

upbeat

Version:

Fast health and performance monitoring with process handling

157 lines (122 loc) 3.56 kB
var tempos = require('./tempos'); // handles overall uptitude export class MetaData { include $m.EventEmitter; private { var HISTORICAL_COUNT = 100; } function initialize(config, id) { this.up = false; this.times = []; this.start = new Date(); this.firstTime = true; this.id = id; this.rise = config.rise || 1; this.fall = config.fall || 1; this.downTime = 0; this.upTime = 0; this.totalResTime = 0; this.totalCount = 0; this.errorHistory = []; this.lastErrorMessage = null; this.lastResponseTime = null; this.passCount = 0; this.failCount = 0; this.runningCount = 0; } function setStatus(error, resTime) { var passed = ! error; // credit uptime var now = (new Date()).getTime(); if (this.firstTime) { this.up = passed; this.firstTime = false; } if (this.lastTime) { var delta = now - this.lastTime; if (this.up) { tempos.increment(this.id, 'uptime', delta); } else { tempos.increment(this.id, 'downtime', delta); } } this.lastTime = now; this.totalCount++; if (passed) { this.passCount++; } else { this.failCount++; } this.mark(passed, resTime); this.emit((passed ? 'pass' : 'fail'), error); this.lastCheck = passed; if (this.wasUp == passed) { this.runningCount++; } else { this.runningCount = 1; } if (passed && this.runningCount == this.rise) { this.up = passed; this.emit('up'); this.emit('change'); } else if (!passed && this.runningCount == this.fall) { this.up = passed; this.emit('down', error); this.emit('change'); this.errorHistory.push({ error: error, timestamp: now }); } this.wasUp = passed; } function uptime(period) { return tempos.get(period).getCount(this.id + ':uptime'); } function downtime(period) { return tempos.get(period).getCount(this.id + ':downtime'); } function getHistory(period) { var history = []; var keys = []; for (var i=1; i<arguments.length; i++) { keys.push(this.id + ':' + arguments[i]); } var tempo = tempos.get(period); var tempHistory = keys.map(function (key) { return tempo.getHistory(key) }); foreach (var row in tempHistory) { var length = row.length; foreach (var bucket:j in row) { history[j] = history[j] || []; history[j].push(row[length - j - 1]); } } return history; } function plotResponseTimes(period) { return this.getHistory(period, 'passed-count', 'passed-resp').map(#(row) { return row[0] && row[1] ? Math.round(row[1] / row[0]) : null; }); } function averageResponseTime() { var totalResp = tempos.day.getCount(this.id + ':passed-resp'); var totalCount = tempos.day.getCount(this.id + ':passed-count'); if (this.totalCount == 0) return null; return Math.round(totalResp / totalCount); } function total(attr, period) { return tempos.get(period).getCount(this.id + ":" + attr); } function mark(passed, time) { var pre = passed ? 'passed' : 'failed'; tempos.increment(this.id, pre + '-resp', time); tempos.increment(this.id, pre + '-count', 1); tempos.increment(this.id, pre, 1); this.totalResTime += time; this.lastResponseTime = time; this.times.push([ passed, time ]); if (this.times.length > HISTORICAL_COUNT) this.times.shift(); } }