Elasticsearch: Fix impossibility to perform non-logs queries after importing queries from loki or prometheus in explore (#31518)

* Chore: remove isLogsQuery flag from ES datasource

* Minore chores

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

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
This commit is contained in:
Giordano Ricci
2021-03-02 09:10:41 +00:00
committed by GitHub
parent a2fe6ef92c
commit 3cf0103782
9 changed files with 19 additions and 27 deletions

View File

@@ -28,8 +28,8 @@ describe('getAlertingValidationMessage', () => {
getInstanceSettings: (() => {}) as any,
};
const targets: ElasticsearchQuery[] = [
{ refId: 'A', query: '@hostname:$hostname', isLogsQuery: false },
{ refId: 'B', query: '@instance:instance', isLogsQuery: false },
{ refId: 'A', query: '@hostname:$hostname' },
{ refId: 'B', query: '@instance:instance' },
];
const transformations: DataTransformerConfig[] = [];
@@ -95,8 +95,8 @@ describe('getAlertingValidationMessage', () => {
},
};
const targets: ElasticsearchQuery[] = [
{ refId: 'A', query: '@hostname:$hostname', isLogsQuery: false },
{ refId: 'B', query: '@instance:$instance', isLogsQuery: false },
{ refId: 'A', query: '@hostname:$hostname' },
{ refId: 'B', query: '@instance:$instance' },
];
const transformations: DataTransformerConfig[] = [];
@@ -124,8 +124,8 @@ describe('getAlertingValidationMessage', () => {
},
};
const targets: ElasticsearchQuery[] = [
{ refId: 'A', query: '@hostname:hostname', isLogsQuery: false },
{ refId: 'B', query: '@instance:instance', isLogsQuery: false },
{ refId: 'A', query: '@hostname:hostname' },
{ refId: 'B', query: '@instance:instance' },
];
const transformations: DataTransformerConfig[] = [];
@@ -153,8 +153,8 @@ describe('getAlertingValidationMessage', () => {
},
};
const targets: ElasticsearchQuery[] = [
{ refId: 'A', query: '@hostname:hostname', isLogsQuery: false },
{ refId: 'B', query: '@instance:instance', isLogsQuery: false },
{ refId: 'A', query: '@hostname:hostname' },
{ refId: 'B', query: '@instance:instance' },
];
const transformations: DataTransformerConfig[] = [{ id: 'A', options: null }];

View File

@@ -226,9 +226,8 @@ describe('ElasticDatasource', function (this: any) {
id: '2',
},
],
metrics: [{ type: 'count', id: '1' }],
metrics: [{ type: 'logs', id: '1' }],
query: 'escape\\:test',
isLogsQuery: true,
timeField: '@timestamp',
},
],
@@ -957,7 +956,6 @@ const createElasticQuery = (): DataQueryRequest<ElasticsearchQuery> => {
targets: [
{
refId: '',
isLogsQuery: false,
bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '2' }],
metrics: [{ type: 'count', id: '' }],
query: 'test',

View File

@@ -497,7 +497,7 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
const payload = [header, esQuery].join('\n') + '\n';
const url = this.getMultiSearchUrl();
const response = await this.post(url, payload).toPromise();
const targets: ElasticsearchQuery[] = [{ refId: `${row.dataFrame.refId}`, metrics: [], isLogsQuery: true }];
const targets: ElasticsearchQuery[] = [{ refId: `${row.dataFrame.refId}`, metrics: [{ type: 'logs', id: '1' }] }];
const elasticResponse = new ElasticResponse(targets, transformHitsBasedOnDirection(response, sort));
const logResponse = elasticResponse.getLogs(this.logMessageField, this.logLevelField);
const dataFrame = _.first(logResponse.data);
@@ -530,6 +530,7 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
let payload = '';
const targets = this.interpolateVariablesInQueries(_.cloneDeep(options.targets), options.scopedVars);
const sentTargets: ElasticsearchQuery[] = [];
let targetsContainsLogsQuery = targets.some((target) => hasMetricOfType(target, 'logs'));
// add global adhoc filters to timeFilter
const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
@@ -540,11 +541,10 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
}
let queryObj;
if (target.isLogsQuery || hasMetricOfType(target, 'logs')) {
if (hasMetricOfType(target, 'logs')) {
target.bucketAggs = [defaultBucketAgg()];
target.metrics = [];
// Setting this for metrics queries that are typed as logs
target.isLogsQuery = true;
queryObj = this.queryBuilder.getLogsQuery(target, adhocFilters, target.query);
} else {
if (target.alias) {
@@ -583,7 +583,8 @@ export class ElasticDatasource extends DataSourceApi<ElasticsearchQuery, Elastic
map((res) => {
const er = new ElasticResponse(sentTargets, res);
if (sentTargets.some((target) => target.isLogsQuery)) {
// TODO: This needs to be revisited, it seems wrong to process ALL the sent queries as logs if only one of them was a log query
if (targetsContainsLogsQuery) {
const response = er.getLogs(this.logMessageField, this.logLevelField);
for (const dataFrame of response.data) {
enhanceDataFrame(dataFrame, this.dataLinks);

View File

@@ -425,7 +425,7 @@ export class ElasticResponse {
}
getTimeSeries() {
if (this.targets.some((target) => target.metrics?.some((metric) => metric.type === 'raw_data'))) {
if (this.targets.some((target) => queryDef.hasMetricOfType(target, 'raw_data'))) {
return this.processResponseToDataFrames(false);
}
return this.processResponseToSeries();

View File

@@ -26,7 +26,6 @@ const dataSource = new ElasticDatasource(
);
const baseLogsQuery: Partial<ElasticsearchQuery> = {
isLogsQuery: true,
metrics: [{ type: 'logs', id: '1' }],
bucketAggs: [{ ...defaultBucketAgg('2'), field: dataSource.timeField } as DateHistogram],
};

View File

@@ -116,7 +116,6 @@ export default class ElasticsearchLanguageProvider extends LanguageProvider {
let prometheusQuery = query as PromQuery;
const expr = getElasticsearchQuery(extractPrometheusLabels(prometheusQuery.expr));
return {
isLogsQuery: true,
metrics: [
{
id: '1',

View File

@@ -6,6 +6,7 @@ import {
MetricAggregationType,
} from './components/QueryEditor/MetricAggregationsEditor/aggregations';
import { metricAggregationConfig, pipelineOptions } from './components/QueryEditor/MetricAggregationsEditor/utils';
import { ElasticsearchQuery } from './types';
export const extendedStats: ExtendedStat[] = [
{ label: 'Avg', value: 'avg' },
@@ -42,8 +43,8 @@ export function defaultBucketAgg(id = '1'): BucketAggregation {
export const findMetricById = (metrics: MetricAggregation[], id: MetricAggregation['id']) =>
metrics.find((metric) => metric.id === id);
export function hasMetricOfType(target: any, type: string): boolean {
return target && target.metrics && target.metrics.some((m: any) => m.type === type);
export function hasMetricOfType(target: ElasticsearchQuery, type: MetricAggregationType): boolean {
return !!target?.metrics?.some((m) => m.type === type);
}
// Even if we have type guards when building a query, we currently have no way of getting this information from the response.

View File

@@ -1208,17 +1208,12 @@ describe('ElasticResponse', () => {
});
describe('simple logs query and count', () => {
const targets: any = [
const targets: ElasticsearchQuery[] = [
{
refId: 'A',
metrics: [{ type: 'count', id: '1' }],
bucketAggs: [{ type: 'date_histogram', settings: { interval: 'auto' }, id: '2' }],
context: 'explore',
interval: '10s',
isLogsQuery: true,
key: 'Q-1561369883389-0.7611823271062786-0',
liveStreaming: false,
maxDataPoints: 1620,
query: 'hello AND message',
timeField: '@timestamp',
},

View File

@@ -59,7 +59,6 @@ export interface ElasticsearchAggregation {
}
export interface ElasticsearchQuery extends DataQuery {
isLogsQuery?: boolean;
alias?: string;
query?: string;
bucketAggs?: BucketAggregation[];