Correlation: Fix loki dataplane field change (#94088)

* Fix loki dataplane field change

* Add test for dataplane

* Reset feature toggle in test
This commit is contained in:
Kristina 2024-11-19 09:06:16 -06:00 committed by GitHub
parent 4cc28c76fb
commit 32de1a00d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 10 deletions

View File

@ -1,15 +1,17 @@
import { DataFrame, DataSourceInstanceSettings, FieldType, toDataFrame } from '@grafana/data';
import { DataFrame, DataFrameType, DataSourceInstanceSettings, FieldType, toDataFrame } from '@grafana/data';
import { config } from '@grafana/runtime';
import { CorrelationData } from './useCorrelations';
import { attachCorrelationsToDataFrames } from './utils';
describe('correlations utils', () => {
it('attaches correlations defined in the configuration', () => {
config.featureToggles.lokiLogsDataplane = false;
const { testDataFrames, correlations, refIdMap, prometheus, elastic } = setup();
attachCorrelationsToDataFrames(testDataFrames, correlations, refIdMap);
// Loki line (no links)
expect(testDataFrames[0].fields[0].config.links).toHaveLength(0);
// Loki line
expect(testDataFrames[0].fields[0].config.links).toHaveLength(1);
// Loki traceId (linked to Prometheus and Elastic)
expect(testDataFrames[0].fields[1].config.links).toHaveLength(2);
expect(testDataFrames[0].fields[1].config.links).toMatchObject([
@ -68,10 +70,29 @@ describe('correlations utils', () => {
// Prometheus value (linked to Elastic)
expect(testDataFrames[2].fields[0].config.links).toHaveLength(1);
});
it('changes the config field if loki dataplane is being used and the correlation is pointing to the legacy body field (Line)', () => {
const originalDataplaneState = config.featureToggles.lokiLogsDataplane;
config.featureToggles.lokiLogsDataplane = true;
const { correlations, refIdMap } = setup();
const testDataFrame = toDataFrame({
name: 'Loki Logs',
refId: 'Loki Query',
fields: [
{ name: 'timestamp', values: [], type: FieldType.time },
{ name: 'body', values: [], type: FieldType.string },
{ name: 'traceId', values: [], type: FieldType.string },
],
meta: { type: DataFrameType.LogLines },
});
const dataFrameOut = attachCorrelationsToDataFrames([testDataFrame], [correlations[3]], refIdMap);
expect(dataFrameOut[0].fields[1].config.links).toHaveLength(1);
config.featureToggles.lokiLogsDataplane = originalDataplaneState;
});
});
function setup() {
const loki = { uid: 'loki-uid', name: 'loki' } as DataSourceInstanceSettings;
const loki = { uid: 'loki-uid', name: 'loki', meta: { id: 'loki' } } as DataSourceInstanceSettings;
const elastic = { uid: 'elastic-uid', name: 'elastic' } as DataSourceInstanceSettings;
const prometheus = { uid: 'prometheus-uid', name: 'prometheus' } as DataSourceInstanceSettings;
@ -86,15 +107,15 @@ function setup() {
name: 'Loki Logs',
refId: 'Loki Query',
fields: [
{ name: 'line', values: [] },
{ name: 'traceId', values: [] },
{ name: 'Line', values: [], type: FieldType.string },
{ name: 'traceId', values: [], type: FieldType.string },
],
}),
toDataFrame({
name: 'Elastic Logs',
refId: 'Elastic Query',
fields: [
{ name: 'line', values: [] },
{ name: 'Line', values: [] },
{ name: 'traceId', values: [] },
],
}),
@ -134,7 +155,16 @@ function setup() {
config: { field: 'value', target: { expr: 'target Elastic query' } },
provisioned: false,
},
{
uid: 'loki-to-loki',
label: 'logs to logs',
source: loki,
target: loki,
type: 'query',
config: { field: 'Line', target: { expr: 'target loki query' } },
provisioned: false,
},
];
return { testDataFrames, correlations, refIdMap, prometheus, elastic };
return { testDataFrames, correlations, refIdMap, loki, prometheus, elastic };
}

View File

@ -1,10 +1,11 @@
import { lastValueFrom } from 'rxjs';
import { DataFrame, DataLinkConfigOrigin } from '@grafana/data';
import { createMonitoringLogger, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { config, createMonitoringLogger, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { ExploreItemState } from 'app/types';
import { formatValueName } from '../explore/PrometheusListView/ItemLabels';
import { parseLogsFrame } from '../logs/logsFrame';
import { CreateCorrelationParams, CreateCorrelationResponse } from './types';
import {
@ -43,7 +44,7 @@ export const attachCorrelationsToDataFrames = (
}
const sourceCorrelations = correlations.filter((correlation) => correlation.source.uid === dataSourceUid);
decorateDataFrameWithInternalDataLinks(dataFrame, sourceCorrelations);
decorateDataFrameWithInternalDataLinks(dataFrame, fixLokiDataplaneFields(sourceCorrelations, dataFrame));
});
return dataFrames;
@ -83,6 +84,27 @@ const decorateDataFrameWithInternalDataLinks = (dataFrame: DataFrame, correlatio
});
};
/*
If a correlation was made based on the log line field prior to the loki data plane, they would use the field "Line"
Change it to use whatever the body field name is post-loki data plane
*/
const fixLokiDataplaneFields = (correlations: CorrelationData[], dataFrame: DataFrame) => {
return correlations.map((correlation) => {
if (
correlation.source.meta?.id === 'loki' &&
config.featureToggles.lokiLogsDataplane === true &&
correlation.config.field === 'Line'
) {
const logsFrame = parseLogsFrame(dataFrame);
if (logsFrame != null && logsFrame.bodyField.name !== undefined) {
correlation.config.field = logsFrame?.bodyField.name;
}
}
return correlation;
});
};
export const getCorrelationsBySourceUIDs = async (sourceUIDs: string[]): Promise<CorrelationsData> => {
return lastValueFrom(
getBackendSrv().fetch<CorrelationsResponse>({