mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
211 lines
5.1 KiB
JavaScript
211 lines
5.1 KiB
JavaScript
'use strict';
|
|
|
|
|
|
angular.module('etcdControlPanel')
|
|
.controller('StatsCtrl', function ($scope, $rootScope, $interval, EtcdV2, statsVega, vg) {
|
|
$scope.graphContainer = '#latency';
|
|
$scope.graphVisibility = 'etcd-graph-show';
|
|
$scope.tableVisibility = 'etcd-table-hide';
|
|
|
|
//make requests
|
|
function readStats() {
|
|
EtcdV2.getStat('leader').get().success(function(data) {
|
|
$scope.leaderStats = data;
|
|
$scope.leaderName = data.leader;
|
|
$scope.peers = [];
|
|
//hardcode leader stats
|
|
$scope.peers.push({
|
|
latency: {
|
|
average: 0,
|
|
current: 0,
|
|
minimum: 0,
|
|
maximum: 0,
|
|
standardDeviation: 0
|
|
},
|
|
name: data.leader
|
|
});
|
|
$.each(data.followers, function(index, value) {
|
|
value.name = index;
|
|
$scope.peers.push(value);
|
|
});
|
|
//sort array so peers don't jump when output
|
|
$scope.peers.sort(function(a, b){
|
|
if(a.name < b.name) {
|
|
return -1;
|
|
}
|
|
if(a.name > b.name) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
});
|
|
drawGraph();
|
|
});
|
|
}
|
|
|
|
function drawGraph () {
|
|
//hardcoded padding from chart json
|
|
var vertPadding = 30;
|
|
var horzPadding = 15;
|
|
//fetch width and height of graph area
|
|
var width = $($scope.graphContainer).width() - horzPadding;
|
|
var height = $($scope.graphContainer).height() - vertPadding;
|
|
|
|
// parse a spec and create a visualization view
|
|
function parse(spec) {
|
|
vg.parse.spec(spec, function(chart) {
|
|
chart({
|
|
el: $scope.graphContainer,
|
|
data: {
|
|
'stats': $scope.peers
|
|
}
|
|
}).width(width).height(height).update();
|
|
});
|
|
}
|
|
parse(statsVega);
|
|
}
|
|
|
|
$scope.showTable = function() {
|
|
$scope.tableVisibility = 'etcd-table-reveal';
|
|
};
|
|
|
|
$scope.showGraph = function() {
|
|
$scope.tableVisibility = 'etcd-table-hide';
|
|
};
|
|
|
|
$scope.getHeight = function() {
|
|
return $(window).height();
|
|
};
|
|
$scope.getWidth = function() {
|
|
return $(window).width();
|
|
};
|
|
//$scope.$watch($scope.getHeight, function() {
|
|
////$('.etcd-container.etcd-stats .etcd-body').css('height', $scope.getHeight()-5);
|
|
//readStats();
|
|
//});
|
|
$scope.$watch($scope.getWidth, function() {
|
|
readStats();
|
|
});
|
|
window.onresize = function(){
|
|
$scope.$apply();
|
|
};
|
|
|
|
$scope.pollPromise = null;
|
|
|
|
$scope.startPolling = function() {
|
|
// Update the graphs live
|
|
if ($scope.pollPromise) {
|
|
return;
|
|
}
|
|
$scope.pollPromise = $interval(function() {
|
|
readStats();
|
|
}, 500);
|
|
};
|
|
|
|
$scope.stopPolling = function() {
|
|
$interval.cancel($scope.pollPromise);
|
|
$scope.pollPromise = null;
|
|
};
|
|
|
|
// Stop polling when navigating away from a view with this controller.
|
|
$rootScope.$on('$routeChangeStart', function () {
|
|
$scope.stopPolling();
|
|
});
|
|
|
|
$scope.startPolling();
|
|
|
|
})
|
|
|
|
|
|
/* statsVega returns the vega configuration for the stats dashboard */
|
|
.factory('statsVega', function () {
|
|
return {
|
|
'padding': {'top': 10, 'left': 5, 'bottom': 40, 'right': 10},
|
|
'data': [
|
|
{
|
|
'name': 'stats'
|
|
},
|
|
{
|
|
'name': 'thresholds',
|
|
'values': [50, 100]
|
|
}
|
|
],
|
|
'scales': [
|
|
{
|
|
'name': 'y',
|
|
'type': 'ordinal',
|
|
'range': 'height',
|
|
'domain': {'data': 'stats', 'field': 'index'}
|
|
},
|
|
{
|
|
'name': 'x',
|
|
'range': 'width',
|
|
'domainMin': 0,
|
|
'domainMax': 100,
|
|
'nice': true,
|
|
'zero': true,
|
|
'domain': {'data': 'stats', 'field': 'data.latency.current'}
|
|
},
|
|
{
|
|
'name': 'color',
|
|
'type': 'linear',
|
|
'domain': [10, 50, 100, 1000000000],
|
|
'range': ['#00DB24', '#FFC000', '#c40022', '#c40022']
|
|
}
|
|
],
|
|
'axes': [
|
|
{
|
|
'type': 'x',
|
|
'scale': 'x',
|
|
'ticks': 6,
|
|
'name': 'Latency (ms)'
|
|
},
|
|
{
|
|
'type': 'y',
|
|
'scale': 'y',
|
|
'properties': {
|
|
'ticks': {
|
|
'stroke': {'value': 'transparent'}
|
|
},
|
|
'majorTicks': {
|
|
'stroke': {'value': 'transparent'}
|
|
},
|
|
'labels': {
|
|
'fill': {'value': 'transparent'}
|
|
},
|
|
'axis': {
|
|
'stroke': {'value': '#333'},
|
|
'strokeWidth': {'value': 1}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
'marks': [
|
|
{
|
|
'type': 'rect',
|
|
'from': {'data': 'stats'},
|
|
'properties': {
|
|
'enter': {
|
|
'x': {'scale': 'x', 'value': 0},
|
|
'x2': {'scale': 'x', 'field': 'data.latency.current'},
|
|
'y': {'scale': 'y', 'field': 'index', 'offset': -1},
|
|
'height': {'value': 3},
|
|
'fill': {'scale':'color', 'field':'data.latency.current'}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'type': 'symbol',
|
|
'from': {'data': 'stats'},
|
|
'properties': {
|
|
'enter': {
|
|
'x': {'scale': 'x', 'field': 'data.latency.current'},
|
|
'y': {'scale': 'y', 'field': 'index'},
|
|
'size': {'value': 50},
|
|
'fill': {'value': '#000'}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
};
|
|
});
|