Skip to content

Commit

Permalink
Merge pull request elastic#7459 from spalger/implement/pluginSpecific…
Browse files Browse the repository at this point in the history
…Status

[server/status] implement generic status tracking
  • Loading branch information
spalger authored Jun 15, 2016
2 parents dbfee59 + e232e07 commit 7af3e7e
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 104 deletions.
32 changes: 17 additions & 15 deletions src/plugins/status_page/public/status_page.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="container state_default state_{{ui.serverState}}">
<div class="container overall_state_default overall_state_{{ui.serverState}}">
<header>
<h1>
Status: <span class="state_color">{{ ui.serverStateMessage }}</span>
<i class="fa state_color state_icon" />
Status: <span class="overall_state_color">{{ ui.serverStateMessage }}</span>
<i class="fa overall_state_color state_icon" />
<span class="pull-right">
{{ ui.name }}
</span>
Expand All @@ -15,27 +15,29 @@ <h1>
</div>
</div>

<div class="row plugin_status_wrapper">
<h3>Installed Plugins</h3>
<div ng-if="!ui.statuses && ui.loading" class="loading_statuses">
<div class="row statuses_wrapper">
<h3>Status Breakdown</h3>

<div ng-if="!ui.statuses && ui.loading" class="statuses_loading">
<span class="spinner"></span>
</div>

<h4 ng-if="!ui.statuses && !ui.loading" class="missing_statuses">
No plugin status information available
<h4 ng-if="!ui.statuses && !ui.loading" class="statuses_missing">
No status information available
</h4>

<table class="plugin_status_breakdown" ng-if="ui.statuses">
<table class="statuses" data-test-subj="statusBreakdown" ng-if="ui.statuses">
<tr class="row">
<th class="col-xs-2">Name</th>
<th class="col-xs-2">Version</th>
<th class="col-xs-4">ID</th>
<th class="col-xs-8">Status</th>
</tr>
<tr ng-repeat="status in ui.statuses" class="status_row plugin_state_default plugin_state_{{status.state}} row">
<td class="col-xs-2 status_name">{{status.name}}</td>
<td class="col-xs-2 status_version">{{status.version}}</td>
<tr
ng-repeat="status in ui.statuses"
class="status status_state_default status_state_{{status.state}} row">

<td class="col-xs-4 status_id">{{status.id}}</td>
<td class="col-xs-8 status_message">
<i class="fa plugin_state_color plugin_state_icon" />
<i class="fa status_state_color status_state_icon" />
{{status.message}}
</td>
</tr>
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/status_page/public/status_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const chrome = require('ui/chrome')

const data = resp.data;
ui.metrics = data.metrics;
ui.statuses = data.status.statuses;
ui.name = data.name;

ui.statuses = data.status.statuses;

const overall = data.status.overall;
if (!ui.serverState || (ui.serverState !== overall.state)) {
ui.serverState = overall.state;
Expand Down
69 changes: 35 additions & 34 deletions src/plugins/status_page/public/status_page.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
@status-metric-border: #aaa;
@status-metric-title-color: #666;

@status-plugins-bg: #fff;
@status-plugins-border: #bbb;
@status-plugins-headings-color: #666;
@status-statuses-bg: #fff;
@status-statuses-border: #bbb;
@status-statuses-headings-color: #666;

@status-default: #7c7c7c;
@status-green: #94c63d;
Expand Down Expand Up @@ -58,47 +58,48 @@
}
}

// plugin status table section
.plugin_status_wrapper {
// status status table section
.statuses_wrapper {
margin-top: 25px;
margin-left: -5px;
margin-right: -5px;
border-top:2px solid;
background-color: @status-plugins-bg;
background-color: @status-statuses-bg;
padding: 10px;

h3 {
margin-top: 3px;
margin-bottom: 3px;
}

.missing_statuses,
.loading_statuses {
.statuses_loading,
.statuses_missing {
padding: 20px;
text-align: center;
}

.plugin_status_breakdown {
.statuses {
margin-left: 0;
margin-right: 0;
margin-bottom: 30px;

.status_row {
.status {
height:30px;
line-height:30px;
border-bottom:1px solid;
border-bottom-color: @status-plugins-border;
border-bottom-color: @status-statuses-border;
}

th {
color:@status-plugins-headings-color;
color:@status-statuses-headings-color;
font-weight: normal;
height:25px;
line-height:25px;
border-bottom:1px solid;
border-bottom-color: @status-plugins-border;
border-bottom-color: @status-statuses-border;
}

.status_name {
.status_id {
padding:0px 5px;
border-left: 2px solid;
}
Expand All @@ -111,17 +112,17 @@
}
}

//plugin state
.plugin_state(@color, @icon) {
.plugin_state_color {
//status state
.status_state(@color, @icon) {
.status_state_color {
color: @color;
}

.plugin_state_icon:before {
.status_state_icon:before {
content: @icon;
}

.status_name {
.status_id {
border-left-color: @color !important;
}

Expand All @@ -130,49 +131,49 @@
}
}

.plugin_state_default {
.plugin_state(@status-default, @icon-default);
.status_state_default {
.status_state(@status-default, @icon-default);
}

.plugin_state_green {
.plugin_state(@status-green, @icon-green);
.status_state_green {
.status_state(@status-green, @icon-green);
}

.plugin_state_yellow {
.plugin_state(@status-yellow, @icon-yellow);
.status_state_yellow {
.status_state(@status-yellow, @icon-yellow);
}

.plugin_state_red {
.plugin_state(@status-red, @icon-red);
.status_state_red {
.status_state(@status-red, @icon-red);
}

//server state
.state(@color, @icon) {
.state_color {
.overall_state_color {
color: @color;
}

.state_icon:before {
.overall_state_icon:before {
content: @icon;
}

.plugin_status_wrapper {
.statuses_wrapper {
border-top-color: @color;
}
}

.state_default {
.overall_state_default {
.state(@status-default, @icon-default);
}

.state_green {
.overall_state_green {
.state(@status-green, @icon-green);
}

.state_yellow {
.overall_state_yellow {
.state(@status-yellow, @icon-yellow);
}

.state_red {
.overall_state_red {
.state(@status-red, @icon-red);
}
2 changes: 1 addition & 1 deletion src/server/plugins/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ module.exports = class Plugin {
server.exposeStaticDir(`/plugins/${id}/{path*}`, this.publicDir);
}

this.status = kbnServer.status.create(this);
this.status = kbnServer.status.createForPlugin(this);
server.expose('status', this.status);

return await attempt(this.externalInit, [server, options], this);
Expand Down
85 changes: 58 additions & 27 deletions src/server/status/__tests__/server_status.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import _ from 'lodash';
import { find } from 'lodash';
import expect from 'expect.js';
import sinon from 'sinon';

Expand All @@ -17,31 +17,63 @@ describe('ServerStatus class', function () {
serverStatus = new ServerStatus(server);
});

describe('#create(plugin)', function () {
describe('#create(id)', () => {
it('should create a new plugin with an id', () => {
const status = serverStatus.create('someid');
expect(status).to.be.a(Status);
});
});

describe('#createForPlugin(plugin)', function () {
it('should create a new status by plugin', function () {
let status = serverStatus.create(plugin);
let status = serverStatus.createForPlugin(plugin);
expect(status).to.be.a(Status);
});
});

describe('#get(name)', function () {
it('exposes plugins by its id/name', function () {
let status = serverStatus.create(plugin);
expect(serverStatus.get('name')).to.be(status);
describe('#get(id)', () => {
it('exposes statuses by their id', () => {
const status = serverStatus.create('statusid');
expect(serverStatus.get('statusid')).to.be(status);
});

it('does not get the status for a plugin', () => {
serverStatus.createForPlugin(plugin);
expect(serverStatus.get(plugin)).to.be(undefined);
});
});

describe('#getForPluginId(plugin)', function () {
it('exposes plugin status for the plugin', function () {
let status = serverStatus.createForPlugin(plugin);
expect(serverStatus.getForPluginId(plugin.id)).to.be(status);
});

it('does not get plain statuses by their id', function () {
serverStatus.create('someid');
expect(serverStatus.getForPluginId('someid')).to.be(undefined);
});
});

describe('#getState(id)', function () {
it('should expose the state of a status by id', function () {
let status = serverStatus.create('someid');
status.green();
expect(serverStatus.getState('someid')).to.be('green');
});
});

describe('#getState(name)', function () {
it('should expose the state of the plugin by name', function () {
let status = serverStatus.create(plugin);
describe('#getStateForPluginId(plugin)', function () {
it('should expose the state of a plugin by id', function () {
let status = serverStatus.createForPlugin(plugin);
status.green();
expect(serverStatus.getState('name')).to.be('green');
expect(serverStatus.getStateForPluginId(plugin.id)).to.be('green');
});
});

describe('#overall()', function () {
it('considers each status to produce a summary', function () {
let status = serverStatus.create(plugin);
let status = serverStatus.createForPlugin(plugin);

expect(serverStatus.overall().state).to.be('uninitialized');

Expand Down Expand Up @@ -69,25 +101,24 @@ describe('ServerStatus class', function () {
it('serializes to overall status and individuals', function () {
const pluginOne = {id: 'one', version: '1.0.0'};
const pluginTwo = {id: 'two', version: '2.0.0'};
const pluginThree = {id: 'three', version: '3.0.0'};

let one = serverStatus.create(pluginOne);
let two = serverStatus.create(pluginTwo);
let three = serverStatus.create(pluginThree);
let service = serverStatus.create('some service');
let p1 = serverStatus.createForPlugin(pluginOne);
let p2 = serverStatus.createForPlugin(pluginTwo);

one.green();
two.yellow();
three.red();
service.green();
p1.yellow();
p2.red();

let obj = JSON.parse(JSON.stringify(serverStatus));
expect(obj).to.have.property('overall');
expect(obj.overall.state).to.eql(serverStatus.overall().state);
expect(obj.statuses).to.have.length(3);
let json = JSON.parse(JSON.stringify(serverStatus));
expect(json).to.have.property('overall');
expect(json.overall.state).to.eql(serverStatus.overall().state);
expect(json.statuses).to.have.length(3);

let outs = _.indexBy(obj.statuses, 'name');
expect(outs.one).to.have.property('state', 'green');
expect(outs.two).to.have.property('state', 'yellow');
expect(outs.three).to.have.property('state', 'red');
const out = status => find(json.statuses, { id: status.id });
expect(out(service)).to.have.property('state', 'green');
expect(out(p1)).to.have.property('state', 'yellow');
expect(out(p2)).to.have.property('state', 'red');
});
});

Expand Down
Loading

0 comments on commit 7af3e7e

Please sign in to comment.