Explore: Prevent empty Elasticsearch logs query responses from hiding the logs panel (#40217)

* remove return value from addPreferredVisualisationType

* Elasticsearch: send empty series instead when no data is received for a query
This commit is contained in:
Giordano Ricci 2021-10-12 13:59:28 +01:00 committed by GitHub
parent ea0c1006f5
commit b0391d4933
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 67 deletions

View File

@ -489,7 +489,7 @@ export class ElasticResponse {
return this.processResponseToDataFrames(true, logMessageField, logLevelField);
}
processResponseToDataFrames(
private processResponseToDataFrames(
isLogsRequest: boolean,
logMessageField?: string,
logLevelField?: string
@ -501,16 +501,22 @@ export class ElasticResponse {
throw this.getErrorFromElasticResponse(this.response, response.error);
}
if (response.hits && response.hits.hits.length > 0) {
if (response.hits) {
const { propNames, docs } = flattenHits(response.hits.hits);
if (docs.length > 0) {
let series = createEmptyDataFrame(
const series = docs.length
? createEmptyDataFrame(
propNames.map(toNameTypePair(docs)),
this.targets[0].timeField!,
isLogsRequest,
this.targets[0].timeField,
logMessageField,
logLevelField
);
)
: createEmptyDataFrame([], isLogsRequest);
if (isLogsRequest) {
addPreferredVisualisationType(series, 'logs');
}
// Add a row for each document
for (const doc of docs) {
@ -552,14 +558,11 @@ export class ElasticResponse {
}
series.add(doc);
}
if (isLogsRequest) {
series = addPreferredVisualisationType(series, 'logs');
}
const target = this.targets[n];
series.refId = target.refId;
dataFrame.push(series);
}
}
if (response.aggregations) {
const aggregations = response.aggregations;
@ -582,7 +585,7 @@ export class ElasticResponse {
// When log results, show aggregations only in graph. Log fields are then going to be shown in table.
if (isLogsRequest) {
series = addPreferredVisualisationType(series, 'graph');
addPreferredVisualisationType(series, 'graph');
}
series.refId = target.refId;
@ -690,13 +693,14 @@ const flattenHits = (hits: Doc[]): { docs: Array<Record<string, any>>; propNames
*/
const createEmptyDataFrame = (
props: Array<[string, FieldType]>,
timeField: string,
isLogsRequest: boolean,
timeField?: string,
logMessageField?: string,
logLevelField?: string
): MutableDataFrame => {
const series = new MutableDataFrame({ fields: [] });
if (timeField) {
series.addField({
config: {
filterable: true,
@ -704,6 +708,7 @@ const createEmptyDataFrame = (
name: timeField,
type: FieldType.time,
});
}
if (logMessageField) {
series.addField({
@ -756,8 +761,6 @@ const addPreferredVisualisationType = (series: any, type: PreferredVisualisation
: (s.meta = {
preferredVisualisationType: type,
});
return s;
};
const toNameTypePair = (docs: Array<Record<string, any>>) => (propName: string): [string, FieldType] => [

View File

@ -1432,4 +1432,39 @@ describe('ElasticResponse', () => {
expect(fields).toContainEqual({ name: 'message', type: 'string' });
});
});
describe('logs query with empty response', () => {
const targets: ElasticsearchQuery[] = [
{
refId: 'A',
metrics: [{ type: 'logs', id: '2' }],
bucketAggs: [{ type: 'date_histogram', settings: { interval: 'auto' }, id: '1' }],
key: 'Q-1561369883389-0.7611823271062786-0',
query: 'hello AND message',
timeField: '@timestamp',
},
];
const response = {
responses: [
{
hits: { hits: [] },
aggregations: {
'1': {
buckets: [
{ key_as_string: '1633676760000', key: 1633676760000, doc_count: 0 },
{ key_as_string: '1633676770000', key: 1633676770000, doc_count: 0 },
{ key_as_string: '1633676780000', key: 1633676780000, doc_count: 0 },
],
},
},
status: 200,
},
],
};
it('should return histogram aggregation and documents', () => {
const result = new ElasticResponse(targets, response).getLogs('message', 'level');
expect(result.data.length).toBe(2);
});
});
});