Skip to content

Instantly share code, notes, and snippets.

@srl295
Created May 20, 2015 01:20
Show Gist options
  • Save srl295/fecf56cb26cbfb2a6c9b to your computer and use it in GitHub Desktop.
Save srl295/fecf56cb26cbfb2a6c9b to your computer and use it in GitHub Desktop.
DIff of changes in the cldr-stwatcher. To be merged.
diff --git a/.cfignore b/.cfignore
index 1273728..066ae58 100644
--- a/.cfignore
+++ b/.cfignore
@@ -1,12 +1,7 @@
-launchConfigurations/
-.git/
-node_modules/
-.cfignore
-.gitignore
+config/runtime.json
+node_modules
.svn
-*~
-*.txt
-*.log
-local-creds.sh
-public/bower_components/
-npm-debug.log
\ No newline at end of file
+.git
+config/akka.json
+config/milu.json
+config/gdx.json
diff --git a/.gitignore b/.gitignore
index abeeff6..e39faf9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,8 +4,10 @@
node_modules
cldr-stwatcher.esproj/user*
config/akka.json
-npmdebug.log
+npm-debug.log
config/milu.json
config/runtime.json
+config/runtime.json.tmp*
config/gdx.json
+config/local.json
**/*~
diff --git a/License.txt b/License.txt
new file mode 100644
index 0000000..ead1daf
--- /dev/null
+++ b/License.txt
@@ -0,0 +1 @@
+<Replace this text with the license you've chosen for your project.>
diff --git a/Readme.md b/Readme.md
index 090aeb6..6e94707 100644
--- a/Readme.md
+++ b/Readme.md
@@ -2,11 +2,8 @@ A watcher for CLDR SurveyTool.
Quite under documented.
-copy config/SOMEHOST.json to config/localhost.json where localhost is your hostname.
+copy config/SOMEHOST.json to config/localhost.json where localhost is your hos
If node is installed, 'make' should fire up the server.
http://127.0.0.1:3000 should show you the watcher.
-
-
-
diff --git a/app.js b/app.js
index 4605e54..9534865 100644
--- a/app.js
+++ b/app.js
@@ -1,29 +1,32 @@
+
/**
* Module dependencies.
*/
-
-var appEnv = require('cfenv').getAppEnv();
-
var express = require('express')
, routes = require('./routes')
, stwatcher = require('./routes/stwatcher')
, http = require('http')
, path = require('path')
-favicon = require('serve-favicon'),
-serveStatic = require('serve-static'),
-morgan = require('morgan'),
-bodyParser = require('body-parser');
+, CONFIG = require('config').SurveyWatcher,
+ favicon = require('serve-favicon'),
+ serveStatic = require('serve-static'),
+ morgan = require('morgan'),
+ bodyParser = require('body-parser');
+
+var host = (process.env.VCAP_APP_HOST || undefined);
+var port = process.env.VCAP_APP_PORT || CONFIG.port || process.env.PORT || 3000;
+console.log("hostport: " + host+":"+port);
var app = express();
// all environments
-app.set('port', appEnv.port);
+app.set('port', port);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.enable('trust proxy');
app.use(favicon(__dirname + '/public/favicon.ico'));
-app.use(morgan({ format: 'dev', immediate: true }));
+app.use(morgan({format: 'dev', immediate: true}));
app.use(bodyParser());
app.use(require('method-override')());
@@ -36,9 +39,9 @@ app.use(serveStatic(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
- app.use(require('errorhandler')());
+ app.use(require('errorhandler')());
}
var port = app.get('port');
console.log('Express server listening on port ' + port);
-app.listen(appEnv.port, appEnv.bind);
+app.listen(app.get('port'));
diff --git a/cldr-stwatcher.esproj/Project.espressostorage b/cldr-stwatcher.esproj/Project.espressostorage
new file mode 100644
index 0000000..892ee38
Binary files /dev/null and b/cldr-stwatcher.esproj/Project.espressostorage differ
diff --git a/config/default.json b/config/default.json
index 84ad2e7..929bc9e 100644
--- a/config/default.json
+++ b/config/default.json
@@ -7,8 +7,10 @@
"title": "SurveyWatcher"
},
"watcher": {
- "polltime": 10
+ "polltime": 500
},
- "port": 3000
+ "port": 3000,
+ "notify": {
+ }
}
}
diff --git a/loopy.sh b/loopy.sh
new file mode 100644
index 0000000..f2a4be2
--- /dev/null
+++ b/loopy.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+while [[ 1 == 1 ]];
+do
+ make
+ sleep 30
+done
+
diff --git a/manifest.yml b/manifest.yml
index dda6c7c..0c7e4ac 100644
--- a/manifest.yml
+++ b/manifest.yml
@@ -1,16 +1,12 @@
----
applications:
-- name: stwatcher
- services:
- - Cloudant NoSQL DB-gx
- - IBM Globalization-zl
- - Monitoring and Analytics-u0
- - SurveyTool-prod
- - SurveyTool-smoke
- disk_quota: 1024M
- host: stwatcher
+- services:
+ - mysql
+ - twilio
+ - SendGrid
+ - sso-ibm
+ disk: 1024M
name: stwatcher
+ command: node app.js
path: .
- domain: mybluemix.net
+ mem: 256M
instances: 1
- memory: 256M
diff --git a/package.json b/package.json
index 5582c70..2a68cb1 100644
--- a/package.json
+++ b/package.json
@@ -6,20 +6,20 @@
"start": "node app.js"
},
"dependencies": {
- "body-parser": "^1.12.3",
- "cfenv": "^1.0.0",
- "cloudant": "^1.0.0-beta3",
- "errorhandler": "^1.3.5",
- "express": "^4.2.0",
- "gaas": "^1.0.1",
- "jade": "^1.9.2",
- "method-override": "^2.3.2",
- "morgan": "^1.5.2",
- "nodemailer": "^1.3.4",
- "ping": "^0.1.9",
- "request": "^2.34.0",
- "serve-favicon": "^2.2.0",
- "serve-static": "^1.9.2",
- "twilio": "^2.2.0"
+ "body-parser":"*",
+ "config": "0.4.x",
+ "express": "4.2.x",
+ "jade": "*",
+ "method-override":"*",
+ "morgan":"*",
+ "mysql": "2.2.xx",
+ "orm": "2.1.x",
+ "ping": "*",
+ "request": "2.34.x",
+ "sendgrid":"1.0.3",
+ "serve-favicon": "*",
+ "serve-static":"*",
+ "twilio": ">=1.6.0",
+ "errorhandler":"*"
}
}
diff --git a/public/javascripts/stwatcher-client.js b/public/javascripts/stwatcher-client.js
index aec3870..4ffe195 100644
--- a/public/javascripts/stwatcher-client.js
+++ b/public/javascripts/stwatcher-client.js
@@ -23,361 +23,493 @@ function stwatcher_interval(_config) {
console.log("Interval = " + n + " sec");
// interval for next time
-require(["dojo/query", "dojo/request", "dojo/dom", "dojo/dom-construct", "dojo/main", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines", "dojox/charting/action2d/MouseIndicator", "dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/action2d/TouchZoomAndPan", "dojox/charting/plot2d/Indicator", "dojo/domReady!"],
- function stwatcherclient(query,request,dom, dcons, main, Chart, Default, Lines, MouseIndicator, MouseZoomAndPan, TouchZoomAndPan, Indicator) {
-
-
- var powered = dom.byId('powered');
- powered.appendChild(document.createTextNode(" and dōjō " + main.version));
+ require(["dojo/query", "dojo/request", "dojo/dom", "dojo/dom-construct", "dojo/main", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines", "dojox/charting/action2d/MouseIndicator", "dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/action2d/TouchZoomAndPan", "dojox/charting/plot2d/Indicator",
+ "dojox/charting/action2d/Tooltip", "dojo/domReady!"],
+ function stwatcherclient(query,request,dom, dcons, main, Chart, Default, Lines, MouseIndicator, MouseZoomAndPan, TouchZoomAndPan, Indicator,
+ Tooltip) {
+
- function fmtNs(val) {
- if(val > 1e9) {
- val = val / 1e9;
- return val.toFixed(3) + "s";
- } else if(val > 1e6) {
- val = val / 1e6;
- return val.toFixed(3) + "ms";
- } else if(val > 1e3) {
- val = val / 1e3;
- return val.toFixed(3) + "µs";
- } else {
- return val + "ns";
- }
- }
- function setText(node, text) {
- var node2 = query(node);
- if(node2==null) return node;
- node2 = node2[0]; // it's a list
-
- var textNode = document.createTextNode(text);
- while(node2.firstChild != null) {
- node2.removeChild(node2.firstChild);
- }
- node2.appendChild(textNode);
- }
+ var powered = dom.byId('powered');
+ powered.appendChild(document.createTextNode(" and dōjō " + main.version));
- setText("#status", "Loading..");
-
- var div = query('#SurveyWatcher');
-
- div.empty();
- var chart1=null;
-
-
- function show_history(server, obj, hostInfo) {
- setText('#chartTitle', "History: " + server + "@" + obj.host);
- var hdiv = query("#SurveyChart");
- if(chart1===null) {
- hdiv.empty();
- }
- setText('#chartstatus', 'Please Wait: Fetching chart info');
- request
- .get('history.json?server='+server, {handleAs: 'json'})
- .then(function(json) {
- window._HISTORY = json; // DEBUGGING
- if(json.err) {
- setText('#chartstatus', 'Err: ' + json.err);
- } else {
- setText('#chartstatus', 'Chart loaded: ' + json.data.length + ' rows');
- var isNew = (chart1 === null);
-
- if(!isNew) {
- chart1.destroy();
+ function fmtNs(val) {
+ if(val > 1e9) {
+ val = val / 1e9;
+ return val.toFixed(3) + "s";
+ } else if(val > 1e6) {
+ val = val / 1e6;
+ return val.toFixed(3) + "ms";
+ } else if(val > 1e3) {
+ val = val / 1e3;
+ return val.toFixed(3) + "µs";
+ } else {
+ return val + "ns";
}
+ }
+
+ function setText(node, text) {
+ var node2 = query(node);
+ if(node2==null) return node;
+ node2 = node2[0]; // it's a list
- var data = [];
- var data2 = [];
- var outages = [];
-
- for(var k in json.data ) {
- var row = json.data[k];
- var when = new Date(row.when).getTime();
- var usersn = -3.0;
- if(row.users) {
- usersn = parseInt(row.users);
- data.push({x:when, y:usersn});
- } else {
- usersn = 0;
- data.push({x:when, y:-3.0});
- }
- var loadn = -1.0;
-
- if(row.isBusted || row.busted) {
- loadn = -3.0;
- outages.push(when);
- data2.push({x:when, y:loadn});
- } else if(row.load === null) {
- loadn = -3.0;
- outages.push(when);
- data2.push({x:when, y:loadn});
- } else {
- loadn = parseFloat(row.load.split(' ')[0]);
- data2.push({x:when, y:loadn});
- }
-
+ var textNode = document.createTextNode(text);
+ while(node2.firstChild != null) {
+ node2.removeChild(node2.firstChild);
}
-
- chart1 = new Chart("SurveyChart");
- chart1.addPlot("default", {type: Lines});
- chart1.addAxis("x", {minorLabels: false, labelFunc: function(xx){
- return new Date(parseInt(xx)).toLocaleString();
- }});
- chart1.addAxis("y", {vertical: true, min: -0});
- chart1.addSeries("Series 1", data);
- chart1.addSeries("Series V", data2, {plot: "default", stroke: {color: "blue"}});
- chart1.addPlot("threshold", { type: Indicator,
- lineStroke: { color: "red", style: "ShortDash"},
- labels: "none",
- labelFunc: function(xx) {return "Ⓧ" /*new Date(outages[xx]).format("HH:MM");*/},
- values: outages});
+ node2.appendChild(textNode);
+ }
-
-// new MouseIndicator(chart1, "default", { series: "Series 1",
-// font: "normal normal bold 12pt Tahoma",
-// fillFunc: function(v){
-// return v.y>55?"green":"red";
-// },
-// autoScroll: true,
-// labelFunc: function(v){
-// return v;
-// }});
- new MouseZoomAndPan(chart1, "default", { axis: "x" });
- //new TouchZoomAndPan(chart1, "default", { axis: "x" });
- chart1.render();
-
-
- /*{
- "busted": null,
- "dbused": 1659,
- "guests": 0,
- "id": 6141,
- "info": "Data Submission 24 LOCAL",
- "isBusted": false,
- "isSetup": true,
- "load": "0.71 cpu=8",
- "mem": "560.23725/1079.296",
- "ns": 333093000,
- "pages": null,
- "probation": false,
- "server": "naf",
- "stamp": "2013-05-25T04:46:48.000Z",
- "statusCode": 200,
- "uptime": "uptime: 1:22:59",
- "users": 0,
- "when": "2013-05-25T06:09:48.000Z"
- },
- */
-
- }
- })
- .otherwise(function(err) {
- setText("#chartstatus", "Error Loading! " + err);
- });
-
- }
-
- function consumeType(obj, newlist, now, json) {
- var keys = Object.keys(newlist);
- for(var k in keys) {
- var e = keys[k];
- if(stw_config.reloadOnly && e != stw_config.reloadOnly) continue;
- var newEntry = newlist[e];
- var oldEntry = null;
- var odiv = obj.div;
- if(!obj.list[e]) {
- // new
- oldEntry = {
- subDiv: dcons.create("li",{innerHTML: "<h4>"+e+"</h4>"}),
- };
- odiv.appendChild(oldEntry.subDiv);
- obj.list[e] = oldEntry;
- } else {
- oldEntry = obj.list[e];
- }
-
- obj.update(obj, e, newEntry, now, json);
- }
- };
-
- var servers = {
- list: {},
- div: dcons.create("div",{id: "servers", class: "group", innerHTML: "<h3>Servers</h3>" }),
- update: function(obj, e, newEntry, now, json) {
- var oldEntry = obj.list[e];
- var txtstatus = "unknown";
-
- if(newEntry.lastKnownStatus) {
- txtstatus = (newEntry.lastKnownStatus.up ? "up" : "down");
- }
- oldEntry.subDiv.className = txtstatus;
- if(stw_config.reloadOnly) {
- oldEntry.subDiv.getElementsByTagName('h4')[0].innerHTML = txtstatus;
- }
+ var updateCpu = function updateCpu(txt, load, ncpus) {
+ var cpus;
+ if(txt.cpus) {
+ cpus = txt.cpus;
+ } else {
+ cpus = [];
+ var cpuDiv = document.createElement("div");
+ cpuDiv.className="cpus";
+ txt.appendChild(cpuDiv);
+ txt.cpuDiv = cpuDiv;
+ txt.cpus = cpus;
+ txt.cpuMsg = document.createElement("span");
+ txt.cpuMsg.className = "cpuMsg";
+ for(var i=0;i<2;i++)
+ {
+ var cpu = document.createElement("div");
+ cpuDiv.appendChild(cpu);
+ cpus.push(cpu);
+ }
+ cpus[0].className = "cpu0";
+ cpus[1].className = "cpu1";
+ cpuDiv.appendChild(txt.cpuMsg);
+ }
+ var totalLoadPct = (load*100.0)/ncpus;
+ var loadPct1 = Number(totalLoadPct).toFixed(1);
+ var loadPct0 = Number(totalLoadPct).toFixed(0);
+ cpus[0].style.width = (loadPct0+"px");
+ cpus[1].style.width = ((100-loadPct0)+"px");
+ setText(txt.cpuMsg, " Total Load:" + loadPct1+"%" + ", " + ncpus + " cpus");
+ };
- var links = oldEntry.links;
- if(!links) {
- links = dcons.create("ul",{class: "links"});
- oldEntry.links = links;
+ setText("#status", "Loading..");
- obj.host = newEntry.host;
- obj.hostEnt = json.hosts[obj.host];
- if(stw_config.reloadOnly) {
- var urlLink = dcons.create("button",{innerHTML: "Try Now"});
- urlLink.onclick = function() {
- window.location.reload(true);
- };
- links.appendChild(urlLink);
- } else {
-
- {
- var urlLink = dcons.create("a",{href: obj.hostEnt.servers[e].url, innerHTML: "go"});
- var urlLi = dcons.create("li");
- urlLi.appendChild(urlLink);
- links.appendChild(urlLi);
+ var div = query('#SurveyWatcher');
+
+ div.empty();
+ var chart1=null;
+
+
+ function show_history(server, obj, hostInfo) {
+ setText('#chartTitle', "History: " + server + "@" + obj.host);
+ var hdiv = query("#SurveyChart");
+ if(chart1===null) {
+ hdiv.empty();
}
- {
- var urlLink = dcons.create("button",{innerHTML: "history"});
- var urlLi = dcons.create("li");
- urlLi.appendChild(urlLink);
- links.appendChild(urlLi);
-
- urlLink.onclick = function() {
- show_history(e, obj, json.hosts[obj.host]);
- return false;
- };
+ setText('#chartstatus', 'Please Wait: Fetching chart info');
+ request
+ .get('history.json?server='+server, {handleAs: 'json'})
+ .then(function(json) {
+ window._HISTORY = json; // DEBUGGING
+ if(json.err) {
+ setText('#chartstatus', 'Err: ' + json.err);
+ } else {
+ setText('#chartstatus', 'Chart loaded: ' + json.data.length + ' data points');
+ var isNew = (chart1 === null);
+
+ if(!isNew) {
+ chart1.destroy();
+ }
+
+ var data = [];
+ var data2 = [];
+ var outages = [];
+ var innages = [];
+ var revages = [];
+ var revs = [];
+ var wasup = null;
+ var lastUpWhen = null; // the previous 'up' row
+ var lastrev = null;
+
+
+ function reportRunning(when, isup, info) {
+ if(
+ (wasup == null) // start of time
+ || (wasup != isup) // change
+ ) {
+ (isup?innages:outages).push(when); // record change
+ wasup = isup;
+
+ if(isup && (info != null) && info.length>0) {
+ var spinfo = info.split(';');
+ if(spinfo && spinfo.length>1) {
+ if(lastrev!=null) {
+ if(lastUpWhen != null && lastrev != spinfo[0]) {
+ // rev change - at lastupWhen
+ innages.pop(); // superceded
+ revages.push(lastUpWhen);
+ revs.push(lastrev);
+ console.log("Rev change " + lastUpWhen + "/" + lastrev);
+ }
+ }
+
+ // have to push this here, or it could get out of sync.
+ lastrev = spinfo[0];
+ lastUpWhen = when;
+ // console.log(".." + lastUpWhen + "/ " + lastrev);
+ } else {
+ // no data after this, but at least mark the version change
+ if(lastUpWhen != null && lastrev != null) {
+ innages.pop(); // superceded
+ revages.push(lastUpWhen);
+ revs.push(lastrev);
+ console.log("Rev change (past=NULL) " + lastUpWhen + "/" + lastrev);
+ }
+ }
+ }
+ } else {
+ // no change
+ }
+ }
+
+ chart1 = new Chart("SurveyChart");
+ chart1.addPlot("default", {type: Lines});
+ chart1.addAxis("x", {minorLabels: false, labelFunc: function(xx){
+ return new Date(parseInt(xx)).toLocaleString();
+ }});
+ chart1.addAxis("y", {vertical: true, min: -0});
+
+ var dataCount = 0;
+ var data2Count = 0;
+ var dataOpts = {};
+ var data2Opts = {plot: "default", stroke: {color: "blue"}};
+ /**
+ * write 'data', start a new chart.
+ */
+ function flushData() {
+ if(data.length>0) {
+ chart1.addSeries("Series 1."+(dataCount++), data, dataOpts);
+ }
+ data = [];
+ }
+ function flushData2() {
+ if(data2.length>0) {
+ chart1.addSeries("Series 2."+(data2Count++), data2, data2Opts);
+ }
+ data2 = [];
+ }
+
+ var lastWhen = null; // the previous row
+ // this data is in REVERSE ORDER
+ for(var k in json.data ) {
+ var row = json.data[k];
+ var when = new Date(row.when).getTime();
+
+ if(lastWhen != null) {
+ // console.log("Gap: " + (lastWhen-when) + " at " + row.when);
+ if((lastWhen-when) > (1000*60*15)) { // over 15 minute gap?
+ // break the chart.
+ flushData();
+ flushData2();
+ }
+ }
+
+ var usersn = -3.0;
+ if(row.users) {
+ usersn = parseInt(row.users);
+ data.push({x:when, y:usersn});
+ } else {
+ // break the users chart.
+ flushData();
+ // usersn = -1.0;
+ // data.push({x:when, y:-3.0});
+ }
+ var loadn = -1.0;
+ if( (row.isBusted || row.busted) || (row.load === null)) {
+ reportRunning(when, false, row.info);
+ // break the load chart.
+ flushData2();
+ // loadn = -3.0; // fake value to get it under the line
+ // data2.push({x:when, y:loadn});
+ } else {
+ reportRunning(when, true, row.info);
+ loadn = parseFloat(row.load.split(' ')[0]);
+ data2.push({x:when, y:loadn});
+ }
+ lastWhen = when;
+ }
+
+ // get any trailing data
+ flushData();
+ flushData2();
+
+ chart1.addPlot("threshold1", { type: Indicator,
+ lineStroke: { color: "red", style: "ShortDash"},
+ labels: "none",
+ labelFunc: function(xx) {return "⬇" /*new Date(outages[xx]).format("HH:MM");*/},
+ values: outages});
+ chart1.addPlot("threshold2", { type: Indicator,
+ lineStroke: { color: "green", style: "ShortDash"},
+ labels: "none",
+ labelFunc: function(xx) {return "⬆" /*new Date(outages[xx]).format("HH:MM");*/},
+ values: innages});
+ chart1.addPlot("threshold3", { type: Indicator,
+ lineStroke: { color: "green", style: "ShortDash"},
+ labels: "none",
+ labelFunc: function(xx) {return "⬆r"+revs[xx] /*new Date(outages[xx]).format("HH:MM");*/},
+ values: revages});
+
+
+ // new MouseIndicator(chart1, "default", { series: "Series 1",
+ // font: "normal normal bold 12pt Tahoma",
+ // fillFunc: function(v){
+ // return v.y>55?"green":"red";
+ // },
+ // autoScroll: true,
+ // labelFunc: function(v){
+ // return v;
+ // }});
+ new MouseZoomAndPan(chart1, "default", { axis: "x" });
+ new Tooltip(chart1, "default");
+ //new TouchZoomAndPan(chart1, "default", { axis: "x" });
+ chart1.render();
+
+
+ /*{
+ "busted": null,
+ "dbused": 1659,
+ "guests": 0,
+ "id": 6141,
+ "info": "Data Submission 24 LOCAL",
+ "isBusted": false,
+ "isSetup": true,
+ "load": "0.71 cpu=8",
+ "mem": "560.23725/1079.296",
+ "ns": 333093000,
+ "pages": null,
+ "probation": false,
+ "server": "naf",
+ "stamp": "2013-05-25T04:46:48.000Z",
+ "statusCode": 200,
+ "uptime": "uptime: 1:22:59",
+ "users": 0,
+ "when": "2013-05-25T06:09:48.000Z"
+ },
+ */
+
+ }
+ })
+ .otherwise(function(err) {
+ setText("#chartstatus", "Error Loading! " + err);
+ });
+
+ }
+
+ function consumeType(obj, newlist, now, json) {
+ var keys = Object.keys(newlist);
+ for(var k in keys) {
+ var e = keys[k];
+ if(stw_config.reloadOnly && e != stw_config.reloadOnly) continue;
+ (function(e){
+ var newEntry = newlist[e];
+ var oldEntry = null;
+ var odiv = obj.div;
+ if(!obj.list[e]) {
+ // new
+ oldEntry = {
+ subDiv: dcons.create("li",{innerHTML: "<h4>"+e+"</h4>"}),
+ };
+ odiv.appendChild(oldEntry.subDiv);
+ obj.list[e] = oldEntry;
+ } else {
+ oldEntry = obj.list[e];
+ }
+ obj.update(obj, e, newEntry, now, json);
+ })(e);
}
- }
+ };
- oldEntry.subDiv.appendChild(links);
- }
-
- var txt = oldEntry.txt;
- if(!txt) {
- txt = dcons.create("i",{class: "info"});
- oldEntry.txt = txt;
- oldEntry.subDiv.appendChild(txt);
- }
-
- if(newEntry.latestStatus && newEntry.latestStatus.update) {
- var u = newEntry.latestStatus.update;
- var j = newEntry.latestStatus.json;
- var statusTxt = "";
- if(u.users != null) {
- statusTxt = statusTxt + u.users+"u/";
- }
- if(u.guests != null) {
- statusTxt = statusTxt + u.guests+"g/";
- }
- if(u.load != null) {
- statusTxt = statusTxt + "l="+u.load +"/";
- }
- if(u.isSetup == false) {
- statusTxt = statusTxt + "(not running)/";
- }
- if(j) {
- if(j.status) {
- if(j.status.currev !== null) {
- statusTxt = statusTxt + "r"+j.status.currev+"/";
+
+ var hosts = {
+ list: {},
+ div: dcons.create("div",{id: "hosts", class: "group", innerHTML: "<h3>Servers</h3>" }),
+ update: function(obj, e, newEntry, now, json) {
+ var oldEntry = obj.list[e];
+ if(newEntry.stealth) {
+ oldEntry.subDiv.className = "stealth";
+ } else if(newEntry.latestPing) {
+ oldEntry.subDiv.className = (newEntry.latestPing.alive ? "up" : "down");
+ } else {
+ oldEntry.subDiv.className = "unknown";
+ }
+
+ var txt = oldEntry.txt;
+ if(!txt) {
+ txt = dcons.create("i",{class: "info"});
+ oldEntry.txt = txt;
+ oldEntry.subDiv.appendChild(txt);
+ }
+ if(newEntry.latestPing) {
+ if(newEntry.latestPing.alive) {
+ setText(txt, "Ping: " + fmtNs(newEntry.latestPing.ns));
+ } else {
+ //setText(txt, "Ping: " + fmtNs(newEntry.latestPing.ns));
+ setText(txt, "Ping Timeout: " + fmtNs(newEntry.latestPing.ns));
+ }
+ } else {
+ setText(txt, "(no ping)");
}
}
- }
- setText(txt, statusTxt);
- } else {
- setText(txt, "");
- }
- }
- };
-
- if(stw_config.reloadOnly) { // 'only' mode- no header.
- servers.div.innerHTML="<h3>Status:</h3>";
- }
- div.adopt(servers.div);
-
- var hosts = {
- list: {},
- div: dcons.create("div",{id: "hosts", class: "group", innerHTML: "<h3>Hosts</h3>" }),
- update: function(obj, e, newEntry, now, json) {
- var oldEntry = obj.list[e];
- if(newEntry.stealth) {
- oldEntry.subDiv.className = "stealth";
- } else if(newEntry.latestPing) {
- oldEntry.subDiv.className = (newEntry.latestPing.alive ? "up" : "down");
- } else {
- oldEntry.subDiv.className = "unknown";
- }
-
- var txt = oldEntry.txt;
- if(!txt) {
- txt = dcons.create("i",{class: "info"});
- oldEntry.txt = txt;
- oldEntry.subDiv.appendChild(txt);
- }
- if(newEntry.latestPing) {
- if(newEntry.latestPing.alive) {
- setText(txt, "Ping: " + fmtNs(newEntry.latestPing.ns));
- } else {
- //setText(txt, "Ping: " + fmtNs(newEntry.latestPing.ns));
- setText(txt, "Ping Timeout: " + fmtNs(newEntry.latestPing.ns));
- }
- } else {
- setText(txt, "(no ping)");
- }
- }
- };
+ };
+ var servers = {
+ list: {},
+ div: dcons.create("div",{id: "servers", class: "group", innerHTML: "<h3>SurveyTool Instances</h3>" }),
+ update: function(obj, e, newEntry, now, json) {
+ var oldEntry = obj.list[e];
+ var txtstatus = "unknown";
+
+ if(newEntry.lastKnownStatus) {
+ txtstatus = (newEntry.lastKnownStatus.up ? "up" : "down");
+ }
+ oldEntry.subDiv.className = txtstatus;
- if(!stw_config.reloadOnly) { // 'only' mode- no hosts.
- div.adopt(hosts.div);
- }
-
- var lastTime=-1;
- var drift =0;
-
- stw_update = function() {
- request
- .get(stw_config.jsonurl, {handleAs: 'json'})
- .then(function(json) {
- var now = new Date().getTime();
- drift = now - json.now; // loading 'delay' (or clock skew)
-
- lastTime = now;
- setText("#age", "Updated just now");
+ if(stw_config.reloadOnly) {
+ oldEntry.subDiv.getElementsByTagName('h4')[0].innerHTML = txtstatus;
+ }
- if(theInterval2 === -1) {
- theInterval2 = setInterval(function(){
- var now2 = new Date().getTime();
- var age = (now2-lastTime);
- var till = refreshTime - age;
- var tillMsg = ", will refresh soon";
- if(till>0) {
- tillMsg = ", will refresh in "+ fmtNs(till*1e6);
+ var links = oldEntry.links;
+ if(!links) {
+ links = dcons.create("ul",{class: "links"});
+ oldEntry.links = links;
+
+ obj.host = newEntry.host;
+ obj.hostEnt = json.hosts[obj.host];
+ if(stw_config.reloadOnly) {
+ var urlLink = dcons.create("button",{innerHTML: "Try Now"});
+ urlLink.onclick = function() {
+ window.location.reload(true);
+ };
+ links.appendChild(urlLink);
+ } else {
+
+ {
+ var urlLink = dcons.create("a",{href: obj.hostEnt.servers[e].url, innerHTML: "visit"});
+ var urlLi = dcons.create("li");
+ urlLi.appendChild(urlLink);
+ links.appendChild(urlLi);
+ }
+ {
+ var urlLink = dcons.create("button",{innerHTML: "history"});
+ var urlLi = dcons.create("li");
+ urlLi.appendChild(urlLink);
+ links.appendChild(urlLi);
+
+ urlLink.onclick = function() {
+ show_history(e, obj, json.hosts[obj.host]);
+ return false;
+ };
+ }
+ }
+
+ oldEntry.subDiv.appendChild(links);
+ }
+
+ var txt = oldEntry.txt;
+ if(!txt) {
+ txt = dcons.create("i",{class: "info"});
+ oldEntry.txt = txt;
+ oldEntry.subDiv.appendChild(txt);
}
- var ageMsg = "just now";
- if(age > 250) {
- ageMsg = fmtNs(age*1e6) + " ago";
+
+ if(newEntry.latestStatus && newEntry.latestStatus.update) {
+ var u = newEntry.latestStatus.update;
+ var j = newEntry.latestStatus.json;
+ var statusTxt = "";
+ if(u.users != null && u.users != 0) {
+ statusTxt = statusTxt + u.users+" user(s) ";
+ }
+ if(u.guests != null&& u.guests!=0) {
+ statusTxt = statusTxt + u.guests+" viewer(s) ";
+ }
+ if(u.load != null) {
+ var parts = u.load.split(" ");
+ var load = Number(parts[0]);
+ var ncpus = Number(parts[1].split('=')[1]);
+ updateCpu(hosts.list[obj.host].subDiv, load, ncpus);
+ }
+ if(u.isSetup == false) {
+ statusTxt = statusTxt + "(not running) ";
+ }
+ if(j) {
+ if(j.status) {
+ if(j.status.currev !== null) {
+ statusTxt = statusTxt + "r"+j.status.currev;
+ }
+ }
+ }
+ setText(txt, statusTxt);
+ } else {
+ setText(txt, "");
}
- setText("#age", "Updated "+ageMsg +tillMsg);
- }, 5*1000);
+ }
+ };
+
+ if(stw_config.reloadOnly) { // 'only' mode- no header.
+ servers.div.innerHTML="<h3>Status:</h3>";
}
+
+ if(!stw_config.reloadOnly) { // 'only' mode- no hosts.
+ div.adopt(hosts.div);
+ }
+ div.adopt(servers.div);
- setText("#status", "skew=" + drift+"ms");
- window._JSON = json; // DEBUGGING
+ var lastTime=-1;
+ var drift =0;
- consumeType(servers, json.servers, now, json);
- consumeType(hosts, json.hosts, now, json);
- })
- .otherwise(function(err) {
- setText("#status", "Error Loading! (will retry) " + err);
- //clearInterval(theInterval); // do not keep thrashing
- });
- };
-
- setText("#status", "Loading...");
+ stw_update = function() {
+ request
+ .get(stw_config.jsonurl, {handleAs: 'json'})
+ .then(function(json) {
+ var now = new Date().getTime();
+ drift = now - json.now; // loading 'delay' (or clock skew)
+
+ lastTime = now;
+ setText("#age", "Updated just now");
- stw_update();
- theInterval = setInterval(function(){console.log('Update!'); stw_update();}, refreshTime);
-});
+ if(theInterval2 === -1) {
+ theInterval2 = setInterval(function(){
+ var now2 = new Date().getTime();
+ var age = (now2-lastTime);
+ var till = refreshTime - age;
+ var tillMsg = ", will refresh soon";
+ if(till>0) {
+ tillMsg = ", will refresh in "+ fmtNs(till*1e6);
+ }
+ var ageMsg = "just now";
+ if(age > 250) {
+ ageMsg = fmtNs(age*1e6) + " ago";
+ }
+ setText("#age", "Updated "+ageMsg +tillMsg);
+ }, 5*1000);
+ }
+
+ setText("#status", "clock skew=" + drift+"ms");
+ window._JSON = json; // DEBUGGING
+
+ consumeType(hosts, json.hosts, now, json);
+ consumeType(servers, json.servers, now, json);
+ })
+ .otherwise(function(err) {
+ setText("#status", "Error Loading! (will retry) " + err);
+ //clearInterval(theInterval); // do not keep thrashing
+ });
+ };
+
+ setText("#status", "Loading...");
+
+ stw_update();
+ theInterval = setInterval(function(){console.log('Update!'); stw_update();}, refreshTime);
+ });
}
stwatcher_interval();
diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css
index 836d45f..3f43e5f 100644
--- a/public/stylesheets/style.css
+++ b/public/stylesheets/style.css
@@ -1,11 +1,96 @@
/* @override http://127.0.0.1:3000/stylesheets/style.css */
body {
- margin: 1em;
+ margin: 0;
+ padding: 0 !important;
+}
+
+div#heading {
+ background-color: #aab1c1;
+ padding: .5em;
+ margin: 0;
+}
+
+div#heading ul {
+ display: compact;
+ margin: 0;
+ padding: 0;
+}
+
+div#heading ul li {
+ display: inline;
+ padding-right: 1em;
+}
+
+div#heading .heading-left {
+ margin-right: auto;
+ text-align: left;
+}
+
+div#heading .heading-right {
+ text-align: right;
+ margin-left: auto;
+ margin-right: 0;
+}
+
+div#heading a {
+}
+
+div.cpus {
+ margin: 0.25em;
+ display: block;
+ padding: 10px;
+ margin: 10px;
+}
+
+div.cpus div {
+ height: 20px;
+ display: table-cell;
+ padding: 0;
+ margin: 0;
+ border-top: 2px solid black;
+ border-bottom: 2px solid black;
+}
+
+div.cpus .cpu0 {
+ background-color: yellow;
+ color: white;
+ border-left: 2px solid black;
+
+}
+
+div.cpus .cpu1 {
+ background-color: black;
+ color: green;
+ border-right: 2px solid black;
+}
+
+.cpuMsg {
+ font-size: smaller;
+ white-space: pre;
}
h1 {
font-family: Georgia, "Times New Roman", Times, serif;
+ color: white;
+ text-shadow: 2px 2px 3px black;
+ margin-top: 0;
+ margin-left: 0;
+ margin-bottom: 0;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+}
+
+
+div#main {
+ margin: 1em;
+}
+
+i#status {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ font-size: small;
}
div.group {
@@ -35,7 +120,7 @@ div.group {
background-color: #dfd;
}
.group li.up::before {
- content: '✓';
+ content: '⬆';
color: #0F0;
}
@@ -44,7 +129,7 @@ div.group {
color: white;
}
.group li.down::before {
- content: 'Ⓧ';
+ content: '⬇';
color: #F00;
}
@@ -75,6 +160,7 @@ div.group {
.group > li i.info {
margin-left: 0.5em;
+ font-size: smaller;
}
#hosts > li {
diff --git a/routes/index.js b/routes/index.js
index 87a0419..0681b9d 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -3,11 +3,7 @@
* GET home page.
*/
-//var CONFIG = require("config").SurveyWatcher;
-var CONFIG = {
- ui: "(ui)",
- watcher: "(watcher)"
-};
+var CONFIG = require("config").SurveyWatcher;
exports.index = function(req, res){
res.render('index', { ui: CONFIG.ui, watcher: CONFIG.watcher } );
diff --git a/routes/stwatcher.js b/routes/stwatcher.js
index 38e0181..78aae0c 100644
--- a/routes/stwatcher.js
+++ b/routes/stwatcher.js
@@ -7,48 +7,78 @@ var os = require('os');
var ping = require("ping");
var url = require("url");
var request = require("request");
-var Cloudant = require('cloudant');
-var gaas = require('gaas');
-var VERBOSE = process.env.STWATCHER_VERBOSE || false;
+var orm = require("orm");
+var CONFIG = require("config").SurveyWatcher;
+var VERBOSE = CONFIG.watcher.verbose || false;
// local data
var hosts = {};
var uhosts = {};
var servers = {};
var hostname = os.hostname();
-var appEnv = require('cfenv').getAppEnv();
-var cloudantCred = appEnv.getServiceCreds(/.*[Cc]loudant.*/);
-if(cloudantCred == {}) throw "mising cloudant creds";
-var appsToWatch = appEnv.getServices();
-console.log("Setup stwatcher.. verbose="+VERBOSE);
+var host = (process.env.VCAP_APP_HOST || hostname);
+var port = process.env.VCAP_APP_PORT || CONFIG.port || process.env.PORT || 3000;
+console.log("hostport: " + host+"/"+hostname+":"+port);
-var matchInstances = /SurveyTool.*/;
+var vcap_services = undefined;
+var vcap_application = undefined;
-for ( var k in appsToWatch ) {
- if( ! matchInstances.test(k)) {
+if (process.env.VCAP_SERVICES) {
+ vcap_services = JSON.parse(process.env.VCAP_SERVICES);
+}
+if (process.env.VCAP_APPLICATION) {
+ // console.log("VCAP_APPLICATION: " + process.env.VCAP_APPLICATION);
+ /*
+2014-05-28T08:54:53.23-0700 [App/0] OUT VCAP_APPLICATION: {"limits":{"mem":768,"disk":1024,"fds":16384},"application_version":"76ffd510-4229-410c-ab6d-86a76ec66ec8","application_name":"stwatcher","application_uris":["stwatcher.ng.bluemix.net"],"version":"76ffd510-4229-410c-ab6d-86a76ec66ec8","name":"stwatcher","space_name":"dev","space_id":"0ac42d76-22c4-46e6-a9a6-a4323b9819f3","uris":["stwatcher.ng.bluemix.net"],"users":null,"instance_id":"65addb981b7946a39a2107adb61fea12","instance_index":0,"host":"0.0.0.0","port":63556,"started_at":"2014-05-28 15:54:48 +0000","started_at_timestamp":1401292488,"start":"2014-05-28 15:54:48 +0000","state_timestamp":1401292488}
+*/
+ vcap_application = JSON.parse(process.env.VCAP_APPLICATION);
+}
+
+console.log("Setup stwatcher.. verbose="+VERBOSE + " - have vcap services? " + (vcap_services!==undefined));
+
+var dbpath = undefined;
+var vcap_config = {};
+
+if(vcap_services !== undefined) {
+ console.log("Considering VCAP_SERVICES..");
+ // http://www.ibm.com/developerworks/cloud/library/cl-bluemix-nodejs-app/index.html
+ // look for a service starting with 'mysql'
+ for(var serviceGroup in vcap_services) {
+ for(var k in vcap_services[serviceGroup]) {
+ var service = vcap_services[serviceGroup][k];
+ console.log("VCAP service: `" + serviceGroup+"` . `"+service.name+"`");
+ vcap_config[service.name] = service;
+ if(service.name == 'mysql') {
+ dbpath = service.credentials.uri;
+ console.log("DBPath found.");
+ }
+ }
+ }
+}
+
+
+for ( var k in CONFIG.servers ) {
+ if(CONFIG.servers[k].skip) {
continue;
}
- var serviceInstance = appsToWatch[k];
- if (!serviceInstance.credentials.url) throw "Service " + k + " didn't have credentials.url";
- if (!serviceInstance.credentials.hostname) throw "Service " + k + " didn't have credentials.hostname";
-
- var theUrl = serviceInstance.credentials.url;
- console.log("Considering " + k + " URL " + theUrl);
- if(!hosts[serviceInstance.credentials.hostname]) {
- hosts[serviceInstance.credentials.hostname] = { stealth: false, servers: {} };
+ if(CONFIG.servers[k].url.substr(CONFIG.servers[k].url.length-1)!='/') {
+ CONFIG.servers[k].url = CONFIG.servers[k].url + '/'; // always end with /
}
- servers[k] = { host: serviceInstance.credentials.hostname };
- hosts[serviceInstance.credentials.hostname].servers[k] = { url: theUrl }; // only URL. no other leak.
-
- if(serviceInstance.credentials.stealth) {
- hosts[serviceInstance.credentials.hostname].stealth = true;
+ var theurl = url.parse(CONFIG.servers[k].url);
+ console.log("Considering " + k + " URL " + CONFIG.servers[k].url);
+ if(!hosts[theurl.hostname]) {
+ hosts[theurl.hostname] = { stealth: false, servers: {} };
+ }
+ servers[k] = { host: theurl.hostname };
+ hosts[theurl.hostname].servers[k] = { url: CONFIG.servers[k].url }; // only URL. no other leak.
+ if(CONFIG.servers[k].stealth) {
+ hosts[theurl.hostname].stealth = true;
}
}
function st_notify(opts) {
- if(VERBOSE || true) console.log("Event: " + JSON.stringify(opts));
- return; // ------------------------------------------------------------------------
-
+ if(VERBOSE) console.log("Event: " + JSON.stringify(opts));
+
var notifyList = null;
if(opts.event == 'boot') {
@@ -84,10 +114,11 @@ function st_notify(opts) {
}
if(notify.kind == "email") {
+ if(!vcap_config.SendGrid) {
+ console.log('No sendgrid service..');
+ } else {
+ var sendgrid = require("sendgrid")(vcap_config.SendGrid.credentials.username, vcap_config.SendGrid.credentials.password);
if(VERBOSE) console.log("Sending email notification " + notifyType);;
- var nodemailer = require("nodemailer");
- var smtpTransport = nodemailer.createTransport(notify.mail_kind,
- notify.mail_opts);
var outopts = {
from: notify.from,
@@ -100,15 +131,14 @@ function st_notify(opts) {
('Details: ' + opts.details) + '\n' +
(notify.footer) + '\n'
};
-
- smtpTransport.sendMail(outopts, function(error, response) {
+ sendgrid.send(outopts, function(error, response) {
if(error) {
- console.log(error);
+ console.log("Error sending: "+ error );
} else {
- console.log("Sent: " + notifyType + " - " + response.message + " " + JSON.stringify(opts));
+ console.log("Sent: " + notifyType + " - " + JSON.stringify(response) + " " + JSON.stringify(opts));
}
- smtpTransport.close(); // no more messages
});
+ }
} else if (false && notify.kind == "xmpp") {
var mynotify = notify;
if(!notify.xmpp) {
@@ -203,6 +233,14 @@ st_notify({ event: "boot",
});
+if (dbpath === undefined) {
+ if(!CONFIG.watcher.dbpath) {
+ throw("No config/SurveyWatcher.watcher.dbpath - needs to be of the form mysql://username:password@host/database");
+ } else {
+ dbpath = CONFIG.watcher.dbpath;
+ }
+}
+
exports.latest = function(req,res) {
exports._latest(req,res);
}
@@ -220,35 +258,60 @@ exports._history = function(req,res) {
res.send("Not setup yet");
}
-// patch this
-if ( ! cloudantCred.account ) {
- cloudantCred.account = cloudantCred.username;
-}
-
- var db;
-
-Cloudant(cloudantCred, function(err, cloudant) {
- if(err) {
- console.log("Error with database: " + err.toString());
- throw err;
+orm.connect(dbpath, function (orm_err, db) {
+ if(orm_err) {
+ console.log("Error with database: " + orm_err.toString());
+ throw orm_err;
}
- cloudant.db.create('st-watcher', function() {
- db = cloudant.db.use('st-watcher', true);
+ // setup DB stuff
+ var HostStatus = db.define("hoststatus", {
+ host : String,
+ when : Date,
+ alive : Boolean,
+ ns : Number
+ }, {
+ methods: {
+ },
+ validations: {
+ }
+ });
+
+ var FetchStatus = db.define("fetchstatus", {
+ server : String,
+ when : Date,
+ ns : Number,
+ probation : Boolean,
+ isSetup : Boolean,
+ isBusted : Boolean,
+ users : Number,
+ guests : Number,
+ pages : Number,
+ dbused : Number,
+ mem : String,
+ load : String,
+ info : String,
+ busted : String,
+ uptime : String,
+ stamp : Date, // boot time, relatively
+ statusCode : Number
+ }, {
+ methods: {
+ },
+ validations: {
+ }
+ });
+
+ db.sync(function (err) {
+ !err && console.log("db synced!");
- function postHostStatus(anUpdate, cb) {
+ function postHostStatus(anUpdate) {
hosts[anUpdate.host].latestPing = anUpdate;
- db.insert(anUpdate, function(err, body, header){
- if(!err) {
- //cb(null);
- //reply({ok: true, _rev: body.rev, _id: body.id});
- } else {
- server.log('error', err);
- //reply({err: true});
- //cb(err);
- }
- });
+ HostStatus.create( [anUpdate],
+ function (err, items) {
+ if(err) throw(err);
+ });
}
function postFetchStatus(anUpdate, json) {
@@ -286,13 +349,13 @@ Cloudant(cloudantCred, function(err, cloudant) {
});
}
}
- db.insert(anUpdate, function(err,body,header) {
+ FetchStatus.create( [anUpdate],
+ function (err, items) {
if(err) throw(err);
- //newStatus.id = items[0].id; TODO: get _rev
+ newStatus.id = items[0].id;
servers[anUpdate.server].lastKnownStatus = newStatus;
- });
+ });
}
-
exports.poll = function() {
@@ -330,7 +393,7 @@ exports.poll = function() {
for(var j in hosts[k].servers) {
var server = hosts[k].servers[j];
- var theurl = url.parse(server.url+'/');
+ var theurl = url.parse(server.url);
var statusurl = url.format(url.resolve(theurl, 'SurveyAjax?what=status'));
if(VERBOSE) console.log("* " + statusurl);
@@ -374,7 +437,7 @@ exports.poll = function() {
record.users = body.status.users;
record.guests = body.status.guests;
record.mem = body.status.memfree + '/' + body.status.memtotal;
- record.info = body.status.phase + " " + body.status.newVersion + ' ' + body.status.environment;
+ record.info = body.status.currev + ";"+body.status.phase + " " + body.status.newVersion + ' ' + body.status.environment;
record.load = body.status.sysload + ' cpu='+body.status.sysprocs;
record.dbused = body.status.dbused;
record.uptime = body.status.uptime; // string, unfortunately
@@ -398,35 +461,37 @@ exports.poll = function() {
})(server,j));
}
}
-
+ db.sync(function (err) {
+ if(err) throw(err);
+ //!err && console.log("db synced on update!");
+ });
return latestUpdate;
};
- exports._pollsec = (3600);
- exports._probsec = (500);
+ exports._pollsec = (CONFIG.watcher.polltime || 3600);
+ exports._probsec = (CONFIG.watcher.probation_time || 500);
exports._interval = setInterval(exports.poll,exports._pollsec*1000);
// get the last time for each server
- //TODOTODO
-// for(var k in servers) {
-// (function(k){return function(){FetchStatus.find({server: k}, 1, ["when","Z"], function(err, stat) {
-// if(err) throw (err);
-//
-// if(stat && stat.length >0) {
-// var res = stat[0];
-// var up = (res.isBusted==false && res.statusCode == 200);
-// servers[k].lastKnownStatus={ when: res.when, up: up,
-// probation: res.probation,
-// id: res.id };
-// if(VERBOSE) console.log("SERVER " + k + " : up="+up);
-// } else {
-// if(VERBOSE) console.log("Not found: " + k);
-// }
-// });};})(k)();
-// }
-
- //console.log("Polling every " + CONFIG.watcher.polltime + "s");
+ for(var k in servers) {
+ (function(k){return function(){FetchStatus.find({server: k}, 1, ["when","Z"], function(err, stat) {
+ if(err) throw (err);
+
+ if(stat && stat.length >0) {
+ var res = stat[0];
+ var up = (res.isBusted==false && res.statusCode == 200);
+ servers[k].lastKnownStatus={ when: res.when, up: up,
+ probation: res.probation,
+ id: res.id };
+ if(VERBOSE) console.log("SERVER " + k + " : up="+up);
+ } else {
+ if(VERBOSE) console.log("Not found: " + k);
+ }
+ });};})(k)();
+ }
+
+ console.log("Polling every " + CONFIG.watcher.polltime + "s");
exports.poll(); // first time
// DB based now ready
@@ -447,21 +512,23 @@ exports.poll = function() {
//if(req.query.limit) {
//limit = Integer.parse(req.query.limit);
//}
-
- // TODO: IMP
- if(false) {
-// FetchStatus.find({server: server}, limit, ["when","Z"], function(err, stat) {
-// if(err) throw (err);
-//
-// if(stat && stat.length >0) {
-// res.send({ now: new Date().getTime(), server: server, data: stat });
-// } else {
-// res.send({ now: new Date().getTime(), server: server, err: 'not found' });
-// }
-// });
- }
+
+ FetchStatus.find({server: server}, limit, ["when","Z"], function(err, stat) {
+ if(err) throw (err);
+
+ if(stat && stat.length >0) {
+ res.send({ now: new Date().getTime(), server: server, data: stat });
+ } else {
+ res.send({ now: new Date().getTime(), server: server, err: 'not found' });
+ }
+ });
};
});
-});
+// set up DB versions
+
+}); // orm.connect
+
+
+
diff --git a/views/index.jade b/views/index.jade
index b512edc..2df3264 100644
--- a/views/index.jade
+++ b/views/index.jade
@@ -2,28 +2,29 @@ extends layout
block content
- h1= SurveyWatcher
- p Note - Charts are currently not working. Pardon the dust as we move to the new host.
- p Welcome to the SurveyWatcher
- hr
- div(id='statusdiv')
- i(id='status') Initializing
- div(id='SurveyWatcher')
- hr
- button(onclick='update()') (update)
- i(id='age')
- hr
- h2(id='chartTitle') Charts
- i(id='chartstatus') click a history link above to view charts
- div(id='SurveyChart')
- p (no chart loaded)
- p blue is load, black is user count. vertical red is outage. scroll wheel or Ctrl-"+" / Ctrl-"-" to zoom. dbl click to reset.
- p chart does not reload unless you click the history button again.
- hr
- p Note - Charts are currently not working. Pardon the dust as we move to the new host.
- hr
- i(id='powered') Powered by node.js #{process.version}, Express.js. Running on
- a(href='http://bluemix.net') IBM Bluemix
- i *
- i
- a(href='#{ui.mainurl}') Return
+ div(id='heading')
+ h1= ui.title
+ ul(class='heading-right')
+ li
+ a(href='http://cldr.unicode.org') Return to CLDR
+ li
+ a(href='http://cldr.unicode.org') Help
+ div(id='main')
+ div(id='statusdiv')
+ i(id='status') Initializing
+ div(id='SurveyWatcher')
+ hr
+ button(onclick='stw_update()') (update)
+ i(id='age')
+ hr
+ h2(id='chartTitle') Charts (broken right now, sorry)
+ i(id='chartstatus') click a history link above to view charts
+ div(id='SurveyChart')
+ p (no chart loaded)
+ p blue is load, black is user count. vertical red is outage. scroll wheel or Ctrl-"+" / Ctrl-"-" to zoom. dbl click to reset.
+ p chart does not reload unless you click the history button again.
+ hr
+ i(id='powered') Powered by node.js #{process.version}, Express.js
+ i *
+ i
+ a(href='#{ui.mainurl}') Return
diff --git a/views/layout.jade b/views/layout.jade
index 09dbc95..460d94f 100644
--- a/views/layout.jade
+++ b/views/layout.jade
@@ -1,13 +1,15 @@
doctype html
-html
+html(class='claro')
head
title= ui.title
+ link(rel='stylesheet', href='//ajax.googleapis.com/ajax/libs/dojo/1.9.3/dijit/themes/claro/claro.css')
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='//ajax.googleapis.com/ajax/libs/dojo/1.9.3/dojo/dojo.js')
script window.default_stw_config = { reloadMode: false, jsonurl: '/latest.json', polltime: #{watcher.polltime} };
script(src='/javascripts/stwatcher-client.js')
+
- body
+ body(class='claro')
block content
//- block footer
\ No newline at end of file
@srl295
Copy link
Author

srl295 commented May 20, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment