Files
grafana/public/app/plugins/datasource/elasticsearch/hooks/useFields.ts
Chris Cowan f580c9149c 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>
2021-06-04 11:07:59 +01:00

71 lines
2.6 KiB
TypeScript

import { MetricFindValue, SelectableValue } from '@grafana/data';
import {
BucketAggregationType,
isBucketAggregationType,
} from '../components/QueryEditor/BucketAggregationsEditor/aggregations';
import { useDatasource, useRange } from '../components/QueryEditor/ElasticsearchQueryContext';
import {
isMetricAggregationType,
MetricAggregationType,
} from '../components/QueryEditor/MetricAggregationsEditor/aggregations';
type AggregationType = BucketAggregationType | MetricAggregationType;
const getFilter = (type: AggregationType) => {
if (isMetricAggregationType(type)) {
switch (type) {
case 'cardinality':
return [];
case 'top_metrics':
// top_metrics was introduced in 7.7 where `metrics` only supported number:
// https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-metrics-top-metrics.html#_metrics
// TODO: starting from 7.11 it supports ips and keywords as well:
// https://www.elastic.co/guide/en/elasticsearch/reference/7.11/search-aggregations-metrics-top-metrics.html#_metrics
return ['number'];
default:
return ['number'];
}
}
if (isBucketAggregationType(type)) {
switch (type) {
case 'date_histogram':
return ['date'];
case 'geohash_grid':
return ['geo_point'];
default:
return [];
}
}
return [];
};
const toSelectableValue = ({ text }: MetricFindValue): SelectableValue<string> => ({
label: text,
value: text,
});
/**
* Returns a function to query the configured datasource for autocomplete values for the specified aggregation type or data types.
* Each aggregation can be run on different types, for example avg only operates on numeric fields, geohash_grid only on geo_point fields.
* If an aggregation type is provided, the promise will resolve with all fields suitable to be used as a field for the given aggregation.
* If an array of types is providem the promise will resolve with all the fields matching the provided types.
* @param aggregationType the type of aggregation to get fields for
*/
export const useFields = (type: AggregationType | string[]) => {
const datasource = useDatasource();
const range = useRange();
const filter = Array.isArray(type) ? type : getFilter(type);
let rawFields: MetricFindValue[];
return async (q?: string) => {
// _mapping doesn't support filtering, we avoid sending a request everytime q changes
if (!rawFields) {
rawFields = await datasource.getFields(filter, range).toPromise();
}
return rawFields.filter(({ text }) => q === undefined || text.includes(q)).map(toSelectableValue);
};
};