mirror of https://github.com/grafana/grafana
commit
b164e5ea79
@ -0,0 +1,17 @@ |
|||||||
|
<div> |
||||||
|
<div class="row-fluid"> |
||||||
|
<div class="span12"> |
||||||
|
The derive queries panel takes a query and a field, then runs a terms facet against both and generates a list of terms to query on. For example, you might want to see a histogram of the top 5 requests that return a 404. <strong>You should be careful not to select a high cardinality field</strong> as Elasticsearch must load all of these values into memory. |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row-fluid"> |
||||||
|
<div class="span3"> |
||||||
|
<label class="small">Length</label> |
||||||
|
<input type="number" style="width:80%" ng-model="panel.size" ng-change="set_refresh(true)"> |
||||||
|
</div> |
||||||
|
<div class="span8"> |
||||||
|
<label class="small">Exclude Terms(s) (comma seperated)</label> |
||||||
|
<input array-join type="text" style="width:90%" ng-change="set_refresh(true)" ng-model='panel.exclude'></input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,32 @@ |
|||||||
|
<kibana-panel ng-controller='derivequeries' ng-init="init()"> |
||||||
|
<span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'> |
||||||
|
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i> |
||||||
|
</span> |
||||||
|
<div ng-show="!panel.multi"> |
||||||
|
<form> |
||||||
|
<table class="form-horizontal"> |
||||||
|
<tr> |
||||||
|
<td><label><small>{{panel.label}}</small></label></td> |
||||||
|
<td><label><small>Field</small></label></td> |
||||||
|
</tr> |
||||||
|
<tr> |
||||||
|
<td width="97%" style="padding-right:20px"> |
||||||
|
<input type="text" style="width:100%" ng-model="panel.query"> |
||||||
|
</td> |
||||||
|
<td ng-show="panel.fields.length > 0"> |
||||||
|
<select class="input-small" ng-model="panel.field" ng-options="f for f in panel.fields"></select> |
||||||
|
</td> |
||||||
|
<td ng-show="panel.fields.length == 0"> |
||||||
|
<input class="input-small" ng-model="panel.field" type="text"/> |
||||||
|
</td> |
||||||
|
<td style="margin-left:20px" width="1%"> |
||||||
|
<button style="margin-top:0px" type="submit" class="btn btn-info" ng-click="get_data()"><i class="icon-search"></i></button> |
||||||
|
</td> |
||||||
|
<td width="1%"> |
||||||
|
<button style="margin-top:0px" type="submit" class="btn btn-danger" ng-click="panel.query='';get_data()"><i class="icon-ban-circle"></i></button> |
||||||
|
</td> |
||||||
|
<tr> |
||||||
|
</table> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</kibana-panel> |
@ -0,0 +1,124 @@ |
|||||||
|
/* |
||||||
|
|
||||||
|
## Termsquery |
||||||
|
|
||||||
|
Broadcasts an array of queries based on the results of a terms facet |
||||||
|
|
||||||
|
### Parameters |
||||||
|
* label :: The label to stick over the field
|
||||||
|
* query :: A string to use as a filter for the terms facet |
||||||
|
* field :: the field to facet on |
||||||
|
* size :: how many queries to generate |
||||||
|
* fields :: a list of fields known to us |
||||||
|
|
||||||
|
### Group Events |
||||||
|
#### Sends |
||||||
|
* query :: Always broadcast as an array, even in multi: false |
||||||
|
* get_time :: Request the time object from the timepicker |
||||||
|
#### Receives |
||||||
|
* query :: An array of queries. This is probably needs to be fixed. |
||||||
|
* time :: populate index and time |
||||||
|
* fields :: A list of fields known to us |
||||||
|
*/ |
||||||
|
|
||||||
|
angular.module('kibana.derivequeries', []) |
||||||
|
.controller('derivequeries', function($scope, eventBus) { |
||||||
|
|
||||||
|
// Set and populate defaults
|
||||||
|
var _d = { |
||||||
|
label : "Search", |
||||||
|
query : "*", |
||||||
|
group : "default", |
||||||
|
field : '_type', |
||||||
|
fields : [], |
||||||
|
spyable : true, |
||||||
|
size : 5, |
||||||
|
exclude : [] |
||||||
|
} |
||||||
|
_.defaults($scope.panel,_d); |
||||||
|
|
||||||
|
$scope.init = function() { |
||||||
|
eventBus.register($scope,'fields', function(event, fields) { |
||||||
|
$scope.panel.fields = fields.all; |
||||||
|
}); |
||||||
|
eventBus.register($scope,'time', function(event,time){set_time(time)}); |
||||||
|
eventBus.register($scope,'query', function(event, query) { |
||||||
|
$scope.panel.query = _.isArray(query) ? query[0] : query; |
||||||
|
$scope.get_data(); |
||||||
|
}); |
||||||
|
// Now that we're all setup, request the time from our group
|
||||||
|
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time') |
||||||
|
} |
||||||
|
|
||||||
|
$scope.get_data = function() { |
||||||
|
// Make sure we have everything for the request to complete
|
||||||
|
if(_.isUndefined($scope.index) || _.isUndefined($scope.time)) |
||||||
|
return |
||||||
|
|
||||||
|
$scope.panel.loading = true; |
||||||
|
var request = $scope.ejs.Request().indices($scope.index); |
||||||
|
|
||||||
|
// Terms mode
|
||||||
|
request = request |
||||||
|
.facet(ejs.TermsFacet('query') |
||||||
|
.field($scope.panel.field) |
||||||
|
.size($scope.panel['size']) |
||||||
|
.exclude($scope.panel.exclude) |
||||||
|
.facetFilter(ejs.QueryFilter( |
||||||
|
ejs.FilteredQuery( |
||||||
|
ejs.QueryStringQuery($scope.panel.query || '*'), |
||||||
|
ejs.RangeFilter($scope.time.field) |
||||||
|
.from($scope.time.from) |
||||||
|
.to($scope.time.to) |
||||||
|
)))).size(0) |
||||||
|
|
||||||
|
$scope.populate_modal(request); |
||||||
|
|
||||||
|
var results = request.doSearch(); |
||||||
|
|
||||||
|
// Populate scope when we have results
|
||||||
|
results.then(function(results) { |
||||||
|
$scope.panel.loading = false; |
||||||
|
var data = []; |
||||||
|
_.each(results.facets.query.terms, function(v) { |
||||||
|
data.push($scope.panel.field+":"+v.term) |
||||||
|
}); |
||||||
|
console.log(data) |
||||||
|
$scope.send_query(data) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.set_refresh = function (state) {
|
||||||
|
$scope.refresh = state;
|
||||||
|
} |
||||||
|
|
||||||
|
$scope.close_edit = function() { |
||||||
|
if($scope.refresh) |
||||||
|
$scope.get_data(); |
||||||
|
$scope.refresh = false; |
||||||
|
} |
||||||
|
|
||||||
|
$scope.populate_modal = function(request) { |
||||||
|
$scope.modal = { |
||||||
|
title: "Inspector", |
||||||
|
body : "<h5>Last Elasticsearch Query</h5><pre>"+ |
||||||
|
'curl -XGET '+config.elasticsearch+'/'+$scope.index+"/_search?pretty -d'\n"+ |
||||||
|
angular.toJson(JSON.parse(request.toString()),true)+ |
||||||
|
"'</pre>",
|
||||||
|
}
|
||||||
|
} |
||||||
|
|
||||||
|
function set_time(time) { |
||||||
|
$scope.time = time; |
||||||
|
$scope.index = _.isUndefined(time.index) ? $scope.index : time.index |
||||||
|
$scope.get_data(); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.send_query = function(query) { |
||||||
|
var _query = _.isArray(query) ? query : [query] |
||||||
|
eventBus.broadcast($scope.$id,$scope.panel.group,'query',_query) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}); |
Loading…
Reference in new issue