Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from rashidkpc/master
Browse files Browse the repository at this point in the history
Compare nodes button and scripted dashboard
  • Loading branch information
Rashid Khan committed Nov 6, 2013
2 parents 9680e12 + e33d4bb commit 92a5f9d
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 103 deletions.
149 changes: 149 additions & 0 deletions dashboards/node_stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* global _ */

/*
* Node statistics scripted dashboard
* This script generates a dashboard object that Kibana can load.
*
* Parameters (all optional)
* nodes :: By default, a comma seperated list of queries to run. Default: *
* show :: The names of the rows to expand
* from :: Search this amount of time back, eg 15m, 1h, 2d. Default: 1d
*
*/

'use strict';

// Setup some variables
var dashboard, queries, _d_timespan;

// All url parameters are available via the ARGS object
var ARGS;

// Set a default timespan if one isn't specified
_d_timespan = '1d';

// Intialize a skeleton with nothing but a rows array and service object
dashboard = {
rows : [],
services : {}
};

// Set a title
dashboard.title = 'Node Statistics';

// And the index options
dashboard.failover = false;
dashboard.index = {
default: 'ADD_A_TIME_FILTER',
pattern: '[es_monitor-]YYYY.MM.DD',
interval: 'day'
};

// In this dashboard we let users pass nodes as comma seperated list to the query parameter.
// If nodes are defined, split into a list of query objects, otherwise, show all
// NOTE: ids must be integers, hence the parseInt()s
if(!_.isUndefined(ARGS.nodes)) {
queries = _.object(_.map(ARGS.nodes.split(','), function(v,k) {
return [k,{
query: 'node.transport_address:"'+v+'"',
id: parseInt(k,10),
alias: v
}];
}));
} else {
// No queries passed? Initialize a single query to match everything
queries = {
0: {
query: '*',
id: 0,
}
};
}

var show = ARGS.show.split(',') || [];

// Now populate the query service with our objects
dashboard.services.query = {
list : queries,
ids : _.map(_.keys(queries),function(v){return parseInt(v,10);})
};

// Lets also add a default time filter, the value of which can be specified by the user
dashboard.services.filter = {
list: {
0: {
from: "now-"+(ARGS.from||_d_timespan),
to: "now",
field: "@timestamp",
type: "time",
active: true,
id: 0,
}
},
ids: [0]
};

// Ok, lets make some rows. Since all of our panels are similar, we can abstract this.
// Obviously this is a partial list, feel free to expand on this.
var rows = [
{
name:'OS',
charts: [{
field: 'os.cpu.user',
derivative: false,
},{
field: 'os.mem.used_percent',
derivative: false
},{
field: 'os.swap.used_in_bytes',
derivative: true
}]
},
{
name: 'JVM',
charts: [{
field: 'jvm.gc.collectors.ParNew.collection_time_in_millis',
derivative: true
},{
field: 'jvm.gc.collectors.ParNew.collection_count',
derivative: true
},{
field: 'jvm.gc.collectors.ConcurrentMarkSweep.collection_time_in_millis',
derivative: true
}]
}
];

dashboard.rows = _.map(rows, function(r) {
return {
title: r.name,
height: '150px',
collapse: !_.contains(show,r.name),
panels: _.map(r.charts,function(c) {
// A bunch of histogram panels, with similar defaults
return {
title: c.field,
type: 'histogram',
span: 4,
time_field: '@timestamp',
value_field: c.field,
derivative: c.derivative,
bars: false,
lines: true,
stack: false,
linewidth:2,
mode: 'max', // Pretty sure we want max for all of these? No? Average for some?
zoomlinks: false,
options: false,
legend: false, // Might want to enable this, cleaner without it though
interactive: false // Because the filter pulldown is hidden
};
})
};
});

// No pulldowns shown, and they can't be enabled.
dashboard.pulldowns = [];

// Now return the object and we're good!
return dashboard;
153 changes: 85 additions & 68 deletions panels/nodes_health/module.html
Original file line number Diff line number Diff line change
@@ -1,76 +1,93 @@
<div ng-controller='marvel.nodes_health' ng-init="init()">
<style>
.marvel-table {
vertical-align: middle;
}
.marvel-mean {
font-size: 20pt;
font-weight: 200;
display: inline-block;
vertical-align: middle;
}
.marvel-extended {
display: inline-block;
font-size:9pt;
margin-left: 5px;
vertical-align: middle;
}
.marvel-header .nodes{
font-size: 20pt;
font-weight: bold;
margin-left: 10px;
}
.marvel-nodes-health-chart {
margin-top: 5px;
display: inline-block;
height: 10px;
width: 50px;
}
</style>
<style>
.marvel-table {
vertical-align: middle;
}
.marvel-mean {
font-size: 20pt;
font-weight: 200;
display: inline-block;
vertical-align: middle;
}
.marvel-extended {
display: inline-block;
font-size:9pt;
margin-left: 5px;
vertical-align: middle;
}
.marvel-header {
margin-bottom: 10px;
}
.marvel-header .nodes{
font-size: 20pt;
font-weight: bold;
margin-left: 10px;
}
.marvel-nodes-health-chart {
margin-top: 5px;
display: inline-block;
height: 10px;
width: 50px;
}
</style>

<div class="pull-left marvel-header marvel-table" ng-show="nodes.length > 0">
<span class="nodes">{{nodes.length}} nodes</span> / Last 10m</span>
</div>
<div class="pull-right">
<a href="" ng-class="{strong:!panel.compact}" ng-click="panel.compact=false">Full</a> / <a href="" ng-class="{strong:panel.compact}"
ng-click="panel.compact=true">Compact</a>
</div>
<div class="pull-left marvel-header marvel-table" ng-show="nodes.length > 0">
<span class="nodes">{{nodes.length}} nodes</span> / Last 10m </span>
</div>
<div class="pull-right">
<a href="" ng-class="{strong:!panel.compact}" ng-click="panel.compact=false">Full</a> /
<a href="" ng-class="{strong:panel.compact}" ng-click="panel.compact=true">Compact</a>
</div>

<table class="table table-bordered" ng-if="!panel.compact">
<thead>
<th>node</th>
<th ng-repeat="metric in metrics" ng-class="alertClass(warnLevels['_global_'][metric.name])">{{metric.name}}</th>
</thead>
<tr ng-repeat="node in nodes">
<td>{{node}}</td>
<td ng-repeat="metric in metrics" ng-class="alertClass(warnLevels[node][metric.name])">
<div class="marvel-mean">
{{data[node+"_"+metric.name].mean / metric.scale | number:metric.decimals}}<br>
<table class="table table-bordered" ng-if="!panel.compact">
<thead>
<th>node <a ng-href="{{compareLink()}}" target="_blank" class="btn btn-mini btn-info" ng-disabled="!hasSelected(nodes)" bs-tooltip="compareTip()" data-placement="right">Compare</a></th>
<th ng-repeat="metric in metrics" ng-class="alertClass(warnLevels['_global_'][metric.name])">{{metric.name}}</th>
</thead>
<tr ng-repeat="node in nodes">
<td>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="nodes[$index].selected" ng-checked="nodes[$index].selected">
{{node.name}}
</label>
</div>
</td>
<td ng-repeat="metric in metrics" ng-class="alertClass(warnLevels[node][metric.name])">
<div class="marvel-mean">
{{data[node.name+"_"+metric.name].mean / metric.scale | number:metric.decimals}}<br>

<div class="marvel-nodes-health-chart" series="data[node+'_'+metric.name+'_history']"></div>
</div>
<div class="marvel-extended">
<span>min: {{data[node+"_"+metric.name].min / metric.scale | number:metric.decimals}}</span><br>
<span>max: {{data[node+"_"+metric.name].max / metric.scale | number:metric.decimals}}</span>
<div class="marvel-nodes-health-chart" series="data[node.name+'_'+metric.name+'_history']"></div>
</div>
<div class="marvel-extended">
<span>min: {{data[node.name+"_"+metric.name].min / metric.scale | number:metric.decimals}}</span><br>
<span>max: {{data[node.name+"_"+metric.name].max / metric.scale | number:metric.decimals}}</span>

</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>

<table class="table table-bordered table-condensed marvel-table" ng-if="panel.compact">
<thead>
<th>node</th>
<th ng-repeat="metric in metrics" ng-class="alertClass(warnLevels['_global_'][metric.name])">{{metric.name}}</th>
</thead>
<tr ng-repeat="node in nodes">
<td>{{node}}</td>
<td ng-repeat="metric in metrics" ng-class="alertClass(warnLevels[node][metric.name])">
<div>{{data[node+"_"+metric.name].mean / metric.scale | number:metric.decimals}}
<div class="marvel-nodes-health-chart" series="data[node+'_'+metric.name+'_history']"></div>
</div>
</td>
</tr>
</table>
<table class="table table-bordered table-condensed marvel-table" ng-if="panel.compact">
<thead>
<th>node <a ng-href="{{compareLink()}}" class="btn btn-mini btn-info" ng-disabled="!hasSelected(nodes)" bs-tooltip="compareTip()" data-placement="right">Compare</a></th>
<th ng-repeat="metric in metrics" ng-class="alertClass(warnLevels['_global_'][metric.name])">{{metric.name}}</th>
</thead>
<tr ng-repeat="node in nodes">
<td>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="nodes[$index].selected" ng-checked="nodes[$index].selected">
{{node.name}}
</label>
</div>
</td>
<td ng-repeat="metric in metrics" ng-class="alertClass(warnLevels[node.name][metric.name])">
<div>{{data[node.name+"_"+metric.name].mean / metric.scale | number:metric.decimals}}
<div class="marvel-nodes-health-chart" series="data[node.name+'_'+metric.name+'_history']"></div>
</div>
</td>
</tr>
</table>

</div>
Loading

0 comments on commit 92a5f9d

Please sign in to comment.