Commit ede827f5 by Torkel Ödegaard

feat: Elasticsearch change to how queries without date histogram are transformed…

feat: Elasticsearch change to how queries without date histogram are transformed into Grafana data stucture, now it is processed into a table structure instead of json structure
parent 6224a25e
...@@ -3,9 +3,11 @@ export default class TableModel { ...@@ -3,9 +3,11 @@ export default class TableModel {
columns: any[]; columns: any[];
rows: any[]; rows: any[];
type: string; type: string;
columnMap: any;
constructor() { constructor() {
this.columns = []; this.columns = [];
this.columnMap = {};
this.rows = []; this.rows = [];
this.type = 'table'; this.type = 'table';
} }
...@@ -36,4 +38,11 @@ export default class TableModel { ...@@ -36,4 +38,11 @@ export default class TableModel {
this.columns[options.col].desc = false; this.columns[options.col].desc = false;
} }
} }
addColumn(col) {
if (!this.columnMap[col.text]) {
this.columns.push(col);
this.columnMap[col.text] = col;
}
}
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import _ from 'lodash'; import _ from 'lodash';
import queryDef from "./query_def"; import queryDef from "./query_def";
import TableModel from 'app/core/table_model';
export function ElasticResponse(targets, response) { export function ElasticResponse(targets, response) {
this.targets = targets; this.targets = targets;
...@@ -95,21 +96,35 @@ ElasticResponse.prototype.processMetrics = function(esAgg, target, seriesList, p ...@@ -95,21 +96,35 @@ ElasticResponse.prototype.processMetrics = function(esAgg, target, seriesList, p
} }
}; };
ElasticResponse.prototype.processAggregationDocs = function(esAgg, aggDef, target, docs, props) { ElasticResponse.prototype.processAggregationDocs = function(esAgg, aggDef, target, table, props) {
var metric, y, i, bucket, metricName, doc; // add columns
if (table.columns.length === 0) {
for (let propKey of _.keys(props)) {
table.addColumn({text: propKey});
}
table.addColumn({text: aggDef.field});
}
// helper func to add values to value array
let addMetricValue = (values, metricName, value) => {
table.addColumn({text: metricName});
values.push(value);
};
for (i = 0; i < esAgg.buckets.length; i++) { for (let bucket of esAgg.buckets) {
bucket = esAgg.buckets[i]; let values = [];
doc = _.defaults({}, props);
doc[aggDef.field] = bucket.key; for (let propValues of _.values(props)) {
values.push(propValues);
}
for (y = 0; y < target.metrics.length; y++) { // add bucket key (value)
metric = target.metrics[y]; values.push(bucket.key);
for (let metric of target.metrics) {
switch (metric.type) { switch (metric.type) {
case "count": { case "count": {
metricName = this._getMetricName(metric.type); addMetricValue(values, this._getMetricName(metric.type), bucket.doc_count);
doc[metricName] = bucket.doc_count;
break; break;
} }
case 'extended_stats': { case 'extended_stats': {
...@@ -123,33 +138,32 @@ ElasticResponse.prototype.processAggregationDocs = function(esAgg, aggDef, targe ...@@ -123,33 +138,32 @@ ElasticResponse.prototype.processAggregationDocs = function(esAgg, aggDef, targe
stats.std_deviation_bounds_upper = stats.std_deviation_bounds.upper; stats.std_deviation_bounds_upper = stats.std_deviation_bounds.upper;
stats.std_deviation_bounds_lower = stats.std_deviation_bounds.lower; stats.std_deviation_bounds_lower = stats.std_deviation_bounds.lower;
metricName = this._getMetricName(statName); addMetricValue(values, this._getMetricName(statName), stats[statName]);
doc[metricName] = stats[statName];
} }
break; break;
} }
default: { default: {
metricName = this._getMetricName(metric.type); let metricName = this._getMetricName(metric.type);
var otherMetrics = _.filter(target.metrics, {type: metric.type}); let otherMetrics = _.filter(target.metrics, {type: metric.type});
// if more of the same metric type include field field name in property // if more of the same metric type include field field name in property
if (otherMetrics.length > 1) { if (otherMetrics.length > 1) {
metricName += ' ' + metric.field; metricName += ' ' + metric.field;
} }
doc[metricName] = bucket[metric.id].value; addMetricValue(values, metricName, bucket[metric.id].value);
break; break;
} }
} }
} }
docs.push(doc); table.rows.push(values);
} }
}; };
// This is quite complex // This is quite complex
// neeed to recurise down the nested buckets to build series // neeed to recurise down the nested buckets to build series
ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, docs, props, depth) { ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, table, props, depth) {
var bucket, aggDef, esAgg, aggId; var bucket, aggDef, esAgg, aggId;
var maxDepth = target.bucketAggs.length-1; var maxDepth = target.bucketAggs.length-1;
...@@ -165,7 +179,7 @@ ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, do ...@@ -165,7 +179,7 @@ ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, do
if (aggDef.type === 'date_histogram') { if (aggDef.type === 'date_histogram') {
this.processMetrics(esAgg, target, seriesList, props); this.processMetrics(esAgg, target, seriesList, props);
} else { } else {
this.processAggregationDocs(esAgg, aggDef, target, docs, props); this.processAggregationDocs(esAgg, aggDef, target, table, props);
} }
} else { } else {
for (var nameIndex in esAgg.buckets) { for (var nameIndex in esAgg.buckets) {
...@@ -179,7 +193,7 @@ ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, do ...@@ -179,7 +193,7 @@ ElasticResponse.prototype.processBuckets = function(aggs, target, seriesList, do
if (bucket.key_as_string) { if (bucket.key_as_string) {
props[aggDef.field] = bucket.key_as_string; props[aggDef.field] = bucket.key_as_string;
} }
this.processBuckets(bucket, target, seriesList, docs, props, depth+1); this.processBuckets(bucket, target, seriesList, table, props, depth+1);
} }
} }
} }
...@@ -325,9 +339,9 @@ ElasticResponse.prototype.getTimeSeries = function() { ...@@ -325,9 +339,9 @@ ElasticResponse.prototype.getTimeSeries = function() {
var aggregations = response.aggregations; var aggregations = response.aggregations;
var target = this.targets[i]; var target = this.targets[i];
var tmpSeriesList = []; var tmpSeriesList = [];
var docs = []; var table = new TableModel();
this.processBuckets(aggregations, target, tmpSeriesList, docs, {}, 0); this.processBuckets(aggregations, target, tmpSeriesList, table, {}, 0);
this.trimDatapoints(tmpSeriesList, target); this.trimDatapoints(tmpSeriesList, target);
this.nameSeries(tmpSeriesList, target); this.nameSeries(tmpSeriesList, target);
...@@ -335,8 +349,8 @@ ElasticResponse.prototype.getTimeSeries = function() { ...@@ -335,8 +349,8 @@ ElasticResponse.prototype.getTimeSeries = function() {
seriesList.push(tmpSeriesList[y]); seriesList.push(tmpSeriesList[y]);
} }
if (seriesList.length === 0 && docs.length > 0) { if (table.rows.length > 0) {
seriesList.push({target: 'docs', type: 'docs', datapoints: docs}); seriesList.push(table);
} }
} }
} }
......
...@@ -387,10 +387,9 @@ describe('ElasticResponse', function() { ...@@ -387,10 +387,9 @@ describe('ElasticResponse', function() {
result = new ElasticResponse(targets, response).getTimeSeries(); result = new ElasticResponse(targets, response).getTimeSeries();
}); });
it('should return docs with byte and count', function() { it('should return table with byte and count', function() {
expect(result.data[0].datapoints.length).to.be(3); expect(result.data[0].rows.length).to.be(3);
expect(result.data[0].datapoints[0].Count).to.be(1); expect(result.data[0].columns).to.eql([{text: 'bytes'}, {text: 'Count'}]);
expect(result.data[0].datapoints[0].bytes).to.be(1000);
}); });
}); });
...@@ -530,14 +529,14 @@ describe('ElasticResponse', function() { ...@@ -530,14 +529,14 @@ describe('ElasticResponse', function() {
it('should return table', function() { it('should return table', function() {
expect(result.data.length).to.be(1); expect(result.data.length).to.be(1);
expect(result.data[0].type).to.be('docs'); expect(result.data[0].type).to.be('table');
expect(result.data[0].datapoints.length).to.be(2); expect(result.data[0].rows.length).to.be(2);
expect(result.data[0].datapoints[0].host).to.be("server-1"); expect(result.data[0].rows[0][0]).to.be("server-1");
expect(result.data[0].datapoints[0].Average).to.be(1000); expect(result.data[0].rows[0][1]).to.be(1000);
expect(result.data[0].datapoints[0].Count).to.be(369); expect(result.data[0].rows[0][2]).to.be(369);
expect(result.data[0].datapoints[1].host).to.be("server-2"); expect(result.data[0].rows[1][0]).to.be("server-2");
expect(result.data[0].datapoints[1].Average).to.be(2000); expect(result.data[0].rows[1][1]).to.be(2000);
}); });
}); });
...@@ -573,10 +572,9 @@ describe('ElasticResponse', function() { ...@@ -573,10 +572,9 @@ describe('ElasticResponse', function() {
}); });
it('should include field in metric name', function() { it('should include field in metric name', function() {
expect(result.data[0].type).to.be('docs'); expect(result.data[0].type).to.be('table');
expect(result.data[0].datapoints[0].Average).to.be(undefined); expect(result.data[0].rows[0][1]).to.be(1000);
expect(result.data[0].datapoints[0]['Average test']).to.be(1000); expect(result.data[0].rows[0][2]).to.be(3000);
expect(result.data[0].datapoints[0]['Average test2']).to.be(3000);
}); });
}); });
......
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