[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">
<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">
</head>
<body>
<div class="container" ng-controller="StatusPage">
@ -27,13 +27,13 @@
</h3>
<div id="plugin_table">
<div class="plugin_table_header plugin_row">
<div class="col-md-1 plugin_key">Plugin</div>
<div class="col-md-11 plugin_state">Status</div>
<div class="col-md-1 col-sm-2 col-xs-4 plugin_key">Plugin</div>
<div class="col-md-11 col-sm-10 col-xs-8 plugin_state">Status</div>
<div class="clearfix"></div>
</div>
<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-11 plugin_state">{{plugin.message}}</div>
<div class="col-md-1 col-sm-2 col-xs-4 plugin_key">{{key}}</div>
<div class="col-md-11 col-sm-10 col-xs-8 plugin_state">{{plugin.message}}</div>
<div class="clearfix"></div>
</div>
</div>
@ -41,14 +41,9 @@
<h2>Server Metrics</h2>
<p>Interval of 5 seconds, with a max history of 5 minutes.</p>
<div id="chart_cont" class="row">
<div ng-repeat="(key, chart) in ui.charts" class="status_chart_wrapper col-md-4">
<h3 class="title">{{chart.niceName}}</h2>
<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 ng-repeat="(key, chart) in ui.charts">
<kb-sparkline chart-data="ui.charts[key].data" chart-key="key"></kb-sparkline>
</div>
<div class="clearfix"></div>
</div>
</div>
<footer></footer>

View file

@ -1,5 +1,5 @@
window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directives'],
function (angular, $, _, moment, numeral) {
window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'text!status/chartTemplate.html', 'nvd3_directives'],
function (angular, $, _, moment, numeral, chartTemplate) {
// Make sure we don't have to deal with statuses by hand
function getStatus(plugin) {
@ -32,68 +32,6 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
}
function getLabel(plugin) { return getStatus(plugin).label; }
// Turns thisIsASentence to
// This Is A Sentence
function niceName(name) {
return name
.split(/(?=[A-Z])/)
.map(function (word) { return word[0].toUpperCase() + _.rest(word).join(''); })
.join(' ');
}
function formatNumber(num, which) {
var format = '0.00';
var postfix = '';
switch (which) {
case 'time':
return moment(num).format('HH:mm:ss');
case 'byte':
format += 'b';
break;
case 'ms':
postfix = 'ms';
break;
}
return numeral(num).format(format) + postfix;
}
function numberType(key) {
var byteMetrics = ['heapTotal', 'heapUsed', 'rss'];
var msMetrics = ['delay', 'responseTimeAvg', 'responseTimeMax'];
var preciseMetric = ['requests', 'load'];
if ( byteMetrics.indexOf(key) > -1 ) {
return 'byte';
} else if (msMetrics.indexOf(key) > -1 ) {
return 'ms';
} else {
return 'precise';
}
}
var makeChartOptions = _.memoize(function (type) {
return {
chart: {
type: 'lineChart',
height: 200,
showLegend: false,
showXAxis: false,
showYAxis: false,
useInteractiveGuideline: true,
tooltips: true,
pointSize: 0,
color: ['#444', '#777', '#aaa'],
margin: {
top: 10,
left: 0,
right: 0,
bottom: 20
},
xAxis: { tickFormat: function (d) { return formatNumber(d, 'time'); } },
yAxis: { tickFormat: function (d) { return formatNumber(d, type); }, },
y: function (d) { return d.y; },
x: function (d) { return d.x; }
}
};
});
// The Kibana App
angular.module('KibanaStatusApp', ['nvd3'])
.controller('StatusPage', ['$scope', '$http', '$window', '$timeout', function ($scope, $http, $window, $timeout) {
@ -137,6 +75,9 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
}
});
// 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
@ -146,47 +87,14 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
// 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 };
_.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
@ -195,19 +103,152 @@ window.define(['angular', 'jquery', 'lodash', 'moment', 'numeral', 'nvd3_directi
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 () {
window.alert('Something went terribly wrong while making the request!!! Perhaps your server is down?');
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
// This Is A Sentence
function niceName(name) {
return name
.split(/(?=[A-Z])/)
.map(function (word) { return word[0].toUpperCase() + _.rest(word).join(''); })
.join(' ');
}
function formatNumber(num, which) {
var format = '0.00';
var postfix = '';
switch (which) {
case 'time':
return moment(num).format('HH:mm:ss');
case 'byte':
format += 'b';
break;
case 'ms':
postfix = 'ms';
break;
}
return numeral(num).format(format) + postfix;
}
function numberType(key) {
var byteMetrics = ['heapTotal', 'heapUsed', 'rss'];
var msMetrics = ['delay', 'responseTimeAvg', 'responseTimeMax'];
var preciseMetric = ['requests', 'load'];
if ( byteMetrics.indexOf(key) > -1 ) {
return 'byte';
} else if (msMetrics.indexOf(key) > -1 ) {
return 'ms';
} else {
return 'precise';
}
}
var makeChartOptions = _.memoize(function (type) {
return {
chart: {
type: 'lineChart',
height: 200,
showLegend: false,
showXAxis: false,
showYAxis: false,
useInteractiveGuideline: true,
tooltips: true,
pointSize: 0,
color: ['#444', '#777', '#aaa'],
margin: {
top: 10,
left: 0,
right: 0,
bottom: 20
},
xAxis: { tickFormat: function (d) { return formatNumber(d, 'time'); } },
yAxis: { tickFormat: function (d) { return formatNumber(d, type); }, },
y: function (d) { return d.y; },
x: function (d) { return d.x; }
}
};
});
return directiveDef;
});
return {
init: function () {

View file

@ -10,7 +10,8 @@ require.config({
moment: '/bower_components/moment/moment',
nvd3: '/bower_components/nvd3/build/nv.d3',
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: {
angular: {

View file

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

View file

@ -7,7 +7,7 @@ module.exports = function (grunt) {
'<%= plugins %>/*/*.less',
'<%= app %>/**/components/**/*.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']
},