mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(elasticsearch): lots of work on elasticsearch metrics query editor, #1034
This commit is contained in:
parent
7e9f11ea1c
commit
590b155c6c
@ -174,29 +174,41 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
|
||||
|
||||
// This is quite complex
|
||||
// neeed to recurise down the nested buckets to build series
|
||||
ElasticDatasource.prototype._processBuckets = function(buckets, groupByFields, series, level, parentName, parentTime) {
|
||||
ElasticDatasource.prototype._processBuckets = function(buckets, target, series, level, parentName, parentTime) {
|
||||
var points = [];
|
||||
var groupBy = groupByFields[level];
|
||||
var groupBy = target.groupByFields[level];
|
||||
|
||||
for (var i = 0; i < buckets.length; i++) {
|
||||
var bucket = buckets[i];
|
||||
|
||||
if (groupBy) {
|
||||
var seriesName = level > 0 ? bucket.key : '';
|
||||
var seriesName = level > 0 ? parentName + ' ' + bucket.key : parentName;
|
||||
var time = parentTime || bucket.key;
|
||||
this._processBuckets(bucket[groupBy.field].buckets, groupByFields, series, level+1, seriesName, time)
|
||||
this._processBuckets(bucket[groupBy.field].buckets, target, series, level+1, seriesName, time)
|
||||
} else {
|
||||
var seriesName = parentName;
|
||||
|
||||
if (level > 0) {
|
||||
if (seriesName) { seriesName += " "; }
|
||||
seriesName += bucket.key;
|
||||
} else {
|
||||
parentTime = bucket.key;
|
||||
for (var y = 0; y < target.select.length; y++) {
|
||||
var select = target.select[y];
|
||||
var seriesName = parentName;
|
||||
var value;
|
||||
|
||||
if (level > 0) {
|
||||
seriesName += ' ' + bucket.key;
|
||||
} else {
|
||||
parentTime = bucket.key;
|
||||
}
|
||||
|
||||
if (select.field) {
|
||||
seriesName += ' ' + select.field;
|
||||
value = bucket[select.field].value;
|
||||
} else {
|
||||
seriesName += ' count';
|
||||
value = bucket.doc_count;
|
||||
}
|
||||
|
||||
var serie = series[seriesName] = series[seriesName] || {target: seriesName, datapoints: []};
|
||||
serie.datapoints.push([value, parentTime]);
|
||||
}
|
||||
|
||||
var serie = series[seriesName] = series[seriesName] || {target: seriesName, datapoints: []};
|
||||
serie.datapoints.push([bucket.doc_count, parentTime]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -215,7 +227,7 @@ function (angular, _, config, kbn, moment, ElasticQueryBuilder) {
|
||||
var points = [];
|
||||
var querySeries = {}
|
||||
|
||||
this._processBuckets(buckets, target.groupByFields, querySeries, 0);
|
||||
this._processBuckets(buckets, target, querySeries, 0, target.refId);
|
||||
|
||||
_.each(querySeries, function(value) {
|
||||
series.push(value);
|
||||
|
@ -22,7 +22,7 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
var target = $scope.target;
|
||||
target.function = target.function || 'mean';
|
||||
target.timeField = target.timeField || '@timestamp';
|
||||
target.select = target.select || [{ agg: 'Count' }];
|
||||
target.select = target.select || [{ agg: 'count' }];
|
||||
target.groupByFields = target.groupByFields || [];
|
||||
|
||||
$scope.timeSegment = uiSegmentSrv.newSegment(target.timeField);
|
||||
@ -31,8 +31,16 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
return uiSegmentSrv.newSegment(group.field);
|
||||
});
|
||||
|
||||
$scope.initSelectSegments();
|
||||
$scope.groupBySegments.push(uiSegmentSrv.newPlusButton());
|
||||
$scope.removeSelectSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove select --'});
|
||||
$scope.resetSelectSegment = uiSegmentSrv.newSegment({fake: true, value: '-- reset --'});
|
||||
$scope.removeGroupBySegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove group by --'});
|
||||
};
|
||||
|
||||
$scope.initSelectSegments = function() {
|
||||
$scope.selectSegments = [];
|
||||
_.each(target.select, function(select) {
|
||||
_.each($scope.target.select, function(select) {
|
||||
if ($scope.selectSegments.length > 0) {
|
||||
$scope.selectSegments.push(uiSegmentSrv.newCondition(" and "));
|
||||
}
|
||||
@ -44,10 +52,7 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
}
|
||||
});
|
||||
|
||||
$scope.groupBySegments.push(uiSegmentSrv.newPlusButton());
|
||||
$scope.selectSegments.push(uiSegmentSrv.newPlusButton());
|
||||
$scope.removeSelectSegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove select --'});
|
||||
$scope.removeGroupBySegment = uiSegmentSrv.newSegment({fake: true, value: '-- remove group by --'});
|
||||
};
|
||||
|
||||
$scope.getSelectSegments = function(segment, index) {
|
||||
@ -55,12 +60,15 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
var options = [
|
||||
uiSegmentSrv.newSegment({value: 'count', type: 'agg'}),
|
||||
uiSegmentSrv.newSegment({value: 'min', type: 'agg', reqField: true}),
|
||||
uiSegmentSrv.newSegment({value: 'count', type: 'agg', reqField: true}),
|
||||
uiSegmentSrv.newSegment({value: 'max', type: 'agg', reqField: true}),
|
||||
uiSegmentSrv.newSegment({value: 'avg', type: 'agg', reqField: true}),
|
||||
];
|
||||
if (index > 0) {
|
||||
if (segment.type !== 'plus-button' && $scope.selectSegments.length > 3) {
|
||||
options.splice(0, 0, angular.copy($scope.removeSelectSegment));
|
||||
}
|
||||
if (index === 0 && $scope.selectSegments.length > 2) {
|
||||
options.splice(0, 0, angular.copy($scope.resetSelectSegment));
|
||||
}
|
||||
return $q.when(options);
|
||||
}
|
||||
|
||||
@ -70,17 +78,28 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
};
|
||||
|
||||
$scope.selectChanged = function(segment, index) {
|
||||
// reset
|
||||
if (segment.value === $scope.resetSelectSegment.value) {
|
||||
$scope.target.select = [{ agg: 'count' }];
|
||||
$scope.initSelectSegments();
|
||||
$scope.get_data();
|
||||
return;
|
||||
}
|
||||
|
||||
// remove this select field
|
||||
if (segment.value === $scope.removeSelectSegment.value) {
|
||||
var nextSegment = $scope.selectSegments[index + 1];
|
||||
var remove = 2;
|
||||
if (nextSegment && nextSegment.type === 'field') {
|
||||
remove += 1;
|
||||
}
|
||||
$scope.selectSegments.splice(index-1, remove);
|
||||
$scope.selectSegments.splice(Math.max(index-1, 0), remove);
|
||||
$scope.rebuildTargetSelects();
|
||||
$scope.get_data();
|
||||
return;
|
||||
}
|
||||
|
||||
// add new
|
||||
if (segment.type === 'plus-button' && index > 0) {
|
||||
$scope.selectSegments.splice(index, 0, uiSegmentSrv.newCondition(' And '));
|
||||
segment.type = 'agg';
|
||||
@ -102,6 +121,7 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
}
|
||||
|
||||
$scope.rebuildTargetSelects();
|
||||
$scope.get_data();
|
||||
};
|
||||
|
||||
$scope.rebuildTargetSelects = function() {
|
||||
@ -110,13 +130,14 @@ function (angular, _, ElasticQueryBuilder) {
|
||||
var segment = $scope.selectSegments[i];
|
||||
var select = {agg: segment.value };
|
||||
|
||||
if (segment.type === 'agg' && segment.reqField) {
|
||||
if (segment.type === 'agg' && segment.value !== 'count') {
|
||||
select.field = $scope.selectSegments[i+1].value;
|
||||
i += 2;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (select.field === 'select field') { continue; }
|
||||
$scope.target.select.push(select);
|
||||
};
|
||||
};
|
||||
|
@ -25,7 +25,7 @@ define([
|
||||
groupByFields: [],
|
||||
}, 100, 1000);
|
||||
|
||||
expect(query.query.filtered.filter.bool.must[0].range["@timestamp"].gte).to.be(100);
|
||||
var aggs = query.aggs.histogram;
|
||||
});
|
||||
|
||||
|
||||
|
@ -17,12 +17,13 @@ define([
|
||||
|
||||
describe('When processing es response', function() {
|
||||
|
||||
describe('simple query', function() {
|
||||
describe('simple query and count', function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = ctx.ds._processTimeSeries([{
|
||||
refId: 'A',
|
||||
select: [{agg: 'count'}],
|
||||
groupByFields: [],
|
||||
}], {
|
||||
responses: [{
|
||||
@ -53,11 +54,58 @@ define([
|
||||
|
||||
});
|
||||
|
||||
describe('simple query count & avg aggregation', function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = ctx.ds._processTimeSeries([{
|
||||
refId: 'A',
|
||||
select: [{agg: 'count'}, {agg: 'avg', field: 'value'}],
|
||||
groupByFields: [],
|
||||
}], {
|
||||
responses: [{
|
||||
aggregations: {
|
||||
histogram: {
|
||||
buckets: [
|
||||
{
|
||||
value: {value: 88},
|
||||
doc_count: 10,
|
||||
key: 1000
|
||||
},
|
||||
{
|
||||
value: {value: 99},
|
||||
doc_count: 15,
|
||||
key: 2000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
})
|
||||
});
|
||||
|
||||
it('should return 2 series', function() {
|
||||
expect(result.data.length).to.be(2);
|
||||
expect(result.data[0].datapoints.length).to.be(2);
|
||||
expect(result.data[0].datapoints[0][0]).to.be(10);
|
||||
expect(result.data[0].datapoints[0][1]).to.be(1000);
|
||||
|
||||
expect(result.data[1].target).to.be("A value");
|
||||
expect(result.data[1].datapoints[0][0]).to.be(88);
|
||||
expect(result.data[1].datapoints[1][0]).to.be(99);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('single group by query', function() {
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = ctx.ds._processTimeSeries([{refId: 'A', groupByFields: [{field: 'host' }]}], {
|
||||
result = ctx.ds._processTimeSeries([{
|
||||
refId: 'A',
|
||||
select: [{agg: 'count'}],
|
||||
groupByFields: [{field: 'host' }]
|
||||
}], {
|
||||
responses: [{
|
||||
aggregations: {
|
||||
histogram: {
|
||||
@ -92,8 +140,8 @@ define([
|
||||
it('should return 2 series', function() {
|
||||
expect(result.data.length).to.be(2);
|
||||
expect(result.data[0].datapoints.length).to.be(2);
|
||||
expect(result.data[0].target).to.be('server1');
|
||||
expect(result.data[1].target).to.be('server2');
|
||||
expect(result.data[0].target).to.be('A server1 count');
|
||||
expect(result.data[1].target).to.be('A server2 count');
|
||||
});
|
||||
});
|
||||
|
||||
@ -101,7 +149,11 @@ define([
|
||||
var result;
|
||||
|
||||
beforeEach(function() {
|
||||
result = ctx.ds._processTimeSeries([{refId: 'A', groupByFields: [{field: 'host'}, {field: 'site'}]}], {
|
||||
result = ctx.ds._processTimeSeries([{
|
||||
refId: 'A',
|
||||
select: [{agg: 'count'}],
|
||||
groupByFields: [{field: 'host'}, {field: 'site'}]
|
||||
}], {
|
||||
responses: [{
|
||||
aggregations: {
|
||||
histogram: {
|
||||
@ -170,10 +222,10 @@ define([
|
||||
it('should return 2 series', function() {
|
||||
expect(result.data.length).to.be(4);
|
||||
expect(result.data[0].datapoints.length).to.be(2);
|
||||
expect(result.data[0].target).to.be('server1 backend');
|
||||
expect(result.data[1].target).to.be('server1 frontend');
|
||||
expect(result.data[2].target).to.be('server2 backend');
|
||||
expect(result.data[3].target).to.be('server2 frontend');
|
||||
expect(result.data[0].target).to.be('A server1 backend count');
|
||||
expect(result.data[1].target).to.be('A server1 frontend count');
|
||||
expect(result.data[2].target).to.be('A server2 backend count');
|
||||
expect(result.data[3].target).to.be('A server2 frontend count');
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user