Commit 2c5eb8bf by Rashid Khan

Updated default dashboard, added filtering panel

parent de8f8c58
...@@ -284,7 +284,7 @@ function flatten_json(object,root,array) { ...@@ -284,7 +284,7 @@ function flatten_json(object,root,array) {
} else if(obj.length === 1 && _.isNumber(obj[0])) { } else if(obj.length === 1 && _.isNumber(obj[0])) {
array[rootname] = parseFloat(obj[0]); array[rootname] = parseFloat(obj[0]);
} else { } else {
array[rootname] = typeof obj === 'undefined' ? null : obj.join(','); array[rootname] = typeof obj === 'undefined' ? null : obj;
} }
} else { } else {
flatten_json(obj,rootname,array) flatten_json(obj,rootname,array)
......
...@@ -20,7 +20,7 @@ var config = new Settings( ...@@ -20,7 +20,7 @@ var config = new Settings(
elasticsearch: "http://"+window.location.hostname+":9200", elasticsearch: "http://"+window.location.hostname+":9200",
// elasticsearch: 'http://localhost:9200', // elasticsearch: 'http://localhost:9200',
kibana_index: "kibana-int", kibana_index: "kibana-int",
modules: ['histogram','map','pie','table', modules: ['histogram','map','pie','table','filtering',
'timepicker','text','fields','hits','dashcontrol', 'timepicker','text','fields','hits','dashcontrol',
'column','derivequeries','trends','bettermap','query'], 'column','derivequeries','trends','bettermap','query'],
} }
......
{ {
"title": "Logstash Search", "title": "Logstash Search",
"services": {}, "services": {
"query": {
"idQueue": [],
"list": {
"0": {
"query": "*",
"alias": "",
"color": "#7EB26D",
"id": 0
}
},
"ids": [
0
]
},
"filter": {
"idQueue": [],
"list": {
"0": {
"from": "2013-07-15T03:54:27.219Z",
"to": "2013-07-15T04:09:27.219Z",
"field": "@timestamp",
"type": "time",
"mandate": "must",
"alias": "",
"id": 0
}
},
"ids": [
0
]
}
},
"rows": [ "rows": [
{ {
"title": "Options", "title": "Options",
...@@ -11,13 +43,14 @@ ...@@ -11,13 +43,14 @@
"panels": [ "panels": [
{ {
"loading": false, "loading": false,
"error": false, "error": "",
"span": 5, "span": 5,
"editable": true, "editable": true,
"group": [ "group": [
"default" "default"
], ],
"type": "timepicker", "type": "timepicker",
"status": "Stable",
"mode": "relative", "mode": "relative",
"time_options": [ "time_options": [
"5m", "5m",
...@@ -27,18 +60,18 @@ ...@@ -27,18 +60,18 @@
"12h", "12h",
"24h", "24h",
"2d", "2d",
"5d" "7d",
"30d"
], ],
"timespan": "6h", "timespan": "15m",
"timefield": "@timestamp", "timefield": "@timestamp",
"index": "[logstash-]YYYY.MM.DD", "timeformat": "",
"defaultindex": "NOINDEX",
"index_interval": "day",
"refresh": { "refresh": {
"enable": false, "enable": false,
"interval": 30, "interval": 30,
"min": 3 "min": 3
} },
"filter_id": 0
}, },
{ {
"loading": false, "loading": false,
...@@ -49,6 +82,7 @@ ...@@ -49,6 +82,7 @@
"default" "default"
], ],
"type": "dashcontrol", "type": "dashcontrol",
"status": "Stable",
"save": { "save": {
"gist": false, "gist": false,
"elasticsearch": true, "elasticsearch": true,
...@@ -62,7 +96,6 @@ ...@@ -62,7 +96,6 @@
}, },
"hide_control": false, "hide_control": false,
"elasticsearch_size": 20, "elasticsearch_size": 20,
"elasticsearch_saveto": "kibana-int",
"temp": true, "temp": true,
"temp_ttl": "30d" "temp_ttl": "30d"
} }
...@@ -83,16 +116,12 @@ ...@@ -83,16 +116,12 @@
"group": [ "group": [
"default" "default"
], ],
"type": "stringquery", "type": "query",
"status": "Experimental",
"label": "Search", "label": "Search",
"query": "*", "query": "*",
"size": 100, "history": [],
"sort": [ "remember": 10
"_score",
"desc"
],
"multi": false,
"multi_arrange": "horizontal"
} }
] ]
}, },
...@@ -105,61 +134,77 @@ ...@@ -105,61 +134,77 @@
"panels": [ "panels": [
{ {
"loading": false, "loading": false,
"span": 12, "span": 9,
"editable": true, "editable": true,
"group": [ "group": [
"default" "default"
], ],
"type": "histogram", "type": "histogram",
"status": "Stable",
"query": [ "query": [
{ {
"query": "*", "query": "*",
"label": "*" "label": "Query"
} }
], ],
"interval": "5m", "mode": "count",
"show": [ "time_field": "@timestamp",
"points", "value_field": null,
"lines", "auto_int": true,
"legend", "resolution": 100,
"x-axis", "interval": "10s",
"y-axis" "fill": 3,
], "linewidth": 3,
"timezone": "browser", "timezone": "browser",
"spyable": true, "spyable": true,
"zoomlinks": true, "zoomlinks": true,
"fill": 0,
"linewidth": 2,
"bars": true, "bars": true,
"stack": true, "stack": true,
"points": false, "points": false,
"lines": false, "lines": false,
"legend": true, "legend": true,
"x-axis": true, "x-axis": true,
"y-axis": true "y-axis": true,
"percentage": false,
"interactive": true
}, },
{ {
"loading": false, "loading": false,
"span": 0, "error": false,
"span": 3,
"editable": true, "editable": true,
"group": [ "group": [
"default" "default"
], ],
"type": "hits", "type": "filtering",
"status": "Stable",
"query": [ "query": [
{ {
"query": "*", "query": "*",
"label": "*" "label": "Query"
} }
], ],
"style": { "mode": "count",
"font-size": "9pt" "time_field": "@timestamp",
}, "value_field": null,
"aggregate": false, "auto_int": true,
"arrangement": "horizontal", "resolution": 100,
"chart": true, "interval": "5m",
"counters": true, "fill": 3,
"count_pos": "above" "linewidth": 3,
"timezone": "browser",
"spyable": true,
"zoomlinks": true,
"bars": true,
"stack": true,
"points": false,
"lines": false,
"legend": true,
"x-axis": true,
"y-axis": true,
"percentage": false,
"interactive": true,
"title": "Filters"
} }
] ]
}, },
...@@ -179,6 +224,7 @@ ...@@ -179,6 +224,7 @@
"default" "default"
], ],
"type": "fields", "type": "fields",
"status": "Beta",
"style": {}, "style": {},
"arrange": "vertical", "arrange": "vertical",
"micropanel_position": "right", "micropanel_position": "right",
...@@ -197,21 +243,10 @@ ...@@ -197,21 +243,10 @@
"default" "default"
], ],
"type": "table", "type": "table",
"status": "Stable",
"query": "*", "query": "*",
"interval": "1y", "size": 100,
"show": [ "pages": 5,
"bars",
"y-axis",
"x-axis",
"legend"
],
"fill": 3,
"overflow": "min-height",
"timezone": "browser",
"spyable": true,
"zoomlinks": true,
"size": 50,
"pages": 10,
"offset": 0, "offset": 0,
"sort": [ "sort": [
"@timestamp", "@timestamp",
...@@ -220,14 +255,24 @@ ...@@ -220,14 +255,24 @@
"style": { "style": {
"font-size": "9pt" "font-size": "9pt"
}, },
"overflow": "min-height",
"fields": [ "fields": [
"@timestamp", "@timestamp",
"@message" "@message"
], ],
"sortable": true "highlight": [],
"sortable": true,
"header": true,
"paging": true,
"spyable": true
} }
] ]
} }
], ],
"editable": true "editable": true,
} "index": {
"interval": "day",
"pattern": "[logstash-]YYYY.MM.DD",
"default": "MISSING_INDEX"
}
}
\ No newline at end of file
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<div class="navbar navbar-static-top"> <div class="navbar navbar-static-top">
<div class="navbar-inner"> <div class="navbar-inner">
<div class="container-fluid"> <div class="container-fluid">
<p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone 2</small></small></p> <p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone pre-3</small></small></p>
<span class="brand">{{dashboard.current.title}}</span> <span class="brand">{{dashboard.current.title}}</span>
<div class="brand"><i class='icon-cog pointer' ng-show='dashboard.current.editable' bs-modal="'partials/dasheditor.html'"></i></div> <div class="brand"><i class='icon-cog pointer' ng-show='dashboard.current.editable' bs-modal="'partials/dasheditor.html'"></i></div>
</div> </div>
......
...@@ -361,7 +361,6 @@ angular.module('kibana.services', []) ...@@ -361,7 +361,6 @@ angular.module('kibana.services', [])
.to(filter.to) .to(filter.to)
break; break;
case 'querystring': case 'querystring':
console.log(filter.query)
return ejs.QueryFilter(ejs.QueryStringQuery(filter.query)) return ejs.QueryFilter(ejs.QueryStringQuery(filter.query))
break; break;
case 'terms': case 'terms':
...@@ -499,7 +498,7 @@ angular.module('kibana.services', []) ...@@ -499,7 +498,7 @@ angular.module('kibana.services', [])
self.dash_load(dashboard) self.dash_load(dashboard)
// No? Ok, grab default.json, its all we have now // No? Ok, grab default.json, its all we have now
} else { } else {
self.file_load('default') self.file_load('default.json')
} }
} }
} }
...@@ -524,6 +523,7 @@ angular.module('kibana.services', []) ...@@ -524,6 +523,7 @@ angular.module('kibana.services', [])
// This is not optimal, we should be getting the entire index list here, or at least every // This is not optimal, we should be getting the entire index list here, or at least every
// index that possibly matches the pattern // index that possibly matches the pattern
self.indices = [self.current.index.default] self.indices = [self.current.index.default]
$rootScope.$broadcast('refresh')
} }
} else { } else {
self.indices = [self.current.index.pattern] self.indices = [self.current.index.pattern]
...@@ -700,6 +700,7 @@ angular.module('kibana.services', []) ...@@ -700,6 +700,7 @@ angular.module('kibana.services', [])
} }
this.dash_load = function(dashboard) { this.dash_load = function(dashboard) {
timer.cancel_all();
if(dashboard.index.interval === 'none') { if(dashboard.index.interval === 'none') {
self.indices = [dashboard.index.pattern] self.indices = [dashboard.index.pattern]
...@@ -707,8 +708,6 @@ angular.module('kibana.services', []) ...@@ -707,8 +708,6 @@ angular.module('kibana.services', [])
self.current = dashboard; self.current = dashboard;
timer.cancel_all();
// Ok, now that we've setup the current dashboard, we can inject our services // Ok, now that we've setup the current dashboard, we can inject our services
query = $injector.get('query'); query = $injector.get('query');
filterSrv = $injector.get('filterSrv') filterSrv = $injector.get('filterSrv')
......
<a class="close" ng-click="dismiss()" href="">×</a> <a class="close" ng-click="dismiss()" href="">×</a>
<h4> <h4>
Micro Analysis of {{micropanel.field}} Micro Analysis of {{micropanel.field}}
<i class="pointer icon-search" ng-click="fieldExists(micropanel.field,'exists');dismiss();"></i> <i class="pointer icon-search" ng-click="fieldExists(micropanel.field,'must');dismiss();"></i>
<i class="pointer icon-ban-circle" ng-click="fieldExists(micropanel.field,'missing');dismiss();"></i> <i class="pointer icon-ban-circle" ng-click="fieldExists(micropanel.field,'mustNot');dismiss();"></i>
<br><small>{{micropanel.count}} events in the table set</small> <br><small>{{micropanel.count}} events in the table set</small>
</h4> </h4>
<table style="width:480px" class='table table-bordered table-striped table-condensed'> <table style="width:480px" class='table table-bordered table-striped table-condensed'>
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
<tr ng-repeat='field in micropanel.values'> <tr ng-repeat='field in micropanel.values'>
<td>{{{true: "__blank__",false:field[0]}[field[0] == ""]}}</td> <td>{{{true: "__blank__",false:field[0]}[field[0] == ""]}}</td>
<td> <td>
<i class="pointer icon-search" ng-click="build_search(micropanel.field,field[0]);dismiss();"></i> <i class="pointer icon-search" ng-click="build_search(micropanel.field,field[0],'must');dismiss();"></i>
<i class="pointer icon-ban-circle" ng-click="build_search(micropanel.field,field[0],true);dismiss();"></i> <i class="pointer icon-ban-circle" ng-click="build_search(micropanel.field,field[0],'mustNot');dismiss();"></i>
</td> </td>
<td>{{field[1]}}</td> <td>{{field[1]}}</td>
</tr> </tr>
......
...@@ -79,14 +79,15 @@ angular.module('kibana.fields', []) ...@@ -79,14 +79,15 @@ angular.module('kibana.fields', [])
eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active) eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active)
} }
$scope.build_search = function(field,value,negate) { $scope.build_search = function(field,value,mandate) {
var query = (negate ? '-':'+')+field+":\""+value+"\"" var query = field+":"+angular.toJson(value)
filterSrv.set({type:'querystring',query:query})
filterSrv.set({type:'querystring',query:query,mandate:mandate})
dashboard.refresh(); dashboard.refresh();
} }
$scope.fieldExists = function(field,mode) { $scope.fieldExists = function(field,mandate) {
filterSrv.set({type:mode,field:field}) filterSrv.set({type:'exists',field:field,mandate:mandate})
dashboard.refresh(); dashboard.refresh();
} }
......
<div>
<div class="row-fluid">
<div class="span12">
No options here
</div>
</div>
</div>
\ No newline at end of file
<div>
<style>
.input-query-alias {
margin-bottom: 5px !important;
}
</style>
<a class="close" ng-click="render();dismiss();" href="">×</a>
<h6>Query Alias</h6>
<form>
<input class="input-medium input-query-alias" type="text" ng-model="queries.list[id].alias" placeholder='Alias...' />
<div>
<i ng-repeat="color in queries.colors" class="pointer" ng-class="{'icon-circle-blank':queries.list[id].color == color,'icon-circle':queries.list[id].color != color}" style="color:{{color}}" ng-click="queries.list[id].color = color;render();"> </i>
</div>
</form>
</div>
\ No newline at end of file
<kibana-panel ng-controller='filtering' ng-init="init()">
<style>
.filter-panel-filter {
display:inline-block;
margin-left: 10px;
width: 200px;
padding: 5px;
border: #555 1px solid;
margin: 0px 5px 5px 0px;
}
.filter-must {
border-bottom: #7EB26D 3px solid;
}
.filter-mustNot {
border-bottom: #E24D42 3px solid;
}
.filter-should {
border-bottom: #EF843C 3px solid;
}
.filter-remove {
float:right;
margin-bottom: 0px !important;
}
</style>
<div ng-repeat="id in filterSrv.ids" class="small filter-panel-filter">
<div class="filter-{{filterSrv.list[id].mandate}}">
{{filterSrv.list[id].type}} ({{filterSrv.list[id].mandate}})
<i class="filter-remove pointer icon-remove" ng-click="remove(id)"></i>
</div>
<ul class="unstyled">
<li ng-repeat="(key,value) in stripped(filterSrv.list[id])"><strong>{{key}}</strong> : {{value}}</li>
</ul>
</div>
</kibana-panel>
\ No newline at end of file
/*
## filtering
An experimental for interacting with the filter service
### Parameters
*/
angular.module('kibana.filtering', [])
.controller('filtering', function($scope, filterSrv, $rootScope, dashboard) {
// Set and populate defaults
var _d = {
status : "Experimental"
}
_.defaults($scope.panel,_d);
$scope.init = function() {
$scope.filterSrv = filterSrv
}
$scope.remove = function(id) {
filterSrv.remove(id);
dashboard.refresh();
}
$scope.refresh = function(query) {
$rootScope.$broadcast('refresh')
}
$scope.render = function(query) {
$rootScope.$broadcast('render')
}
$scope.stripped = function(filter) {
var filter = _.omit(filter,'type','id','alias','mandate')
return filter
}
});
\ No newline at end of file
...@@ -32,12 +32,6 @@ ...@@ -32,12 +32,6 @@
* x-axis :: Show x-axis labels and grid lines * x-axis :: Show x-axis labels and grid lines
* y-axis :: Show y-axis labels and grid lines * y-axis :: Show y-axis labels and grid lines
* interactive :: Allow drag to select time range * interactive :: Allow drag to select time range
### Group Events
#### Receives
* time :: An object containing the time range to use and the index(es) to query
* query :: An Array of queries, even if its only one
#### Sends
* get_time :: On panel initialization get time range to query
*/ */
...@@ -80,6 +74,8 @@ angular.module('kibana.histogram', []) ...@@ -80,6 +74,8 @@ angular.module('kibana.histogram', [])
$scope.get_data(); $scope.get_data();
}) })
$scope.get_data()
} }
$scope.get_data = function(segment,query_id) { $scope.get_data = function(segment,query_id) {
...@@ -157,7 +153,10 @@ angular.module('kibana.histogram', []) ...@@ -157,7 +153,10 @@ angular.module('kibana.histogram', [])
// Null values at each end of the time range ensure we see entire range // Null values at each end of the time range ensure we see entire range
if(_.isUndefined($scope.data[i]) || _segment == 0) { if(_.isUndefined($scope.data[i]) || _segment == 0) {
var data = [[_range.from.getTime(), null],[_range.to.getTime(), null]]; var data = []
if(filterSrv.idsByType('time').length > 0) {
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
}
var hits = 0; var hits = 0;
} else { } else {
var data = $scope.data[i].data var data = $scope.data[i].data
...@@ -236,7 +235,7 @@ angular.module('kibana.histogram', []) ...@@ -236,7 +235,7 @@ angular.module('kibana.histogram', [])
$scope.modal = { $scope.modal = {
title: "Inspector", title: "Inspector",
body : "<h5>Last Elasticsearch Query</h5><pre>"+ body : "<h5>Last Elasticsearch Query</h5><pre>"+
'curl -XGET '+config.elasticsearch+'/'+$scope.index+"/_search?pretty -d'\n"+ 'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
angular.toJson(JSON.parse(request.toString()),true)+ angular.toJson(JSON.parse(request.toString()),true)+
"'</pre>", "'</pre>",
} }
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
<span class="end-query"> <span class="end-query">
<i class="icon-search pointer" ng-click="refresh()" ng-show="$last"></i> <i class="icon-search pointer" ng-click="refresh()" ng-show="$last"></i>
<i class="icon-plus pointer" ng-click="queries.set({})" ng-show="$last"></i> <i class="icon-plus pointer" ng-click="queries.set({})" ng-show="$last"></i>
</span </span>
</form> </form>
</div> </div>
</kibana-panel> </kibana-panel>
\ No newline at end of file
...@@ -55,8 +55,7 @@ angular.module('kibana.table', []) ...@@ -55,8 +55,7 @@ angular.module('kibana.table', [])
$scope.set_listeners($scope.panel.group) $scope.set_listeners($scope.panel.group)
// Now that we're all setup, request the time from our group $scope.get_data();
eventBus.broadcast($scope.$id,$scope.panel.group,"get_time")
} }
$scope.set_listeners = function(group) { $scope.set_listeners = function(group) {
...@@ -108,8 +107,8 @@ angular.module('kibana.table', []) ...@@ -108,8 +107,8 @@ angular.module('kibana.table', [])
} }
$scope.build_search = function(field,value,negate) { $scope.build_search = function(field,value,negate) {
var query = (negate ? '-':'+')+field+":\""+value+"\"" var query = field+":"+angular.toJson(value)
filterSrv.set({type:'querystring',query:query}) filterSrv.set({type:'querystring',query:query,mandate:(negate ? 'mustNot':'must')})
$scope.panel.offset = 0; $scope.panel.offset = 0;
dashboard.refresh(); dashboard.refresh();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment