From cf74cd41196a1f324778a8bf970eb5ec2a4eceb0 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 11 Apr 2014 17:26:45 -0600 Subject: [PATCH] Fixed stat page erroring when coins were added. Changed default stat update interval to 60 seconds. --- config_example.json | 2 +- libs/api.js | 3 +- libs/stats.js | 12 +--- website/pages/stats.html | 32 +++++---- website/static/stats.js | 138 ++++++++++++++++++++++++++------------- 5 files changed, 119 insertions(+), 68 deletions(-) diff --git a/config_example.json b/config_example.json index 8759fcf..8cd417c 100644 --- a/config_example.json +++ b/config_example.json @@ -11,7 +11,7 @@ "port": 80, "stratumHost": "cryppit.com", "stats": { - "updateInterval": 15, + "updateInterval": 60, "historicalRetention": 43200, "hashrateWindow": 300, "redis": { diff --git a/libs/api.js b/libs/api.js index 53ebd70..3a433ab 100644 --- a/libs/api.js +++ b/libs/api.js @@ -18,8 +18,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ res.end(portalStats.statsString); return; case 'pool_stats': - res.writeHead(200, {'content-encoding': 'gzip'}); - res.end(portalStats.statPoolHistoryBuffer); + res.end(JSON.stringify(portalStats.statPoolHistory)); return; case 'live_stats': res.writeHead(200, { diff --git a/libs/stats.js b/libs/stats.js index 459ff14..62b7f00 100644 --- a/libs/stats.js +++ b/libs/stats.js @@ -20,7 +20,6 @@ module.exports = function(logger, portalConfig, poolConfigs){ this.statHistory = []; this.statPoolHistory = []; - this.statPoolHistoryBuffer; this.stats = {}; this.statsString = ''; @@ -84,7 +83,6 @@ module.exports = function(logger, portalConfig, poolConfigs){ _this.statHistory.forEach(function(stats){ addStatPoolHistory(stats); }); - deflateStatPoolHistory(); }); } @@ -96,7 +94,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ for (var pool in stats.pools){ data.pools[pool] = { hashrate: stats.pools[pool].hashrate, - workers: stats.pools[pool].workerCount, + workerCount: stats.pools[pool].workerCount, blocks: stats.pools[pool].blocks } } @@ -104,11 +102,7 @@ module.exports = function(logger, portalConfig, poolConfigs){ } - function deflateStatPoolHistory(){ - zlib.gzip(JSON.stringify(_this.statPoolHistory), function(err, buffer){ - _this.statPoolHistoryBuffer = buffer; - }); - } + this.getGlobalStats = function(callback){ @@ -245,8 +239,6 @@ module.exports = function(logger, portalConfig, poolConfigs){ } } - deflateStatPoolHistory(); - redisStats.multi([ ['zadd', 'statHistory', statGatherTime, _this.statsString], ['zremrangebyscore', 'statHistory', '-inf', '(' + retentionTime] diff --git a/website/pages/stats.html b/website/pages/stats.html index d7193b3..435a28f 100644 --- a/website/pages/stats.html +++ b/website/pages/stats.html @@ -4,11 +4,18 @@ padding: 18px; } - #topCharts > div > svg{ + #topCharts > div > div > svg{ display: block; height: 280px; } + .chartWrapper{ + border: solid 1px #c7c7c7; + border-radius: 5px; + padding: 5px; + margin-bottom: 18px; + } + .chartLabel{ font-size: 1.2em; text-align: center; @@ -16,24 +23,27 @@ } .chartHolder{ - border: solid 1px #c7c7c7; - border-radius: 5px; - padding: 5px; - margin-bottom: 18px; + }
-
Workers Per Pool
-
+
+
Workers Per Pool
+
+
-
Hashrate Per Pool
-
+
+
Hashrate Per Pool
+
+
-
Blocks Pending Per Pool
-
+
+
Blocks Pending Per Pool
+
+
diff --git a/website/static/stats.js b/website/static/stats.js index 4d5b885..10e43d6 100644 --- a/website/static/stats.js +++ b/website/static/stats.js @@ -1,29 +1,57 @@ -var poolWorkerData = []; -var poolHashrateData = []; -var poolBlockData = []; +var poolWorkerData; +var poolHashrateData; +var poolBlockData; var poolWorkerChart; var poolHashrateChart; var poolBlockChart; -function buildChartData(data){ +var statData; +var poolKeys; + +function buildChartData(){ var pools = {}; - for (var i = 0; i < data.length; i++){ - var time = data[i].time * 1000; - for (var pool in data[i].pools){ - var a = pools[pool] = (pools[pool] || { + poolKeys = []; + for (var i = 0; i < statData.length; i++){ + for (var pool in statData[i].pools){ + if (poolKeys.indexOf(pool) === -1) + poolKeys.push(pool); + } + } + + + for (var i = 0; i < statData.length; i++){ + + var time = statData[i].time * 1000; + + for (var f = 0; f < poolKeys.length; f++){ + var pName = poolKeys[f]; + var a = pools[pName] = (pools[pName] || { hashrate: [], workers: [], blocks: [] }); - a.hashrate.push([time, data[i].pools[pool].hashrate || 0]); - a.workers.push([time, data[i].pools[pool].workers || 0]); - a.blocks.push([time, data[i].pools[pool].blocks.pending]) + if (pName in statData[i].pools){ + a.hashrate.push([time, statData[i].pools[pName].hashrate]); + a.workers.push([time, statData[i].pools[pName].workerCount]); + a.blocks.push([time, statData[i].pools[pName].blocks.pending]) + } + else{ + a.hashrate.push([time, 0]); + a.workers.push([time, 0]); + a.blocks.push([time, 0]) + } + } + } + poolWorkerData = []; + poolHashrateData = []; + poolBlockData = []; + for (var pool in pools){ poolWorkerData.push({ key: pool, @@ -47,21 +75,26 @@ function getReadableHashRateString(hashrate){ hashrate = hashrate / 1024; i++; } while (hashrate > 1024); - return hashrate.toFixed(2) + byteUnits[i]; + return Math.round(hashrate) + byteUnits[i]; +} + +function timeOfDayFormat(timestamp){ + var dStr = d3.time.format('%I:%M %p')(new Date(timestamp)); + if (dStr.indexOf('0') === 0) dStr = dStr.slice(1); + return dStr; } function displayCharts(){ nv.addGraph(function() { poolWorkerChart = nv.models.stackedAreaChart() + .margin({left: 40, right: 40}) .x(function(d){ return d[0] }) .y(function(d){ return d[1] }) .useInteractiveGuideline(true) .clipEdge(true); - poolWorkerChart.xAxis.tickFormat(function(d) { - return d3.time.format('%X')(new Date(d)) - }); + poolWorkerChart.xAxis.tickFormat(timeOfDayFormat); poolWorkerChart.yAxis.tickFormat(d3.format('d')); @@ -73,13 +106,12 @@ function displayCharts(){ nv.addGraph(function() { poolHashrateChart = nv.models.lineChart() + .margin({left: 60, right: 40}) .x(function(d){ return d[0] }) .y(function(d){ return d[1] }) .useInteractiveGuideline(true); - poolHashrateChart.xAxis.tickFormat(function(d) { - return d3.time.format('%X')(new Date(d)) - }); + poolHashrateChart.xAxis.tickFormat(timeOfDayFormat); poolHashrateChart.yAxis.tickFormat(function(d){ return getReadableHashRateString(d); @@ -96,9 +128,7 @@ function displayCharts(){ .x(function(d){ return d[0] }) .y(function(d){ return d[1] }); - poolBlockChart.xAxis.tickFormat(function(d) { - return d3.time.format('%X')(new Date(d)) - }); + poolBlockChart.xAxis.tickFormat(timeOfDayFormat); d3.select('#poolBlocks').datum(poolBlockData).call(poolBlockChart); @@ -115,36 +145,56 @@ function TriggerChartUpdates(){ nv.utils.windowResize(TriggerChartUpdates); $.getJSON('/api/pool_stats', function(data){ - buildChartData(data); + statData = data; + buildChartData(); displayCharts(); }); statsSource.addEventListener('message', function(e){ var stats = JSON.parse(e.data); - var time = stats.time * 1000; - for (var pool in stats.pools){ - for (var i = 0; i < poolWorkerData.length; i++){ - if (poolWorkerData[i].key === pool){ - poolWorkerData[i].values.shift(); - poolWorkerData[i].values.push([time, stats.pools[pool].workerCount]); - break; - } - } - for (var i = 0; i < poolHashrateData.length; i++){ - if (poolHashrateData[i].key === pool){ - poolHashrateData[i].values.shift(); - poolHashrateData[i].values.push([time, stats.pools[pool].hashrate]); - break; - } - } - for (var i = 0; i < poolBlockData.length; i++){ - if (poolBlockData[i].key === pool){ - poolBlockData[i].values.shift(); - poolBlockData[i].values.push([time, stats.pools[pool].blocks.pending]); - break; + statData.push(stats); + + + var newPoolAdded = (function(){ + for (var p in stats.pools){ + if (poolKeys.indexOf(p) === -1) + return true; + } + return false; + })(); + + if (newPoolAdded || Object.keys(stats.pools).length > poolKeys.length){ + buildChartData(); + displayCharts(); + } + else { + var time = stats.time * 1000; + for (var f = 0; f < poolKeys.length; f++) { + var pool = poolKeys[f]; + for (var i = 0; i < poolWorkerData.length; i++) { + if (poolWorkerData[i].key === pool) { + poolWorkerData[i].values.shift(); + poolWorkerData[i].values.push([time, pool in stats.pools ? stats.pools[pool].workerCount : 0]); + break; + } + } + for (var i = 0; i < poolHashrateData.length; i++) { + if (poolHashrateData[i].key === pool) { + poolHashrateData[i].values.shift(); + poolHashrateData[i].values.push([time, pool in stats.pools ? stats.pools[pool].hashrate : 0]); + break; + } + } + for (var i = 0; i < poolBlockData.length; i++) { + if (poolBlockData[i].key === pool) { + poolBlockData[i].values.shift(); + poolBlockData[i].values.push([time, pool in stats.pools ? stats.pools[pool].blocks.pending : 0]); + break; + } } } + TriggerChartUpdates(); } - TriggerChartUpdates(); + }); \ No newline at end of file