mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 00:25:46 -06:00
Alerting: Fix renaming queries and rewiring expressions (#71657)
This commit is contained in:
parent
d183a241e9
commit
ba470fb34d
@ -63,7 +63,6 @@ export const Expression: FC<ExpressionProps> = ({
|
||||
const seriesCount = series.length;
|
||||
|
||||
const alertCondition = isAlertCondition ?? false;
|
||||
//const showSummary = isAlertCondition && hasResults;
|
||||
|
||||
const groupedByState = {
|
||||
[PromAlertingRuleState.Firing]: series.filter((serie) => getSeriesValue(serie) !== 0),
|
||||
@ -225,9 +224,15 @@ export const PreviewSummary: FC<{ firing: number; normal: number; isCondition: b
|
||||
seriesCount,
|
||||
}) => {
|
||||
const { mutedText } = useStyles2(getStyles);
|
||||
|
||||
if (seriesCount === 0) {
|
||||
return <span className={mutedText}>No series</span>;
|
||||
}
|
||||
|
||||
if (isCondition) {
|
||||
return <span className={mutedText}>{`${seriesCount} series: ${firing} firing, ${normal} normal`}</span>;
|
||||
}
|
||||
|
||||
return <span className={mutedText}>{`${seriesCount} series`}</span>;
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ import { NeedHelpInfo } from '../NeedHelpInfo';
|
||||
import { QueryEditor } from '../QueryEditor';
|
||||
import { RecordingRuleEditor } from '../RecordingRuleEditor';
|
||||
import { RuleEditorSection } from '../RuleEditorSection';
|
||||
import { errorFromSeries, refIdExists } from '../util';
|
||||
import { errorFromSeries, refIdExists, findRenamedDataQueryReferences } from '../util';
|
||||
|
||||
import { CloudDataSourceSelector } from './CloudDataSourceSelector';
|
||||
import { SmartAlertTypeDetector } from './SmartAlertTypeDetector';
|
||||
@ -161,15 +161,12 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
|
||||
|
||||
dispatch(setDataQueries(updatedQueries));
|
||||
dispatch(updateExpressionTimeRange());
|
||||
// check if we need to rewire expressions
|
||||
updatedQueries.forEach((query, index) => {
|
||||
const oldRefId = queries[index].refId;
|
||||
const newRefId = query.refId;
|
||||
|
||||
if (oldRefId !== newRefId) {
|
||||
dispatch(rewireExpressions({ oldRefId, newRefId }));
|
||||
}
|
||||
});
|
||||
// check if we need to rewire expressions (and which ones)
|
||||
const [oldRefId, newRefId] = findRenamedDataQueryReferences(queries, updatedQueries);
|
||||
if (oldRefId && newRefId) {
|
||||
dispatch(rewireExpressions({ oldRefId, newRefId }));
|
||||
}
|
||||
},
|
||||
[queries, setValue, updateExpressionAndDatasource]
|
||||
);
|
||||
@ -539,9 +536,14 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
|
||||
const useSetExpressionAndDataSource = () => {
|
||||
const { setValue } = useFormContext<RuleFormValues>();
|
||||
|
||||
return (updatedQueries: AlertQuery[]) => {
|
||||
// update data source name and expression if it's been changed in the queries from the reducer when prom or loki query
|
||||
const query = updatedQueries[0];
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataSourceSettings = getDataSourceSrv().getInstanceSettings(query.datasourceUid);
|
||||
if (!dataSourceSettings) {
|
||||
throw new Error('The Data source has not been defined.');
|
||||
|
@ -4,6 +4,7 @@ import { AlertQuery } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import {
|
||||
checkForPathSeparator,
|
||||
findRenamedDataQueryReferences,
|
||||
getThresholdsForQueries,
|
||||
queriesWithUpdatedReferences,
|
||||
updateMathExpressionRefs,
|
||||
@ -404,3 +405,33 @@ function createThresholdExample(thresholdType: string): AlertQuery[] {
|
||||
|
||||
return [dataQuery, reduceExpression, thresholdExpression];
|
||||
}
|
||||
|
||||
describe('findRenamedReferences', () => {
|
||||
it('should find the renamed ids', () => {
|
||||
const previous = [{ refId: 'A' }, { refId: 'B' }, { refId: 'C' }] as AlertQuery[];
|
||||
const updated = [{ refId: 'FOO' }, { refId: 'B' }, { refId: 'C' }] as AlertQuery[];
|
||||
|
||||
expect(findRenamedDataQueryReferences(previous, updated)).toEqual(['A', 'FOO']);
|
||||
});
|
||||
|
||||
it('should ignore expression queries', () => {
|
||||
// @ts-expect-error
|
||||
const previous = [
|
||||
{ refId: 'A' },
|
||||
{ refId: 'REDUCE', model: { datasource: '-100' } },
|
||||
{ refId: 'MATH', model: { datasource: '-100' } },
|
||||
{ refId: 'B' },
|
||||
{ refId: 'C' },
|
||||
] as AlertQuery[];
|
||||
|
||||
// @ts-expect-error
|
||||
const updated = [
|
||||
{ refId: 'FOO' },
|
||||
{ refId: 'REDUCE', model: { datasource: '-100' } },
|
||||
{ refId: 'B' },
|
||||
{ refId: 'C' },
|
||||
] as AlertQuery[];
|
||||
|
||||
expect(findRenamedDataQueryReferences(previous, updated)).toEqual(['A', 'FOO']);
|
||||
});
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { xor } from 'lodash';
|
||||
import { ValidateResult } from 'react-hook-form';
|
||||
|
||||
import { DataFrame, ThresholdsConfig, ThresholdsMode, isTimeSeriesFrames, PanelData } from '@grafana/data';
|
||||
@ -303,3 +304,28 @@ export function translateRouteParamToRuleType(param = ''): RuleFormType {
|
||||
|
||||
return RuleFormType.grafana;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function finds what refIds have been updated given the previous Array of queries and an Array of updated data queries.
|
||||
* All expression queries are discarded from the arrays, since we have separate handlers for those (see "onUpdateRefId") of the ExpressionEditor
|
||||
*
|
||||
* This code assumes not more than 1 query refId has changed per "onChangeQueries",
|
||||
*/
|
||||
export function findRenamedDataQueryReferences(
|
||||
previousQueries: AlertQuery[],
|
||||
updatedQueries: AlertQuery[]
|
||||
): [string, string] {
|
||||
const updatedDataQueries = updatedQueries
|
||||
.filter((query) => !isExpressionQuery(query.model))
|
||||
.map((query) => query.refId);
|
||||
const previousDataQueries = previousQueries
|
||||
.filter((query) => !isExpressionQuery(query.model))
|
||||
.map((query) => query.refId);
|
||||
|
||||
// given the following two arrays
|
||||
// ['A', 'B', 'C'] and ['FOO', 'B' 'C']
|
||||
// the "xor" function will return ['A', 'FOO'] because those are not in both arrays
|
||||
const [oldRefId, newRefId] = xor(previousDataQueries, updatedDataQueries);
|
||||
|
||||
return [oldRefId, newRefId];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user