1
0
Fork 0

addtional info inside dashboard view

This commit is contained in:
hkernbach 2017-05-09 20:26:43 +02:00
parent 7f92f80e59
commit 841dc1ed95
7 changed files with 297 additions and 131 deletions

View File

@ -93,23 +93,28 @@
<div id="requests"> <div id="requests">
<div class="contentDiv"> <div class="contentDiv">
<div class="dashboard-row pure-u"> <div class="dashboard-row pure-u cluster-values" id="node-info" style="width: 100%; margin-top: 0;">
<% largeChart("requestsChart", "Requests per Second") %>
<% tendency("Request Types", "asyncRequests", false); %>
<% tendency("Number of Client Connections", "clientConnections", false); %>
</div> </div>
<div class="dashboard-row pure-u small-label-padding"> <% if (hideStatistics !== true) { %>
<% largeChart("dataTransferChart", "Transfer Size per Second") %> <div class="dashboard-row pure-u">
<% smallChart("dataTransferDistribution", "Transfer Size per Second (distribution)", false) %> <% largeChart("requestsChart", "Requests per Second") %>
</div>
<div class="dashboard-row pure-u small-label-padding"> <% tendency("Request Types", "asyncRequests", false); %>
<% largeChart("totalTimeChart", "Average Request Time (seconds)") %> <% tendency("Number of Client Connections", "clientConnections", false); %>
<% smallChart("totalTimeDistribution", "Average Request Time (distribution)", false) %> </div>
<div class="dashboard-row pure-u small-label-padding">
<% largeChart("dataTransferChart", "Transfer Size per Second") %>
<% smallChart("dataTransferDistribution", "Transfer Size per Second (distribution)", false) %>
</div>
<div class="dashboard-row pure-u small-label-padding">
<% largeChart("totalTimeChart", "Average Request Time (seconds)") %>
<% smallChart("totalTimeDistribution", "Average Request Time (distribution)", false) %>
</div>
</div> </div>
</div> <% } %>
</div> </div>
<div id="system" class="tendency-box-sizing" style="display: none";> <div id="system" class="tendency-box-sizing" style="display: none";>

View File

@ -46,11 +46,10 @@
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title" style="clear: both"> <div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title" style="clear: both">
<div class="pure-table-row"> <div class="pure-table-row">
<div class="pure-u-9-24 left">Name</div> <div class="pure-u-10-24 left">Name</div>
<div class="pure-u-9-24 left">Endpoint</div> <div class="pure-u-10-24 left">Endpoint</div>
<div class="pure-u-2-24 mid hide-small">Since</div> <div class="pure-u-3-24 mid hide-small">Since</div>
<div class="pure-u-2-24 mid">Info</div> <div class="pure-u-1-24 mid"></div>
<div class="pure-u-2-24 mid">Status</div>
</div> </div>
</div> </div>
@ -60,24 +59,22 @@
<div class="pure-table-row <%= disabled %>" node="<%= id %>"> <div class="pure-table-row <%= disabled %>" node="<%= id %>">
<div class="pure-u-9-24 left"> <div class="pure-u-10-24 left">
<%= node.ShortName %> <%= node.ShortName %>
<i class="fa fa-bar-chart"></i> <i class="fa fa-bar-chart"></i>
<% if(node.Status === 'FAILED') { %> <% if(node.Status === 'FAILED') { %>
<i class="fa fa-trash-o"></i> <i class="fa fa-trash-o"></i>
<% } %> <% } %>
</div> </div>
<div class="pure-u-9-24 left"><%= node.Endpoint %></div> <div class="pure-u-10-24 left"><%= node.Endpoint %></div>
<% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %> <% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %>
<div class="pure-u-2-24 hide-small mid"><%= formatted %></div> <div class="pure-u-3-24 hide-small mid"><%= formatted %></div>
<div class="pure-u-2-24 mid"><i class="fa fa-info-circle"></i></div>
<% if(node.Status === 'GOOD') { %> <% if(node.Status === 'GOOD') { %>
<div class="pure-u-2-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div> <div class="pure-u-1-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div>
<% } else { %> <% } else { %>
<div class="pure-u-2-24 mid state"><i class="fa fa-exclamation-circle"></i></div> <div class="pure-u-1-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<% } %> <% } %>
</div> </div>
@ -90,7 +87,7 @@
<% if (Object.keys(dbs).length > 0) { %> <% if (Object.keys(dbs).length > 0) { %>
<% var disabled = ''; %> <% var disabled = ''; %>
<% disabled = " disabled"; %> <% disabled = " dbserver"; %>
<div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-2"> <div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-2">
<div class="sectionHeader pure-g"> <div class="sectionHeader pure-g">
<div class="pure-u-1-5"> <div class="pure-u-1-5">
@ -128,11 +125,10 @@
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title"> <div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title">
<div class="pure-table-row"> <div class="pure-table-row">
<div class="pure-u-9-24 left">Name</div> <div class="pure-u-10-24 left">Name</div>
<div class="pure-u-9-24 left">Endpoint</div> <div class="pure-u-10-24 left">Endpoint</div>
<div class="pure-u-2-24 mid hide-small">Since</div> <div class="pure-u-3-24 mid hide-small">Since</div>
<div class="pure-u-2-24 mid">Info</div> <div class="pure-u-1-24 mid"></div>
<div class="pure-u-2-24 mid">Status</div>
</div> </div>
</div> </div>
<% } %> <% } %>
@ -143,18 +139,16 @@
<div class="pure-table-row <%= disabled %>" node="<%= id %>"> <div class="pure-table-row <%= disabled %>" node="<%= id %>">
<div class="pure-u-9-24 left"><%= node.ShortName %></div> <div class="pure-u-10-24 left"><%= node.ShortName %></div>
<div class="pure-u-9-24 left"><%= node.Endpoint %></div> <div class="pure-u-10-24 left"><%= node.Endpoint %></div>
<% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %> <% var formatted = (node.LastHeartbeatAcked).substr(11, 18).slice(0, -1); %>
<div class="pure-u-2-24 mid hide-small"><%= formatted %></div> <div class="pure-u-3-24 mid hide-small"><%= formatted %></div>
<div class="pure-u-2-24 mid"><i class="fa fa-info-circle"></i></div>
<% if(node.Status === 'GOOD') { %> <% if(node.Status === 'GOOD') { %>
<div class="pure-u-2-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div> <div class="pure-u-1-24 mid state"><i class="fa fa-check-circle tippy" title="<%= node.LastHeartbeatStatus %>"></i></div>
<% } else { %> <% } else { %>
<div class="pure-u-2-24 mid state"><i class="fa fa-exclamation-circle"></i></div> <div class="pure-u-1-24 mid state"><i class="fa fa-exclamation-circle"></i></div>
<% } %> <% } %>
</div> </div>

View File

@ -1,6 +1,6 @@
/* jshint browser: true */ /* jshint browser: true */
/* jshint unused: false */ /* jshint unused: false */
/* global Backbone, $, window, arangoHelper, nv, d3, prettyBytes */ /* global Backbone, $, window, arangoHelper, moment, nv, d3, prettyBytes */
/* global document, console, frontendConfig, Dygraph, _,templateEngine */ /* global document, console, frontendConfig, Dygraph, _,templateEngine */
(function () { (function () {
@ -603,6 +603,131 @@
} }
}, },
renderStatisticBox: function (name, value, title) {
// box already rendered, just update value
if ($('#node-info #nodeattribute-' + name).length) {
$('#node-info #nodeattribute-' + name).html(value);
} else {
var elem = '';
elem += '<div class="pure-u-1-2 pure-u-md-1-4" style="background-color: #fff">';
elem += '<div class="valueWrapper">';
if (title) {
elem += '<div id="nodeattribute-' + name + '" class="value tippy" title="' + value + '">' + value + '</div>';
} else {
elem += '<div id="nodeattribute-' + name + '" class="value">' + value + '</div>';
}
elem += '<div class="graphLabel">' + name + '</div>';
elem += '</div>';
elem += '</div>';
$('#node-info').append(elem);
}
},
getNodeInfo: function () {
var self = this;
if (frontendConfig.isCluster) {
// Cluster node
if (this.serverInfo.isDBServer) {
this.renderStatisticBox('Role', 'DBServer');
} else {
this.renderStatisticBox('Role', 'Coordinator');
}
this.renderStatisticBox('Host', this.serverInfo.raw, this.serverInfo.raw);
if (this.serverInfo.endpoint) {
this.renderStatisticBox('Protocol', this.serverInfo.endpoint.substr(0, this.serverInfo.endpoint.indexOf('/') - 1));
} else {
this.renderStatisticBox('Protocol', 'Error');
}
this.renderStatisticBox('ID', this.serverInfo.target, this.serverInfo.target);
// get node version + license
$.ajax({
type: 'GET',
cache: false,
url: arangoHelper.databaseUrl('/_admin/clusterNodeVersion?ServerID=' + this.serverInfo.target),
contentType: 'application/json',
processData: false,
success: function (data) {
self.renderStatisticBox('Version', frontendConfig.version.version);
self.renderStatisticBox('License', frontendConfig.version.license);
},
error: function (data) {
self.renderStatisticBox('Version', 'Error');
self.renderStatisticBox('License', 'Error');
}
});
// get server engine
$.ajax({
type: 'GET',
cache: false,
url: arangoHelper.databaseUrl('/_admin/clusterNodeEngine?ServerID=' + this.serverInfo.target),
contentType: 'application/json',
processData: false,
success: function (data) {
self.renderStatisticBox('Engine', data.name);
},
error: function (data) {
self.renderStatisticBox('Engine', 'Error');
}
});
// get server statistics
$.ajax({
type: 'GET',
cache: false,
url: arangoHelper.databaseUrl('/_admin/clusterNodeStats?ServerID=' + this.serverInfo.target),
contentType: 'application/json',
processData: false,
success: function (data) {
self.renderStatisticBox('Uptime', moment.duration(data.server.uptime, 'seconds').humanize());
},
error: function (data) {
self.renderStatisticBox('Uptime', 'Error');
}
});
} else {
// Standalone
// version + license
this.renderStatisticBox('Version', frontendConfig.version.version);
this.renderStatisticBox('License', frontendConfig.version.license);
// engine status
$.ajax({
type: 'GET',
cache: false,
url: arangoHelper.databaseUrl('/_api/engine'),
contentType: 'application/json',
processData: false,
success: function (data) {
self.renderStatisticBox('Engine', data.name);
},
error: function () {
self.renderStatisticBox('Engine', 'Error');
}
});
// uptime status
$.ajax({
type: 'GET',
cache: false,
url: arangoHelper.databaseUrl('/_admin/statistics'),
contentType: 'application/json',
processData: false,
success: function (data) {
self.renderStatisticBox('Uptime', moment.duration(data.server.uptime, 'seconds').humanize());
},
error: function () {
self.renderStatisticBox('Uptime', 'Error');
}
});
}
arangoHelper.createTooltips();
},
getStatistics: function (callback, modalView) { getStatistics: function (callback, modalView) {
var self = this; var self = this;
self.checkState(); self.checkState();
@ -991,78 +1116,95 @@
template: templateEngine.createTemplate('dashboardView.ejs'), template: templateEngine.createTemplate('dashboardView.ejs'),
render: function (modalView) { render: function (modalView) {
this.delegateEvents(this.events); if (this.serverInfo === undefined) {
var callback = function (enabled, modalView) { this.serverInfo = {
if (!modalView) { isDBServer: false
$(this.el).html(this.template.render()); };
} }
if (this.serverInfo.isDBServer !== true) {
if (!enabled || frontendConfig.db !== '_system') { this.delegateEvents(this.events);
$(this.el).html(''); var callback = function (enabled, modalView) {
if (this.server) { if (!modalView) {
$(this.el).append( $(this.el).html(this.template.render({
'<div style="color: red">Server statistics (' + this.server + ') are disabled.</div>' hideStatistics: false
); }));
} else { this.getNodeInfo();
$(this.el).append(
'<div style="color: red">Server statistics are disabled.</div>'
);
} }
if (!enabled || frontendConfig.db !== '_system') {
$(this.el).html('');
if (this.server) {
$(this.el).append(
'<div style="color: red">Server statistics (' + this.server + ') are disabled.</div>'
);
} else {
$(this.el).append(
'<div style="color: red">Server statistics are disabled.</div>'
);
}
return;
}
this.prepareDygraphs();
if (this.isUpdating) {
this.prepareD3Charts();
this.prepareResidentSize();
this.updateTendencies();
$(window).trigger('resize');
}
this.startUpdating();
$(window).resize();
}.bind(this);
var errorFunction = function () {
$(this.el).html('');
$('.contentDiv').remove();
$('.headerBar').remove();
$('.dashboard-headerbar').remove();
$('.dashboard-row').remove();
$(this.el).append(
'<div style="color: red">You do not have permission to view this page.</div>'
);
$(this.el).append(
'<div style="color: red">You can switch to \'_system\' to see the dashboard.</div>'
);
}.bind(this);
if (frontendConfig.db !== '_system') {
errorFunction();
return; return;
} }
this.prepareDygraphs(); var callback2 = function (error, authorized) {
if (this.isUpdating) { if (!error) {
this.prepareD3Charts(); if (!authorized) {
this.prepareResidentSize(); errorFunction();
this.updateTendencies(); } else {
$(window).trigger('resize'); this.getStatistics(callback, modalView);
} }
this.startUpdating();
$(window).resize();
}.bind(this);
var errorFunction = function () {
$(this.el).html('');
$('.contentDiv').remove();
$('.headerBar').remove();
$('.dashboard-headerbar').remove();
$('.dashboard-row').remove();
$(this.el).append(
'<div style="color: red">You do not have permission to view this page.</div>'
);
$(this.el).append(
'<div style="color: red">You can switch to \'_system\' to see the dashboard.</div>'
);
}.bind(this);
if (frontendConfig.db !== '_system') {
errorFunction();
return;
}
var callback2 = function (error, authorized) {
if (!error) {
if (!authorized) {
errorFunction();
} else {
this.getStatistics(callback, modalView);
} }
} }.bind(this);
}.bind(this);
if (window.App.currentDB.get('name') === undefined) { if (window.App.currentDB.get('name') === undefined) {
window.setTimeout(function () { window.setTimeout(function () {
if (window.App.currentDB.get('name') !== '_system') { if (window.App.currentDB.get('name') !== '_system') {
errorFunction(); errorFunction();
return; return;
} }
// check if user has _system permission
this.options.database.hasSystemAccess(callback2);
}.bind(this), 300);
} else {
// check if user has _system permission // check if user has _system permission
this.options.database.hasSystemAccess(callback2); this.options.database.hasSystemAccess(callback2);
}.bind(this), 300); }
} else { } else {
// check if user has _system permission $(this.el).html(this.template.render({
this.options.database.hasSystemAccess(callback2); hideStatistics: true
}));
// hide menu entries
$('.subMenuEntry').remove();
this.getNodeInfo();
} }
} }
}); });

View File

@ -1,6 +1,6 @@
/* jshint browser: true */ /* jshint browser: true */
/* jshint unused: false */ /* jshint unused: false */
/* global _, Backbone, document, templateEngine, $, arangoHelper, window */ /* global _, Backbone, frontendConfig, document, templateEngine, $, arangoHelper, window */
(function () { (function () {
'use strict'; 'use strict';
@ -180,6 +180,7 @@
processData: false, processData: false,
async: true, async: true,
success: function (data) { success: function (data) {
frontendConfig.version = data;
self.showServerStatus(true); self.showServerStatus(true);
if (self.isOffline === true) { if (self.isOffline === true) {
self.isOffline = false; self.isOffline = false;

View File

@ -67,20 +67,42 @@
continueRender: function () { continueRender: function () {
var self = this; var self = this;
var dashboard;
this.dashboards[this.coordinator.get('name')] = new window.DashboardView({ if (this.coordinator) {
dygraphConfig: window.dygraphConfig, dashboard = this.coordinator.get('name');
database: window.App.arangoDatabase, // coordinator
serverToShow: { this.dashboards[this.coordinator.get('name')] = new window.DashboardView({
raw: this.coordinator.get('address'), dygraphConfig: window.dygraphConfig,
isDBServer: false, database: window.App.arangoDatabase,
endpoint: this.coordinator.get('protocol') + '://' + this.coordinator.get('address'), serverToShow: {
target: this.coordinator.get('name') raw: this.coordinator.get('address'),
} isDBServer: false,
}); endpoint: this.coordinator.get('protocol') + '://' + this.coordinator.get('address'),
this.dashboards[this.coordinator.get('name')].render(); target: this.coordinator.get('name')
}
});
} else {
// db server
var attributes = this.dbServer.toJSON();
dashboard = attributes.name;
this.dashboards[attributes.name] = new window.DashboardView({
dygraphConfig: null,
database: window.App.arangoDatabase,
serverToShow: {
raw: attributes.address,
isDBServer: true,
endpoint: attributes.endpoint,
id: attributes.id,
name: attributes.name,
status: attributes.status,
target: attributes.id
}
});
}
this.dashboards[dashboard].render();
window.setTimeout(function () { window.setTimeout(function () {
self.dashboards[self.coordinator.get('name')].resize(); self.dashboards[dashboard].resize();
}, 500); }, 500);
}, },
@ -111,8 +133,9 @@
self.dbServer = self.dbServers[0]; self.dbServer = self.dbServers[0];
self.dbServer.each(function (model) { self.dbServer.each(function (model) {
if (model.get('name') === 'DBServer001') { var id = model.get('id');
self.dbServer = model; if (id === window.location.hash.split('/')[1]) {
self.dbServer = self.dbServer.findWhere({id: id});
} }
}); });

View File

@ -12,7 +12,7 @@
events: { events: {
'click #nodesContent .coords-nodes .pure-table-row': 'navigateToNode', 'click #nodesContent .coords-nodes .pure-table-row': 'navigateToNode',
'click #nodesContent .dbs-nodes .pure-table-row': 'navigateToInfo', 'click #nodesContent .dbs-nodes .pure-table-row': 'navigateToNode',
'click #nodesContent .coords-nodes .pure-table-row .fa-trash-o': 'deleteNode', 'click #nodesContent .coords-nodes .pure-table-row .fa-trash-o': 'deleteNode',
'click #addCoord': 'addCoord', 'click #addCoord': 'addCoord',
'click #removeCoord': 'removeCoord', 'click #removeCoord': 'removeCoord',
@ -129,20 +129,9 @@
return false; return false;
}, },
navigateToInfo: function (elem) {
var name = $(elem.currentTarget).attr('node').slice(0, -5);
if ($(elem.target).hasClass('fa-info-circle')) {
window.App.navigate('#nodeInfo/' + encodeURIComponent(name), {trigger: true});
}
},
navigateToNode: function (elem) { navigateToNode: function (elem) {
var name = $(elem.currentTarget).attr('node').slice(0, -5); var name = $(elem.currentTarget).attr('node').slice(0, -5);
if ($(elem.target).hasClass('fa-info-circle')) {
window.App.navigate('#nodeInfo/' + encodeURIComponent(name), {trigger: true});
return;
}
if ($(elem.currentTarget).hasClass('noHover')) { if ($(elem.currentTarget).hasClass('noHover')) {
return; return;
} }

View File

@ -463,6 +463,18 @@
margin-left: 2px; margin-left: 2px;
margin-right: 0; margin-right: 0;
.valueWrapper {
.value {
font-size: 18pt !important;
font-weight: 100;
overflow: hidden;
padding-left: 10px;
padding-right: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.fa-arrows-alt { .fa-arrows-alt {
display: none; display: none;
} }