Elasticsearch: Add Top Metrics Aggregation and X-Pack support (#33041)

* Elasticsearch: Add Top Metrics Aggregation

* Adding support for non-timeseries visualizations

* removing console.logs

* restoring loadOptions type

* Honor xpack setting

* Adding test for elastic_response

* adding test for query builder

* Adding support of alerting

* Fixing separator spelling

* Fixing linting issues

* attempting to reduce cyclomatic complexity

* Adding elastic77 Docker block

* Update public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.test.tsx

Co-authored-by: Giordano Ricci <grdnricci@gmail.com>

* refactoring MetricsEditor tests

* Fixing typo

* Change getFields type & move TopMetrics to a separate component

* Fix SegmentAsync styles in TopMetrics Settings

* Fix field types for TopMetrics

* WIP

* Refactoring client side to support multiple top metrics

* Adding tests and finishing go implimentation

* removing fmt lib from debugging

* fixing tests

* reducing the cyclomatic complexity

* Update public/app/plugins/datasource/elasticsearch/elastic_response.ts

Co-authored-by: Giordano Ricci <grdnricci@gmail.com>

* Update public/app/plugins/datasource/elasticsearch/hooks/useFields.ts

Co-authored-by: Giordano Ricci <grdnricci@gmail.com>

* Checking for possible nil value

* Fixing types

* fix fake-data-gen param

* fix useFields hook

* Removing aggregateBy and size

* Fixing go tests

* Fixing TS tests

* fixing tests

* Fixes

* Remove date from top_metrics fields

* Restore previous formatting

* Update pkg/tsdb/elasticsearch/client/models.go

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>

* Update pkg/tsdb/elasticsearch/client/models.go

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>

* Fix code review comments on processTopMetricValue

* Remove underscore from variable names

* Remove intermediate array definition

* Refactor test to use testify

Co-authored-by: Giordano Ricci <grdnricci@gmail.com>
Co-authored-by: Elfo404 <me@giordanoricci.com>
Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
This commit is contained in:
Chris Cowan
2021-06-04 03:07:59 -07:00
committed by GitHub
parent f683a497eb
commit f580c9149c
30 changed files with 2718 additions and 111 deletions

View File

@@ -298,7 +298,7 @@ export class ElasticQueryBuilder {
}
const aggField: any = {};
let metricAgg: any = null;
let metricAgg: any = {};
if (isPipelineAggregation(metric)) {
if (isPipelineAggregationWithMultipleBucketPaths(metric)) {
@@ -353,32 +353,47 @@ export class ElasticQueryBuilder {
// Elasticsearch isn't generally too picky about the data types in the request body,
// however some fields are required to be numeric.
// Users might have already created some of those with before, where the values were numbers.
if (metric.type === 'moving_avg') {
metricAgg = {
...metricAgg,
...(metricAgg?.window !== undefined && { window: this.toNumber(metricAgg.window) }),
...(metricAgg?.predict !== undefined && { predict: this.toNumber(metricAgg.predict) }),
...(isMovingAverageWithModelSettings(metric) && {
settings: {
...metricAgg.settings,
...Object.fromEntries(
Object.entries(metricAgg.settings || {})
// Only format properties that are required to be numbers
.filter(([settingName]) => ['alpha', 'beta', 'gamma', 'period'].includes(settingName))
// omitting undefined
.filter(([_, stringValue]) => stringValue !== undefined)
.map(([_, stringValue]) => [_, this.toNumber(stringValue)])
),
},
}),
};
} else if (metric.type === 'serial_diff') {
metricAgg = {
...metricAgg,
...(metricAgg.lag !== undefined && {
lag: this.toNumber(metricAgg.lag),
}),
};
switch (metric.type) {
case 'moving_avg':
metricAgg = {
...metricAgg,
...(metricAgg?.window !== undefined && { window: this.toNumber(metricAgg.window) }),
...(metricAgg?.predict !== undefined && { predict: this.toNumber(metricAgg.predict) }),
...(isMovingAverageWithModelSettings(metric) && {
settings: {
...metricAgg.settings,
...Object.fromEntries(
Object.entries(metricAgg.settings || {})
// Only format properties that are required to be numbers
.filter(([settingName]) => ['alpha', 'beta', 'gamma', 'period'].includes(settingName))
// omitting undefined
.filter(([_, stringValue]) => stringValue !== undefined)
.map(([_, stringValue]) => [_, this.toNumber(stringValue)])
),
},
}),
};
break;
case 'serial_diff':
metricAgg = {
...metricAgg,
...(metricAgg.lag !== undefined && {
lag: this.toNumber(metricAgg.lag),
}),
};
break;
case 'top_metrics':
metricAgg = {
metrics: metric.settings?.metrics?.map((field) => ({ field })),
size: 1,
};
if (metric.settings?.orderBy) {
metricAgg.sort = [{ [metric.settings?.orderBy]: metric.settings?.order }];
}
break;
}
}