mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Elasticsearch: Fix passing of limit and datalinks to logs data frame (#68554)
* Elasticsearch: Fix passing of limit and datalinks to logs data frame * Update public/app/core/logsModel.ts Co-authored-by: François Massot <francois.massot@gmail.com> --------- Co-authored-by: François Massot <francois.massot@gmail.com>
This commit is contained in:
parent
d20a03e2d1
commit
dbbbc46351
@ -160,7 +160,7 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields
|
|||||||
frames := data.Frames{}
|
frames := data.Frames{}
|
||||||
frame := data.NewFrame("", fields...)
|
frame := data.NewFrame("", fields...)
|
||||||
setPreferredVisType(frame, data.VisTypeLogs)
|
setPreferredVisType(frame, data.VisTypeLogs)
|
||||||
setSearchWords(frame, searchWords)
|
setLogsCustomMeta(frame, searchWords, stringToIntWithDefaultValue(target.Metrics[0].Settings.Get("limit").MustString(), defaultSize))
|
||||||
frames = append(frames, frame)
|
frames = append(frames, frame)
|
||||||
|
|
||||||
queryRes.Frames = frames
|
queryRes.Frames = frames
|
||||||
@ -1137,7 +1137,7 @@ func setPreferredVisType(frame *data.Frame, visType data.VisType) {
|
|||||||
frame.Meta.PreferredVisualization = visType
|
frame.Meta.PreferredVisualization = visType
|
||||||
}
|
}
|
||||||
|
|
||||||
func setSearchWords(frame *data.Frame, searchWords map[string]bool) {
|
func setLogsCustomMeta(frame *data.Frame, searchWords map[string]bool, limit int) {
|
||||||
i := 0
|
i := 0
|
||||||
searchWordsList := make([]string, len(searchWords))
|
searchWordsList := make([]string, len(searchWords))
|
||||||
for searchWord := range searchWords {
|
for searchWord := range searchWords {
|
||||||
@ -1156,6 +1156,7 @@ func setSearchWords(frame *data.Frame, searchWords map[string]bool) {
|
|||||||
|
|
||||||
frame.Meta.Custom = map[string]interface{}{
|
frame.Meta.Custom = map[string]interface{}{
|
||||||
"searchWords": searchWordsList,
|
"searchWords": searchWordsList,
|
||||||
|
"limit": limit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ func TestProcessLogsResponse(t *testing.T) {
|
|||||||
logsFrame := frames[0]
|
logsFrame := frames[0]
|
||||||
|
|
||||||
meta := logsFrame.Meta
|
meta := logsFrame.Meta
|
||||||
require.Equal(t, map[string]interface{}{"searchWords": []string{"hello", "message"}}, meta.Custom)
|
require.Equal(t, map[string]interface{}{"searchWords": []string{"hello", "message"}, "limit": 500}, meta.Custom)
|
||||||
require.Equal(t, data.VisTypeLogs, string(meta.PreferredVisualization))
|
require.Equal(t, data.VisTypeLogs, string(meta.PreferredVisualization))
|
||||||
|
|
||||||
logsFieldMap := make(map[string]*data.Field)
|
logsFieldMap := make(map[string]*data.Field)
|
||||||
@ -430,6 +430,7 @@ func TestProcessLogsResponse(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, map[string]interface{}{
|
require.Equal(t, map[string]interface{}{
|
||||||
"searchWords": []string{"hello", "message"},
|
"searchWords": []string{"hello", "message"},
|
||||||
|
"limit": 500,
|
||||||
}, customMeta)
|
}, customMeta)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
// 0
|
// 0
|
||||||
// ],
|
// ],
|
||||||
// "custom": {
|
// "custom": {
|
||||||
|
// "limit": 500,
|
||||||
// "searchWords": [
|
// "searchWords": [
|
||||||
// "hello",
|
// "hello",
|
||||||
// "message"
|
// "message"
|
||||||
@ -40,6 +41,7 @@
|
|||||||
0
|
0
|
||||||
],
|
],
|
||||||
"custom": {
|
"custom": {
|
||||||
|
"limit": 500,
|
||||||
"searchWords": [
|
"searchWords": [
|
||||||
"hello",
|
"hello",
|
||||||
"message"
|
"message"
|
||||||
|
@ -354,6 +354,48 @@ describe('dataFrameToLogsModel', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('given one series with limit as custom meta property should return correct limit', () => {
|
||||||
|
const series: DataFrame[] = [
|
||||||
|
new MutableDataFrame({
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'time',
|
||||||
|
type: FieldType.time,
|
||||||
|
values: ['2019-04-26T09:28:11.352440161Z', '2019-04-26T14:42:50.991981292Z'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
type: FieldType.string,
|
||||||
|
values: [
|
||||||
|
't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
|
||||||
|
't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7',
|
||||||
|
],
|
||||||
|
labels: {
|
||||||
|
filename: '/var/log/grafana/grafana.log',
|
||||||
|
job: 'grafana',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: FieldType.string,
|
||||||
|
values: ['foo', 'bar'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
custom: {
|
||||||
|
limit: 1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
const logsModel = dataFrameToLogsModel(series, 1);
|
||||||
|
expect(logsModel.meta![1]).toMatchObject({
|
||||||
|
label: LIMIT_LABEL,
|
||||||
|
value: `1000 (2 returned)`,
|
||||||
|
kind: LogsMetaKind.String,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('given one series with labels-field should return expected logs model', () => {
|
it('given one series with labels-field should return expected logs model', () => {
|
||||||
const series: DataFrame[] = [
|
const series: DataFrame[] = [
|
||||||
new MutableDataFrame({
|
new MutableDataFrame({
|
||||||
|
@ -474,10 +474,11 @@ export function logSeriesToLogsModel(logSeries: DataFrame[], queries: DataQuery[
|
|||||||
kind: LogsMetaKind.LabelsMap,
|
kind: LogsMetaKind.LabelsMap,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Data sources that set up searchWords on backend use meta.custom.limit.
|
||||||
const limits = logSeries.filter((series) => series.meta && series.meta.limit);
|
// Data sources that set up searchWords through frontend can use meta.limit.
|
||||||
|
const limits = logSeries.filter((series) => series?.meta?.custom?.limit ?? series?.meta?.limit);
|
||||||
const lastLimitPerRef = limits.reduce<Record<string, number>>((acc, elem) => {
|
const lastLimitPerRef = limits.reduce<Record<string, number>>((acc, elem) => {
|
||||||
acc[elem.refId ?? ''] = elem.meta?.limit ?? 0;
|
acc[elem.refId ?? ''] = elem.meta?.custom?.limit ?? elem.meta?.limit ?? 0;
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
@ -15,10 +15,10 @@ import {
|
|||||||
import { BackendSrvRequest, getBackendSrv, TemplateSrv } from '@grafana/runtime';
|
import { BackendSrvRequest, getBackendSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
import { ElasticResponse } from './ElasticResponse';
|
import { ElasticResponse } from './ElasticResponse';
|
||||||
import { ElasticDatasource, enhanceDataFrame } from './datasource';
|
import { ElasticDatasource, enhanceDataFrameWithDataLinks } from './datasource';
|
||||||
import { defaultBucketAgg, hasMetricOfType } from './queryDef';
|
import { defaultBucketAgg, hasMetricOfType } from './queryDef';
|
||||||
import { trackQuery } from './tracking';
|
import { trackQuery } from './tracking';
|
||||||
import { ElasticsearchQuery, Logs } from './types';
|
import { DataLinkConfig, ElasticsearchQuery, Logs } from './types';
|
||||||
|
|
||||||
export class LegacyQueryRunner {
|
export class LegacyQueryRunner {
|
||||||
datasource: ElasticDatasource;
|
datasource: ElasticDatasource;
|
||||||
@ -250,3 +250,17 @@ function transformHitsBasedOnDirection(response: any, direction: 'asc' | 'desc')
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies dataFrame and adds dataLinks from the config.
|
||||||
|
* Exported for tests.
|
||||||
|
*/
|
||||||
|
export function enhanceDataFrame(dataFrame: DataFrame, dataLinks: DataLinkConfig[], limit?: number) {
|
||||||
|
if (limit) {
|
||||||
|
dataFrame.meta = {
|
||||||
|
...dataFrame.meta,
|
||||||
|
limit,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
enhanceDataFrameWithDataLinks(dataFrame, dataLinks);
|
||||||
|
}
|
||||||
|
@ -25,7 +25,8 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
|
|||||||
|
|
||||||
import { createFetchResponse } from '../../../../test/helpers/createFetchResponse';
|
import { createFetchResponse } from '../../../../test/helpers/createFetchResponse';
|
||||||
|
|
||||||
import { ElasticDatasource, enhanceDataFrame } from './datasource';
|
import { enhanceDataFrame } from './LegacyQueryRunner';
|
||||||
|
import { ElasticDatasource } from './datasource';
|
||||||
import { createElasticDatasource } from './mocks';
|
import { createElasticDatasource } from './mocks';
|
||||||
import { Filters, ElasticsearchOptions, ElasticsearchQuery } from './types';
|
import { Filters, ElasticsearchOptions, ElasticsearchQuery } from './types';
|
||||||
|
|
||||||
|
@ -626,7 +626,15 @@ export class ElasticDatasource
|
|||||||
const { enableElasticsearchBackendQuerying } = config.featureToggles;
|
const { enableElasticsearchBackendQuerying } = config.featureToggles;
|
||||||
if (enableElasticsearchBackendQuerying) {
|
if (enableElasticsearchBackendQuerying) {
|
||||||
const start = new Date();
|
const start = new Date();
|
||||||
return super.query(request).pipe(tap((response) => trackQuery(response, request, start)));
|
return super.query(request).pipe(
|
||||||
|
tap((response) => trackQuery(response, request, start)),
|
||||||
|
map((response) => {
|
||||||
|
response.data.forEach((dataFrame) => {
|
||||||
|
enhanceDataFrameWithDataLinks(dataFrame, this.dataLinks);
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return this.legacyQueryRunner.query(request);
|
return this.legacyQueryRunner.query(request);
|
||||||
}
|
}
|
||||||
@ -1034,18 +1042,7 @@ export class ElasticDatasource
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export function enhanceDataFrameWithDataLinks(dataFrame: DataFrame, dataLinks: DataLinkConfig[]) {
|
||||||
* Modifies dataframe and adds dataLinks from the config.
|
|
||||||
* Exported for tests.
|
|
||||||
*/
|
|
||||||
export function enhanceDataFrame(dataFrame: DataFrame, dataLinks: DataLinkConfig[], limit?: number) {
|
|
||||||
if (limit) {
|
|
||||||
dataFrame.meta = {
|
|
||||||
...dataFrame.meta,
|
|
||||||
limit,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dataLinks.length) {
|
if (!dataLinks.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user