aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinclude/nms/web.pm4
-rw-r--r--web/js/nms-data.js29
-rw-r--r--web/js/nms-map-handlers.js12
-rw-r--r--web/js/nms-map.js59
4 files changed, 80 insertions, 24 deletions
diff --git a/include/nms/web.pm b/include/nms/web.pm
index 18fe919..fcd45b4 100755
--- a/include/nms/web.pm
+++ b/include/nms/web.pm
@@ -76,7 +76,9 @@ sub setwhen {
sub finalize_output {
my $query;
- my $hash = Digest::SHA::sha512_base64(FreezeThaw::freeze(%json));
+ $Data::Dumper::Indent = 0;
+ $Data::Dumper::Sortkeys = 1;
+ my $hash = Digest::SHA::sha512_base64(Data::Dumper::Dumper(\%json));
$dbh->commit;
$query = $dbh->prepare('select extract(epoch from date_trunc(\'seconds\', ' . $now . ')) as time;');
$query->execute();
diff --git a/web/js/nms-data.js b/web/js/nms-data.js
index e3c4106..5a219e8 100644
--- a/web/js/nms-data.js
+++ b/web/js/nms-data.js
@@ -224,18 +224,37 @@ nmsData._genericUpdater = function(name, cacheok) {
heads['Cache-Control'] = "max-age=0, no-cache, stale-while-revalidate=0";
}
+ /*
+ * Note that we intentionally set dataType: "text" here.
+ *
+ * We can be smarter than jQuery here. We know that the ETag can be
+ * used to evaluate against our cached copy. If the ETag is a
+ * match, we never have to do the potentially extensive JSON
+ * parsing.
+ *
+ * Also note that we accept weakened ETags too (ETags with W/
+ * prefixed). This is typically if the intermediate cache has
+ * compressed the content for us, so this is fine.
+ *
+ * This is particularly important because we poll everything even
+ * though we _know_ it will hit both browser cache and most likely
+ * Varnish. JSON.Parse was one of the biggest CPU hogs before this.
+ */
$.ajax({
type: "GET",
headers: heads,
url: this._sources[name].target + now,
- dataType: "json",
- success: function (data, textStatus, jqXHR) {
- if (nmsData[name] == undefined || nmsData[name]['hash'] != data['hash']) {
- if (name == "ping")
+ dataType: "text",
+ success: function (indata, textStatus, jqXHR) {
+ let etag = jqXHR.getResponseHeader("ETag");
+ if (nmsData[name] == undefined || (nmsData[name]['hash'] != etag && nmsData[name]['hash'] != etag.slice(2))) {
+ var data = JSON.parse(indata);
+ if (name == "ping") {
nmsData._last = data['time'];
+ nmsMap.drawNow();
+ }
nmsData.old[name] = nmsData[name];
nmsData[name] = data;
- nmsMap.drawNow();
for (var i in nmsData._sources[name].cbs) {
var tmp2 = nmsData._sources[name].cbs[i];
if (tmp2.cb != undefined) {
diff --git a/web/js/nms-map-handlers.js b/web/js/nms-map-handlers.js
index 38407d1..21ed709 100644
--- a/web/js/nms-map-handlers.js
+++ b/web/js/nms-map-handlers.js
@@ -329,6 +329,7 @@ function tempInit()
setLegend(4,temp_color(30),"30 °C");
setLegend(5,temp_color(35),"35 °C");
nmsData.addHandler("switchstate","mapHandler",tempUpdater);
+ tempUpdater();
}
function pingUpdater()
@@ -401,8 +402,7 @@ function pingInit()
setLegend(4,nmsColor.getColorStop(1000),"100ms");
setLegend(5,nmsColor.blue,"No response");
nmsData.addHandler("ping","mapHandler",pingUpdater);
- nmsData.addHandler("switches","mapHandler",pingUpdater);
- nmsData.addHandler("ticker", "mapHandler", pingUpdater);
+ pingUpdater();
}
function getDhcpColor(stop)
@@ -474,6 +474,7 @@ function dhcpInit()
setLegend(3,getDhcpColor(300),"300 Seconds old");
setLegend(4,getDhcpColor(900),"900 Seconds old");
setLegend(5,getDhcpColor(1200),"1200 Seconds old");
+ dhcpUpdater();
}
/*
@@ -506,6 +507,7 @@ function discoInit()
setLegend(3,nmsColor.orange,"C");
setLegend(4,nmsColor.green, "A");
setLegend(5,"white","!");
+ discoDo();
}
function snmpUpdater() {
@@ -576,7 +578,7 @@ function snmpInit() {
setLegend(3,nmsColor.red,"No SNMP data");
setLegend(4,nmsColor.green, "");
setLegend(5,nmsColor.green,"");
-
+ snmpUpdater();
}
function cpuUpdater() {
@@ -645,6 +647,7 @@ function cpuInit() {
setLegend(3,getColorStop(600),"60 %");
setLegend(4,getColorStop(1000),"100 %");
setLegend(5,"white","N/A");
+ cpuUpdater();
}
function healthInfo(sw) {
@@ -682,11 +685,12 @@ function healthUpdater() {
}
function healthInit() {
- nmsData.addHandler("ping", "mapHandler", healthUpdater);
+ nmsData.addHandler("ticker", "mapHandler", healthUpdater);
nmsColor.drawGradient([nmsColor.green,nmsColor.lightgreen, nmsColor.orange,nmsColor.red]);
setLegend(1,nmsColor.getColorStop(0),"All good");
setLegend(2,nmsColor.getColorStop(250),"Ok-ish");
setLegend(3,nmsColor.getColorStop(600),"Ick-ish");
setLegend(4,nmsColor.getColorStop(800),"Nasty");
setLegend(5,nmsColor.getColorStop(1000),"WTF?");
+ healthUpdater();
}
diff --git a/web/js/nms-map.js b/web/js/nms-map.js
index 26782f8..491916b 100644
--- a/web/js/nms-map.js
+++ b/web/js/nms-map.js
@@ -26,13 +26,16 @@ var nmsMap = nmsMap || {
resizeEvents:0,
switchInfoSame:0,
switchInfoUpdate:0,
- highlightChange:0
+ highlightChange:0,
+ textSwitchDraws:0,
+ textInfoDraws:0,
+ textInfoClears:0
},
contexts: ["bg","link","blur","switch","text","textInfo","top","input","hidden"],
_info: {},
_settings: {
fontLineFactor: 2,
- textMargin: 3,
+ textMargin: 4,
xMargin: 10,
yMargin: 20,
fontSize: 15,
@@ -50,7 +53,9 @@ var nmsMap = nmsMap || {
_linknets: {} ,
_highlight: { },
_highlightActive: false,
- _c: {}
+ _c: {},
+ _lastName: {},
+ _lastInfo: {}
};
nmsMap._loadEvent = function(e) {
@@ -136,7 +141,17 @@ nmsMap._resizeEvent = function() {
var xScale = (width / (nmsMap._orig.width + nmsMap._settings.xMargin));
var yScale = (height / (nmsMap._orig.height + nmsMap._settings.yMargin));
-
+
+ /*
+ * We need to forget this. Because the rescale will blank the text
+ * anyway it is safe to set it to undefined here. This is a special
+ * case, if you set it to 'undefined' anywhere else to "reset" or
+ * force a redraw of the text you will introduce a bug if a handler
+ * then tries to _unset_ the text (which you do by setting the text
+ * to undefined)
+ */
+ nmsMap._lastName = {};
+ nmsMap._lastInfo = {};
if (xScale > yScale) {
nmsMap.scale = yScale;
} else {
@@ -150,9 +165,9 @@ nmsMap._resizeEvent = function() {
continue;
nmsMap._c[a].c.height = nmsMap._canvas.height;
nmsMap._c[a].c.width = nmsMap._canvas.width;
- if(a == 'bg') {
- nmsMap._drawBG();
- }
+ if(a == 'bg') {
+ nmsMap._drawBG();
+ }
}
if (nmsMap._init != true) {
nmsMap._blurDrawn = false;
@@ -296,7 +311,16 @@ nmsMap._drawSwitch = function(sw)
this._c.switch.ctx.fillStyle = color;
this._drawBox(this._c.switch.ctx, box['x'],box['y'],box['width'],box['height']);
this._c.switch.ctx.shadowBlur = 0;
- this._drawText(this._c.text.ctx, sw,box);
+ var switchtext = sw;
+ var textl = switchtext.length;
+ if (textl > 10)
+ switchtext = switchtext.slice(0,5) + ".." + switchtext.slice(textl-2,textl);
+
+ if (this._lastName[sw] != switchtext) {
+ nmsMap.stats.textSwitchDraws++;
+ this._drawText(this._c.text.ctx, switchtext,box);
+ this._lastName[sw] = switchtext;
+ }
if(this._info[sw])
this._drawSwitchInfo(sw);
@@ -304,17 +328,24 @@ nmsMap._drawSwitch = function(sw)
nmsMap._drawSwitchInfo = function(sw) {
var box = this._getBox(sw);
- if (this._info[sw] == undefined) {
- this._clearBox(this._c.textInfo.ctx, box);
- } else {
+ if (this._lastInfo[sw] == this._info[sw])
+ return;
+ this._clearBox(this._c.textInfo.ctx, box, 3);
+ nmsMap.stats.textInfoClears++;
+ if (this._info[sw] != undefined) {
this._drawText(this._c.textInfo.ctx, this._info[sw], box, "right");
+ nmsMap.stats.textInfoDraws++;
}
+ this._lastInfo[sw] = this._info[sw];
};
-nmsMap._clearBox = function(ctx,box) {
+nmsMap._clearBox = function(ctx,box,margin) {
+ if (margin == undefined)
+ margin = 0;
ctx.save();
+ margin = Math.floor(margin * this.scale );
ctx.scale(this.scale,this.scale);
- ctx.clearRect(box['x'], box['y'], box['width'], box['height']);
+ ctx.clearRect(box['x'] - margin, box['y'] - margin, box['width'] + margin*2, box['height'] + margin*2);
ctx.restore();
};
@@ -324,7 +355,7 @@ nmsMap._drawText = function(ctx, text, box, align) {
if ((box['width'] + 10 )< box['height'])
rotate = true;
- this._clearBox(ctx,box);
+ this._clearBox(ctx,box, 1);
ctx.save();
ctx.scale(this.scale, this.scale);
ctx.font = "bold " + this._settings.fontSize + "px " + this._settings.fontFace;