[Status] Fixed some bugs, moved some things around generally improved code, Also fixed watch task for status plugin css

This commit is contained in:
Khalah Jones-Golden 2015-07-10 11:14:09 -04:00
parent 8d33e9f039
commit 0936b0340c
6 changed files with 166 additions and 122 deletions

View file

@ -0,0 +1,8 @@
<div class="status_chart_wrapper col-md-4">
<h3 class="title">{{chart.niceName}}</h3>
<h4 class="average">
<span ng-repeat="average in chart.average track by $index"><span ng-if="$index">,&nbsp;</span>{{average}}</span>
</h4>
<nvd3 options="chart.options" data="chart.data"></nvd3>
</h4>
</div>

View file

@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="/styles/theme/elk.ico"> <link rel="shortcut icon" href="/styles/theme/elk.ico">
<link rel="stylesheet" href="/status/styles/main.css?_b=@@buildNum">
<link rel="stylesheet" href="/styles/main.css?_b=@@buildNum"> <link rel="stylesheet" href="/styles/main.css?_b=@@buildNum">
<link rel="stylesheet" href="styles/main.css?_b=@@buildNum">
</head> </head>
<body> <body>
<div class="container" ng-controller="StatusPage"> <div class="container" ng-controller="StatusPage">
@ -27,13 +27,13 @@
</h3> </h3>
<div id="plugin_table"> <div id="plugin_table">
<div class="plugin_table_header plugin_row"> <div class="plugin_table_header plugin_row">
<div class="col-md-1 plugin_key">Plugin</div> <div class="col-md-1 col-sm-2 col-xs-4 plugin_key">Plugin</div>
<div class="col-md-11 plugin_state">Status</div> <div class="col-md-11 col-sm-10 col-xs-8 plugin_state">Status</div>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div ng-repeat="(key, plugin) in ui.plugins" class="plugin_table_plugin plugin_row plugin_status_{{plugin.uiStatus}}"> <div ng-repeat="(key, plugin) in ui.plugins" class="plugin_table_plugin plugin_row plugin_status_{{plugin.uiStatus}}">
<div class="col-md-1 plugin_key">{{key}}</div> <div class="col-md-1 col-sm-2 col-xs-4 plugin_key">{{key}}</div>
<div class="col-md-11 plugin_state">{{plugin.message}}</div> <div class="col-md-11 col-sm-10 col-xs-8 plugin_state">{{plugin.message}}</div>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
</div> </div>
@ -41,14 +41,9 @@
<h2>Server Metrics</h2> <h2>Server Metrics</h2>
<p>Interval of 5 seconds, with a max history of 5 minutes.</p> <p>Interval of 5 seconds, with a max history of 5 minutes.</p>
<div id="chart_cont" class="row"> <div id="chart_cont" class="row">
<div ng-repeat="(key, chart) in ui.charts" class="status_chart_wrapper col-md-4"> <div ng-repeat="(key, chart) in ui.charts">
<h3 class="title">{{chart.niceName}}</h2> <kb-sparkline chart-data="ui.charts[key].data" chart-key="key"></kb-sparkline>
<h4 class="average">
<span ng-repeat="average in chart.average track by $index"><span ng-if="$index">, </span>{{average}}</span>
</h4>
<nvd3 options="chart.options" data="chart.data"></nvd3>
</div> </div>
<div class="clearfix"></div>
</div> </div>
</div> </div>
<footer></footer> <footer></footer>

View file

@ -1,5 +1,5 @@
window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directives'], window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'text!status/chartTemplate.html', 'nvd3_directives'],
function (angular, $, _, moment, numeral) { function (angular, $, _, moment, numeral, chartTemplate) {
// Make sure we don't have to deal with statuses by hand // Make sure we don't have to deal with statuses by hand
function getStatus(plugin) { function getStatus(plugin) {
@ -32,6 +32,159 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
} }
function getLabel(plugin) { return getStatus(plugin).label; } function getLabel(plugin) { return getStatus(plugin).label; }
// The Kibana App
angular.module('KibanaStatusApp', ['nvd3'])
.controller('StatusPage', ['$scope', '$http', '$window', '$timeout', function ($scope, $http, $window, $timeout) {
// the object representing all of the elements the ui touches
$scope.ui = {
// show the system status by going through all of the plugins,
// and making sure they're green.
systemStatus: (function () {
// for convenience
function getIdx(plugin) { return getStatus(plugin).idx; }
return function () {
var currentStatus = 'loading';
var currentIdx = getIdx(currentStatus);
// FIXME eh, not too thrilled about this.
var status = _.reduce($scope.ui.plugins, function (curr, plugin, key) {
var pluginIdx = getIdx(plugin);
if (pluginIdx > currentIdx) {
// set the current status
currentStatus = plugin.state;
currentIdx = getIdx(plugin);
}
return currentStatus;
}, 'loading');
// give the ui the label for colors and such
return getStatus(status);
};
}()),
charts: {},
plugins: []
};
var windowHasFocus = true;
angular.element($window).bind({
blur: function () { windowHasFocus = false; },
focus: function () {
windowHasFocus = true;
getAppStatus();
}
});
// To make sure that the alert box doesn't keep showing up
var hasHttpError = false;
function getAppStatus() {
// go ahead and get the info you want
$http
.get('/status/health')
.success(function (data) {
// Assign the propper variables to the scope and change them as necessary
// setup The charts
// wrap the metrics data and append the average
_.mapValues(data.metrics, function (metric, name) {
var currentMetricObj = $scope.ui.charts[name];
var newMetricObj = {data: metric, key: name};
if (currentMetricObj) {
currentMetricObj.data = metric;
} else {
$scope.ui.charts[name] = newMetricObj;
}
});
// give the plugins their proper name so CSS classes can be properply applied
$scope.ui.plugins = _.mapValues(data.status, function (plugin) {
plugin.uiStatus = getLabel(plugin);
return plugin;
});
// Finally notify that there has been a succesful request
hasHttpError = false;
if (windowHasFocus) {
// go ahead and get another status in 5 seconds
$timeout(getAppStatus, 5000);
}
})
.error(function () {
if (!hasHttpError) {
window.alert('Something went terribly wrong while making the request!!! Perhaps your server is down?');
hasHttpError = true;
}
});
}
// Start it all up
getAppStatus();
}])
.directive('kbSparkline', function () {
var directiveDef = {
restrict: 'E',
scope: {
data: '=chartData',
key: '=chartKey'
},
template: chartTemplate,
link: function ($scope, $el, attrs) {
var metricNumberType = numberType($scope.key);
var options = makeChartOptions(metricNumberType);
$scope.chart = { niceName: niceName($scope.key), options: options };
$scope.$watch('data', function (newData) {
var metricList = convertData(newData);
var average = calcAvg(metricList);
$scope.chart.data = metricList;
$scope.chart.average = average;
});
function convertData(data) {
// Metric Values format
// metric: [[xValue, yValue], ...]
// LoadMetric:
// metric: [[xValue, [yValue, yValue2, yValue3]], ...]
// return [
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue}, ...]},
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue1}, ...]},
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue2}, ...]}]
//
// Go through all of the metric values and split the values out.
// returns an array of all of the averages
var metricList = [];
data.forEach(function (vector) {
vector = _.flatten(vector);
var x = vector.shift();
vector.forEach(function (yValue, idx) {
if (!metricList[idx]) {
metricList[idx] = {
key: idx,
values: []
};
}
// unshift to make sure they're in the correct order
metricList[idx].values.unshift({x: x, y: yValue});
});
});
return metricList;
}
function calcAvg(metricList) {
return metricList.map(function (data) {
var uglySum = data.values.reduce(function (sumSoFar, vector) {
return sumSoFar + vector.y;
}, 0);
return formatNumber(uglySum / data.values.length, metricNumberType);
});
}
}
};
// Turns thisIsASentence to // Turns thisIsASentence to
// This Is A Sentence // This Is A Sentence
function niceName(name) { function niceName(name) {
@ -94,121 +247,9 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
}; };
}); });
// The Kibana App return directiveDef;
angular.module('KibanaStatusApp', ['nvd3'])
.controller('StatusPage', ['$scope', '$http', '$window', '$timeout', function ($scope, $http, $window, $timeout) {
// the object representing all of the elements the ui touches
$scope.ui = {
// show the system status by going through all of the plugins,
// and making sure they're green.
systemStatus: (function () {
// for convenience
function getIdx(plugin) { return getStatus(plugin).idx; }
return function () {
var currentStatus = 'loading';
var currentIdx = getIdx(currentStatus);
// FIXME eh, not too thrilled about this.
var status = _.reduce($scope.ui.plugins, function (curr, plugin, key) {
var pluginIdx = getIdx(plugin);
if (pluginIdx > currentIdx) {
// set the current status
currentStatus = plugin.state;
currentIdx = getIdx(plugin);
}
return currentStatus;
}, 'loading');
// give the ui the label for colors and such
return getStatus(status);
};
}()),
charts: {},
plugins: []
};
var windowHasFocus = true;
angular.element($window).bind({
blur: function () { windowHasFocus = false; },
focus: function () {
windowHasFocus = true;
getAppStatus();
}
}); });
function getAppStatus() {
// go ahead and get the info you want
$http
.get('/status/health')
.success(function (data) {
// Assign the propper variables to the scope and change them as necessary
// setup The charts
// wrap the metrics data and append the average
$scope.ui.charts = _.mapValues(data.metrics, function (metric, name) {
// Metric Values format
// metric: [[xValue, yValue], ...]
// LoadMetric:
// metric: [[xValue, [yValue, yValue2, yValue3]], ...]
// return [
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue}, ...]},
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue1}, ...]},
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue2}, ...]}]
//
// Go through all of the metric values and split the values out.
// returns an array of all of the averages
var metricList = [];
var metricNumberType = numberType(name);
// convert the [x,y] into {x: x, y: y}
metric.forEach(function (vector) {
vector = _.flatten(vector);
var x = vector.shift();
vector.forEach(function (yValue, idx) {
if (!metricList[idx]) {
metricList[idx] = {
key: name + idx,
values: []
};
}
// unshift to make sure they're in the correct order
metricList[idx].values.unshift({x: x, y: yValue});
});
});
var average = metricList.map(function (data) {
var uglySum = data.values.reduce(function (sumSoFar, vector) {
return sumSoFar + vector.y;
}, 0);
return formatNumber(uglySum / data.values.length, metricNumberType);
});
var options = makeChartOptions(metricNumberType);
return { data: metricList, average: average, niceName: niceName(name), options: options };
});
// give the plugins their proper name so CSS classes can be properply applied
$scope.ui.plugins = _.mapValues(data.status, function (plugin) {
plugin.uiStatus = getLabel(plugin);
return plugin;
});
if (windowHasFocus) {
// go ahead and get another status in 5 seconds
$timeout(getAppStatus, 5000);
}
})
.error(function () {
window.alert('Something went terribly wrong while making the request!!! Perhaps your server is down?');
});
}
// Start it all up
getAppStatus();
}]);
return { return {
init: function () { init: function () {
$(function () { $(function () {

View file

@ -10,7 +10,8 @@ require.config({
moment: '/bower_components/moment/moment', moment: '/bower_components/moment/moment',
nvd3: '/bower_components/nvd3/build/nv.d3', nvd3: '/bower_components/nvd3/build/nv.d3',
nvd3_directives: '/bower_components/angular-nvd3/dist/angular-nvd3', nvd3_directives: '/bower_components/angular-nvd3/dist/angular-nvd3',
numeral: '/bower_components/numeral/numeral' numeral: '/bower_components/numeral/numeral',
text: '/bower_components/requirejs-text/text'
}, },
shim: { shim: {
angular: { angular: {

View file

@ -52,7 +52,6 @@
#plugin_table { #plugin_table {
margin:0 15px 15px 15px; margin:0 15px 15px 15px;
.plugin_row { .plugin_row {
height:30px;
line-height:30px; line-height:30px;
+ .plugin_row { + .plugin_row {
border-top:1px solid #ebebeb; border-top:1px solid #ebebeb;

View file

@ -7,7 +7,7 @@ module.exports = function (grunt) {
'<%= plugins %>/*/*.less', '<%= plugins %>/*/*.less',
'<%= app %>/**/components/**/*.less', '<%= app %>/**/components/**/*.less',
'<%= app %>/**/components/vislib/components/styles/**/*.less', '<%= app %>/**/components/vislib/components/styles/**/*.less',
'<%= src %>/*/server/plugins/status/public/styles/*.less' '<%= src %>/server/plugins/status/public/styles/main.less'
], ],
tasks: ['less:dev'] tasks: ['less:dev']
}, },