Fixed stat page erroring when coins were added. Changed default stat update interval to 60 seconds.

This commit is contained in:
Matt 2014-04-11 17:26:45 -06:00
parent 201d02d10b
commit cf74cd4119
5 changed files with 119 additions and 68 deletions

View File

@ -11,7 +11,7 @@
"port": 80,
"stratumHost": "cryppit.com",
"stats": {
"updateInterval": 15,
"updateInterval": 60,
"historicalRetention": 43200,
"hashrateWindow": 300,
"redis": {

View File

@ -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, {

View File

@ -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]

View File

@ -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;
}
</style>
<div id="topCharts">
<div class="chartLabel">Workers Per Pool</div>
<div class="chartHolder"><svg id="poolWorkers"/></div>
<div class="chartWrapper">
<div class="chartLabel">Workers Per Pool</div>
<div class="chartHolder"><svg id="poolWorkers"/></div>
</div>
<div class="chartLabel">Hashrate Per Pool</div>
<div class="chartHolder"><svg id="poolHashrate"/></div>
<div class="chartWrapper">
<div class="chartLabel">Hashrate Per Pool</div>
<div class="chartHolder"><svg id="poolHashrate"/></div>
</div>
<div class="chartLabel">Blocks Pending Per Pool</div>
<div class="chartHolder"><svg id="poolBlocks"/></div>
<div class="chartWrapper">
<div class="chartLabel">Blocks Pending Per Pool</div>
<div class="chartHolder"><svg id="poolBlocks"/></div>
</div>
</div>

View File

@ -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();
});