mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Merge branch 'pr/4724'
This commit is contained in:
commit
556e79dc2f
10 changed files with 223 additions and 151 deletions
|
@ -5,6 +5,7 @@ define(function (require) {
|
|||
require('plugins/kibana/settings/sections/indices/index'),
|
||||
require('plugins/kibana/settings/sections/advanced/index'),
|
||||
require('plugins/kibana/settings/sections/objects/index'),
|
||||
require('plugins/kibana/settings/sections/status/index'),
|
||||
require('plugins/kibana/settings/sections/about/index')
|
||||
];
|
||||
});
|
||||
|
|
10
src/plugins/kibana/public/settings/sections/status/index.js
Normal file
10
src/plugins/kibana/public/settings/sections/status/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
|
||||
return {
|
||||
order: 3,
|
||||
name: 'status',
|
||||
display: 'Status',
|
||||
url: '/status'
|
||||
};
|
||||
});
|
|
@ -9,10 +9,10 @@ module.exports = function formatNumber(num, which) {
|
|||
case 'time':
|
||||
return moment(num).format('HH:mm:ss');
|
||||
case 'byte':
|
||||
format += 'b';
|
||||
format += ' b';
|
||||
break;
|
||||
case 'ms':
|
||||
postfix = 'ms';
|
||||
postfix = ' ms';
|
||||
break;
|
||||
}
|
||||
return numeral(num).format(format) + postfix;
|
||||
|
|
|
@ -1,48 +1,39 @@
|
|||
<div class="container">
|
||||
<div class="container state_default state_{{ui.serverState}}">
|
||||
<header>
|
||||
<h1>
|
||||
<strong>Kibana</strong> Status Page
|
||||
Status: <span class="state_color">{{ ui.serverStateMessage }}</span>
|
||||
<i class="fa state_color state_icon" />
|
||||
</h1>
|
||||
</header>
|
||||
|
||||
<section class="section">
|
||||
<h4>What is this page?</h4>
|
||||
<p>This page is your sanity check, and your savior. You can check for potential problems</p>
|
||||
<p>Here is the status of your kibana instance and the plugins you have installed along with some, statistics to asses potential problems.</p>
|
||||
</section>
|
||||
|
||||
<div class="system_status_wrapper state_default state_{{ui.serverState}}">
|
||||
|
||||
<h3 class="title">
|
||||
<b>System Status</b> {{ ui.serverStateMessage }}
|
||||
</h3>
|
||||
<div class="row metrics_wrapper">
|
||||
<div ng-repeat="(name, data) in ui.metrics">
|
||||
<status-page-metric name="{{name}}" data="data"></status-page-metric>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row plugin_status_wrapper">
|
||||
<h3>Installed Plugins</h3>
|
||||
<div ng-if="!ui.statuses && ui.loading" class="loading_statuses">
|
||||
<span class="spinner"></span>
|
||||
</div>
|
||||
|
||||
<h4 ng-if="!ui.statuses && !ui.loading" class="missing_statuses">
|
||||
No status information available
|
||||
No plugin status information available
|
||||
</h4>
|
||||
|
||||
<table class="status_breakdown" ng-if="ui.statuses">
|
||||
<table class="plugin_status_breakdown row" ng-if="ui.statuses">
|
||||
<tr>
|
||||
<th class="col-xs-1">Name</th>
|
||||
<th class="col-xs-11">Description</th>
|
||||
<th class="col-xs-11">Status</th>
|
||||
</tr>
|
||||
<tr ng-repeat="status in ui.statuses" class="status_row state_default state_{{status.state}}">
|
||||
<tr ng-repeat="status in ui.statuses" class="status_row plugin_state_default plugin_state_{{status.state}}">
|
||||
<td class="col-xs-1 status_name">{{status.name}}</td>
|
||||
<td class="col-xs-11 status_message">{{status.message}}</td>
|
||||
<td class="col-xs-11 status_message">
|
||||
<i class="fa plugin_state_color plugin_state_icon" />
|
||||
{{status.message}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<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="(name, data) in ui.metrics">
|
||||
<status-page-metric name="{{name}}" data="data"></status-page-metric>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,8 @@ require('ui/chrome')
|
|||
.setTabs([
|
||||
{
|
||||
id: '',
|
||||
title: 'Server Status'
|
||||
title: 'Server Status',
|
||||
activeIndicatorColor: '#EFF0F2'
|
||||
}
|
||||
])
|
||||
.setRootTemplate(require('plugins/statusPage/statusPage.html'))
|
||||
|
@ -24,6 +25,7 @@ require('ui/chrome')
|
|||
return $http
|
||||
.get('/api/status')
|
||||
.then(function (resp) {
|
||||
|
||||
if (ui.fetchError) {
|
||||
ui.fetchError.clear();
|
||||
ui.fetchError = null;
|
||||
|
@ -36,7 +38,7 @@ require('ui/chrome')
|
|||
var overall = data.status.overall;
|
||||
if (!ui.serverState || (ui.serverState !== overall.state)) {
|
||||
ui.serverState = overall.state;
|
||||
ui.serverStateMessage = overall.nickname || overall.title;
|
||||
ui.serverStateMessage = overall.title;
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
|
@ -50,9 +52,4 @@ require('ui/chrome')
|
|||
};
|
||||
|
||||
ui.refresh();
|
||||
|
||||
// let the browser decide when to slow down requests
|
||||
setInterval(function () {
|
||||
$scope.$eval(ui.refresh);
|
||||
}, 5000);
|
||||
});
|
||||
|
|
|
@ -1,126 +1,178 @@
|
|||
@import "~font-awesome/less/font-awesome";
|
||||
|
||||
@status-bg: #eff0f2;
|
||||
@status-metric-bg: #fff;
|
||||
@status-metric-border: #aaa;
|
||||
@status-metric-title-color: #666;
|
||||
|
||||
@status-plugins-bg: #fff;
|
||||
@status-plugins-border: #bbb;
|
||||
@status-plugins-headings-color: #666;
|
||||
|
||||
@status-default: #7c7c7c;
|
||||
@status-green: #94c63d;
|
||||
@status-yellow: #edb800;
|
||||
@status-red: #da1e04;
|
||||
|
||||
@icon-default: @fa-var-clock-o;
|
||||
@icon-green: @fa-var-check;
|
||||
@icon-yellow: @fa-var-exclamation-circle;
|
||||
@icon-red: @fa-var-exclamation-triangle;
|
||||
|
||||
// background of main page
|
||||
.content {
|
||||
background-color: @status-bg;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom:15px;
|
||||
}
|
||||
|
||||
.status_breakdown {
|
||||
margin:0 15px 15px 15px;
|
||||
// metrics section
|
||||
.metrics_wrapper {
|
||||
margin-top: 25px;
|
||||
.status_metric_wrapper {
|
||||
padding: 10px;
|
||||
border: 0;
|
||||
|
||||
.status_row {
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
+ .status_row {
|
||||
border-top:1px solid #ebebeb;
|
||||
.content {
|
||||
text-align: right;
|
||||
padding: 15px;
|
||||
padding-right: 20px;
|
||||
background-color: @status-metric-bg;
|
||||
border-top: 2px solid;
|
||||
border-top-color: @status-metric-border;
|
||||
|
||||
.title {
|
||||
color: @status-metric-title-color;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.average {
|
||||
font-size: 42px;
|
||||
line-height:45px;
|
||||
font-weight: normal;
|
||||
margin:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
font-size:10px;
|
||||
color:#a9a9a9;
|
||||
height:25px;
|
||||
line-height:25px;
|
||||
}
|
||||
|
||||
.status_name {
|
||||
font-weight:bold;
|
||||
padding:0px 5px;
|
||||
}
|
||||
|
||||
.status_message {
|
||||
border-left:1px solid #ebebeb;
|
||||
padding:0;
|
||||
padding-left:15px;
|
||||
}
|
||||
}
|
||||
|
||||
.system_status_wrapper {
|
||||
// plugin status table section
|
||||
.plugin_status_wrapper {
|
||||
margin-top: 25px;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
border-top:2px solid;
|
||||
background-color: @status-plugins-bg;
|
||||
padding: 10px;
|
||||
|
||||
h3 {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.missing_statuses,
|
||||
.loading_statuses {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.status_chart_wrapper {
|
||||
border-top:1px solid #ebebeb;
|
||||
border-left:1px solid #ebebeb;
|
||||
.average {
|
||||
font-size: 42px;
|
||||
line-height:45px;
|
||||
margin-top:0;
|
||||
font-weight:bold;
|
||||
}
|
||||
.title {
|
||||
margin:0 0 5px 0;
|
||||
text-transform:capitalize;
|
||||
}
|
||||
}
|
||||
.plugin_status_breakdown {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
|
||||
#chart_cont {
|
||||
margin-top:35px;
|
||||
}
|
||||
.status_row {
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
border-bottom:1px solid;
|
||||
border-bottom-color: @status-plugins-border;
|
||||
}
|
||||
|
||||
.status_chart_wrapper:nth-child(2), .status_chart_wrapper:nth-child(3) {
|
||||
border-top:0 none transparent;
|
||||
}
|
||||
th {
|
||||
color:@status-plugins-headings-color;
|
||||
font-weight: normal;
|
||||
height:25px;
|
||||
line-height:25px;
|
||||
border-bottom:1px solid;
|
||||
border-bottom-color: @status-plugins-border;
|
||||
}
|
||||
|
||||
.status_chart_wrapper:first-child {
|
||||
border-top:0 none transparent;
|
||||
border-left:0 none transparent;
|
||||
}
|
||||
.status_name {
|
||||
padding:0px 5px;
|
||||
border-left: 2px solid;
|
||||
}
|
||||
|
||||
.status_chart_wrapper:nth-child(3n + 1) {
|
||||
border-left:0 none transparent;
|
||||
}
|
||||
|
||||
.status_chart_wrapper:nth-child(n + 4) {
|
||||
padding-top:20px;
|
||||
}
|
||||
|
||||
.nv-axis.nv-x .tick line {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.state(@primary, @secondary) {
|
||||
&.system_status_wrapper {
|
||||
border:1px solid @primary;
|
||||
border-radius:5px;
|
||||
overflow: hidden;
|
||||
|
||||
.title {
|
||||
color:#ffffff;
|
||||
height:50px;
|
||||
line-height:50px;
|
||||
margin:0 0 10px 0;
|
||||
padding:0 15px;
|
||||
border-color:@primary;
|
||||
background:@primary;
|
||||
background:-moz-linear-gradient(left,@primary 0%,@secondary 100%);
|
||||
background:-webkit-gradient(linear,left top,right top,color-stop(0%,@primary),color-stop(100%,@secondary));
|
||||
background:-webkit-linear-gradient(left,@primary 0%,@secondary 100%);
|
||||
background:-o-linear-gradient(left,@primary 0%,@secondary 100%);
|
||||
background:-ms-linear-gradient(left,@primary 0%,@secondary 100%);
|
||||
background:linear-gradient(to right,@primary 0%,@secondary 100%);
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=@primary,endColorstr=@secondary,GradientType=1);
|
||||
.status_message {
|
||||
padding:0;
|
||||
padding-left:15px;
|
||||
border-right: 2px solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.status_row {
|
||||
color: @primary;
|
||||
//plugin state
|
||||
.plugin_state(@color, @icon) {
|
||||
.plugin_state_color {
|
||||
color: @color;
|
||||
}
|
||||
|
||||
.plugin_state_icon:before {
|
||||
content: @icon;
|
||||
}
|
||||
|
||||
.status_name {
|
||||
border-left-color: @color !important;
|
||||
}
|
||||
|
||||
.status_message {
|
||||
border-right-color: @color !important;
|
||||
}
|
||||
}
|
||||
|
||||
.plugin_state_default {
|
||||
.plugin_state(@status-default, @icon-default);
|
||||
}
|
||||
|
||||
.plugin_state_green {
|
||||
.plugin_state(@status-green, @icon-green);
|
||||
}
|
||||
|
||||
.plugin_state_yellow {
|
||||
.plugin_state(@status-yellow, @icon-yellow);
|
||||
}
|
||||
|
||||
.plugin_state_red {
|
||||
.plugin_state(@status-red, @icon-red);
|
||||
}
|
||||
|
||||
//server state
|
||||
.state(@color, @icon) {
|
||||
.state_color {
|
||||
color: @color;
|
||||
}
|
||||
|
||||
.state_icon:before {
|
||||
content: @icon;
|
||||
}
|
||||
|
||||
.plugin_status_wrapper {
|
||||
border-top-color: @color;
|
||||
}
|
||||
}
|
||||
|
||||
.state_default {
|
||||
.state(#7C7C7C, #CFCFCF);
|
||||
.state(@status-default, @icon-default);
|
||||
}
|
||||
|
||||
.state_green {
|
||||
.state(#0a8e03, #96f501);
|
||||
.state(@status-green, @icon-green);
|
||||
}
|
||||
|
||||
.state_yellow {
|
||||
.state(#fdee00, #c16f00);
|
||||
.state(@status-yellow, @icon-yellow);
|
||||
}
|
||||
|
||||
.state_red {
|
||||
.state(#da1e04, #ff730f);
|
||||
.state(@status-red, @icon-red);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<div class="status_chart_wrapper col-md-4">
|
||||
<h3 class="title">{{metric.title}}</h3>
|
||||
<h4 class="average">{{ metric.averages.join(', ') }}</h4>
|
||||
<nvd3 options="metric.chartOptions" data="metric.chartData"></nvd3>
|
||||
<div class="status_metric_wrapper col-md-4">
|
||||
<div class="content">
|
||||
<h3 class="title">{{metric.extendedTitle}}</h3>
|
||||
<h4 class="average">{{ metric.averages.join(', ') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,6 @@ require('angular-nvd3');
|
|||
|
||||
var toTitleCase = require('./lib/toTitleCase');
|
||||
var formatNumber = require('./lib/formatNumber');
|
||||
var getChartOptions = _.memoize(require('./lib/makeChartOptions'));
|
||||
var readStatData = require('./lib/readStatData');
|
||||
|
||||
function calcAvg(metricList, metricNumberType) {
|
||||
|
@ -33,17 +32,16 @@ require('ui/modules')
|
|||
|
||||
self.name = $scope.name;
|
||||
self.title = toTitleCase(self.name);
|
||||
self.extendedTitle = self.title;
|
||||
self.numberType = 'precise';
|
||||
self.seriesNames = [];
|
||||
|
||||
switch (self.name) {
|
||||
case 'heapTotal':
|
||||
case 'heapUsed':
|
||||
case 'rss':
|
||||
self.numberType = 'byte';
|
||||
break;
|
||||
|
||||
case 'delay':
|
||||
case 'responseTimeAvg':
|
||||
case 'responseTimeMax':
|
||||
self.numberType = 'ms';
|
||||
|
@ -54,12 +52,22 @@ require('ui/modules')
|
|||
break;
|
||||
}
|
||||
|
||||
self.chartOptions = getChartOptions(self.numberType);
|
||||
|
||||
$scope.$watch('data', function (data) {
|
||||
self.rawData = data;
|
||||
self.chartData = readStatData(self.rawData, self.seriesNames);
|
||||
self.averages = calcAvg(self.chartData, self.numberType);
|
||||
|
||||
var unit = '';
|
||||
self.averages = self.averages.map(function (average) {
|
||||
var parts = average.split(' ');
|
||||
var value = parts.shift();
|
||||
unit = parts.join(' ');
|
||||
return value;
|
||||
});
|
||||
self.extendedTitle = self.title;
|
||||
if (unit) {
|
||||
self.extendedTitle = `${self.extendedTitle} (${unit})`;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
module.exports = function (kbnServer, server, config) {
|
||||
var _ = require('lodash');
|
||||
var Samples = require('./Samples');
|
||||
var ServerStatus = require('./ServerStatus');
|
||||
var { join } = require('path');
|
||||
|
||||
kbnServer.status = new ServerStatus(kbnServer.server);
|
||||
kbnServer.metrics = new Samples(60);
|
||||
|
||||
if (server.plugins.good) {
|
||||
server.plugins.good.monitor.on('ops', function (event) {
|
||||
var port = config.get('server.port');
|
||||
kbnServer.metrics.add({
|
||||
rss: event.psmem.rss,
|
||||
heapTotal: event.psmem.heapTotal,
|
||||
heapUsed: event.psmem.heapUsed,
|
||||
load: event.osload,
|
||||
delay: event.psdelay,
|
||||
concurrency: _.get(event, ['concurrents', port]),
|
||||
responseTimeAvg: _.get(event, ['responseTimes', port, 'avg']),
|
||||
responseTimeMax: _.get(event, ['responseTimes', port, 'max']),
|
||||
requests: _.get(event, ['requests', port, 'total'], 0)
|
||||
});
|
||||
});
|
||||
kbnServer.mixin(require('./metrics'));
|
||||
}
|
||||
|
||||
server.route({
|
||||
|
|
27
src/server/status/metrics.js
Normal file
27
src/server/status/metrics.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
module.exports = function (kbnServer, server, config) {
|
||||
var _ = require('lodash');
|
||||
var Samples = require('./Samples');
|
||||
let lastReport = Date.now();
|
||||
|
||||
kbnServer.metrics = new Samples(12);
|
||||
|
||||
server.plugins.good.monitor.on('ops', function (event) {
|
||||
let now = Date.now();
|
||||
let secSinceLast = (now - lastReport) / 1000;
|
||||
lastReport = now;
|
||||
|
||||
var port = config.get('server.port');
|
||||
let requests = _.get(event, ['requests', port, 'total'], 0);
|
||||
let requestsPerSecond = requests / secSinceLast;
|
||||
|
||||
kbnServer.metrics.add({
|
||||
heapTotal: _.get(event, 'psmem.heapTotal'),
|
||||
heapUsed: _.get(event, 'psmem.heapUsed'),
|
||||
load: event.osload,
|
||||
responseTimeAvg: _.get(event, ['responseTimes', port, 'avg']),
|
||||
responseTimeMax: _.get(event, ['responseTimes', port, 'max']),
|
||||
requestsPerSecond: requestsPerSecond
|
||||
});
|
||||
|
||||
});
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue