Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templated and scriptable dashboard options #463

Merged
merged 4 commits into from
Sep 4, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = function (grunt) {
' Licensed <%= pkg.license %> */\n\n'
},
jshint: {
files: ['Gruntfile.js', 'js/*.js', 'panels/*/*.js' ],
files: ['Gruntfile.js', 'js/*.js', 'panels/*/*.js', 'dashboards/*.js' ],
options: {
jshintrc: '.jshintrc'
}
Expand Down
174 changes: 174 additions & 0 deletions dashboards/logstash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* Complex scripted Logstash dashboard
* This script generates a dashboard object that Kibana can load. It also takes a number of user
* supplied URL parameters, none are required:
*
* index :: Which index to search? If this is specified, interval is set to 'none'
* pattern :: Does nothing if index is specified. Set a timestamped index pattern. Default: [logstash-]YYYY.MM.DD
* interval :: Sets the index interval (eg: day,week,month,year), Default: day
*
* split :: The character to split the queries on Default: ','
* query :: By default, a comma seperated list of queries to run. Default: *
*
* from :: Search this amount of time back, eg 15m, 1h, 2d. Default: 15m
* timefield :: The field containing the time to filter on, Default: @timestamp
*
* fields :: comma seperated list of fields to show in the table
* sort :: comma seperated field to sort on, and direction, eg sort=@timestamp,desc
*
*/

'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 = '1h';

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

// Set a title
dashboard.title = 'Logstash Search';

// Allow the user to set the index, if they dont, fall back to logstash.
if(!_.isUndefined(ARGS.index)) {
dashboard.index = {
default: ARGS.index,
interval: 'none'
};
} else {
// Don't fail to default
dashboard.failover = false;
dashboard.index = {
default: ARGS.index||'ADD_A_TIME_FILTER',
pattern: ARGS.pattern||'[logstash-]YYYY.MM.DD',
interval: ARGS.interval||'day'
};
}

// In this dashboard we let users pass queries as comma seperated list to the query parameter.
// Or they can specify a split character using the split aparameter
// If query is defined, split it into a list of query objects
// NOTE: ids must be integers, hence the parseInt()s
if(!_.isUndefined(ARGS.query)) {
queries = _.object(_.map(ARGS.query.split(ARGS.split||','), function(v,k) {
return [k,{
query: v,
id: parseInt(k,10),
alias: v
}];
}));
} else {
// No queries passed? Initialize a single query to match everything
queries = {
0: {
query: '*',
id: 0
}
};
}

// 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
// This isn't strictly needed, but it gets rid of the info alert about the missing time filter
dashboard.services.filter = {
list: {
0: {
from: kbn.time_ago(ARGS.from||_d_timespan),
to: new Date(),
field: ARGS.timefield||"@timestamp",
type: "time",
active: true,
id: 0
}
},
ids: [0]
};

// Ok, lets make some rows. The Filters row is collapsed by default
dashboard.rows = [
{
title: "Options",
height: "30px"
},
{
title: "Query",
height: "30px"
},
{
title: "Filters",
height: "100px",
collapse: true
},
{
title: "Chart",
height: "300px"
},
{
title: "Events",
height: "400px"
}
];

// Setup some panels. A query panel and a filter panel on the same row
dashboard.rows[0].panels = [
{
type: 'timepicker',
span: 6,
timespan: ARGS.from||_d_timespan
},
{
type: 'dashcontrol',
span: 3
}
];

// Add a filtering panel to the 3rd row
dashboard.rows[1].panels = [
{
type: 'Query'
}
];


// Add a filtering panel to the 3rd row
dashboard.rows[2].panels = [
{
type: 'filtering'
}
];

// And a histogram that allows the user to specify the interval and time field
dashboard.rows[3].panels = [
{
type: 'histogram',
time_field: ARGS.timefield||"@timestamp",
auto_int: true
}
];

// And a table row where you can specify field and sort order
dashboard.rows[4].panels = [
{
type: 'table',
fields: !_.isUndefined(ARGS.fields) ? ARGS.fields.split(',') : ['@timestamp','@message'],
sort: !_.isUndefined(ARGS.sort) ? ARGS.sort.split(',') : [ARGS.timefield||'@timestamp','desc'],
overflow: 'expand'
}
];

// Now return the object and we're good!
return dashboard;
14 changes: 5 additions & 9 deletions dashboards/logstash.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
"services": {
"query": {
"idQueue": [
1,
2,
3,
4
1
],
"list": {
"0": {
"query": "*",
"query": "{{ARGS.query || '*'}}",
"alias": "",
"color": "#7EB26D",
"id": 0
Expand All @@ -22,8 +19,7 @@
},
"filter": {
"idQueue": [
1,
2
1
],
"list": {
"0": {
Expand Down Expand Up @@ -70,7 +66,7 @@
"7d",
"30d"
],
"timespan": "1h",
"timespan": "{{ARGS.from || '1h'}}",
"timefield": "@timestamp",
"timeformat": "",
"refresh": {
Expand Down Expand Up @@ -246,4 +242,4 @@
"pattern": "[logstash-]YYYY.MM.DD",
"default": "NO_TIME_FILTER_OR_INDEX_PATTERN_NOT_MATCHED"
}
}
}
4 changes: 2 additions & 2 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ labjs.wait(function(){
.when('/dashboard', {
templateUrl: 'partials/dashboard.html',
})
.when('/dashboard/:type/:id', {
.when('/dashboard/:kbnType/:kbnId', {
templateUrl: 'partials/dashboard.html',
})
.when('/dashboard/:type/:id/:params', {
.when('/dashboard/:kbnType/:kbnId/:params', {
templateUrl: 'partials/dashboard.html'
})
.otherwise({
Expand Down
Loading