mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add filters for AlertList panel (#43130)
* add state filters for prom alerts * combine state filters * add datasource filter for panel * remove duplicate state check * show only prom, loki, and grafana datasources
This commit is contained in:
parent
be498f312e
commit
187a8703c8
@ -4,6 +4,7 @@ import { RulesSource } from 'app/types/unified-alerting';
|
||||
import { getAllDataSources } from './config';
|
||||
|
||||
export const GRAFANA_RULES_SOURCE_NAME = 'grafana';
|
||||
export const GRAFANA_DATASOURCE_NAME = '-- Grafana --';
|
||||
|
||||
export enum DataSourceType {
|
||||
Alertmanager = 'alertmanager',
|
||||
|
@ -8,7 +8,6 @@ import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-aler
|
||||
import { UnifiedAlertListOptions } from './types';
|
||||
import { AlertInstancesTable } from 'app/features/alerting/unified/components/rules/AlertInstancesTable';
|
||||
import { sortAlerts } from 'app/features/alerting/unified/utils/misc';
|
||||
import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager';
|
||||
|
||||
interface Props {
|
||||
ruleWithLocation: PromRuleWithLocation;
|
||||
@ -44,23 +43,22 @@ export const AlertInstances = ({ ruleWithLocation, options }: Props) => {
|
||||
};
|
||||
|
||||
function filterAlerts(options: PanelProps<UnifiedAlertListOptions>['options'], alerts: Alert[]): Alert[] {
|
||||
const hasAlertState = Object.values(options.stateFilter).some((value) => value);
|
||||
let filteredAlerts = [...alerts];
|
||||
if (options.alertInstanceLabelFilter) {
|
||||
const matchers = parseMatchers(options.alertInstanceLabelFilter || '');
|
||||
filteredAlerts = filteredAlerts.filter(({ labels }) => labelsMatchMatchers(labels, matchers));
|
||||
}
|
||||
if (Object.values(options.alertInstanceStateFilter).some((value) => value)) {
|
||||
if (hasAlertState) {
|
||||
filteredAlerts = filteredAlerts.filter((alert) => {
|
||||
return (
|
||||
(options.alertInstanceStateFilter.Alerting && alert.state === GrafanaAlertState.Alerting) ||
|
||||
(options.alertInstanceStateFilter.Pending && alert.state === GrafanaAlertState.Pending) ||
|
||||
(options.alertInstanceStateFilter.NoData && alert.state === GrafanaAlertState.NoData) ||
|
||||
(options.alertInstanceStateFilter.Normal && alert.state === GrafanaAlertState.Normal) ||
|
||||
(options.alertInstanceStateFilter.Error && alert.state === GrafanaAlertState.Error)
|
||||
(options.stateFilter.firing &&
|
||||
(alert.state === GrafanaAlertState.Alerting || alert.state === PromAlertingRuleState.Firing)) ||
|
||||
(options.stateFilter.pending &&
|
||||
(alert.state === GrafanaAlertState.Pending || alert.state === PromAlertingRuleState.Pending)) ||
|
||||
(options.stateFilter.noData && alert.state === GrafanaAlertState.NoData) ||
|
||||
(options.stateFilter.normal && alert.state === GrafanaAlertState.Normal) ||
|
||||
(options.stateFilter.error && alert.state === GrafanaAlertState.Error) ||
|
||||
(options.stateFilter.inactive && alert.state === PromAlertingRuleState.Inactive)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return filteredAlerts;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,15 @@ import { flattenRules, alertStateToState, getFirstActiveAt } from 'app/features/
|
||||
import { PromRuleWithLocation } from 'app/types/unified-alerting';
|
||||
import { fetchAllPromRulesAction } from 'app/features/alerting/unified/state/actions';
|
||||
import { useUnifiedAlertingSelector } from 'app/features/alerting/unified/hooks/useUnifiedAlertingSelector';
|
||||
import { getAllRulesSourceNames } from 'app/features/alerting/unified/utils/datasource';
|
||||
import {
|
||||
getAllRulesSourceNames,
|
||||
GRAFANA_DATASOURCE_NAME,
|
||||
GRAFANA_RULES_SOURCE_NAME,
|
||||
} from 'app/features/alerting/unified/utils/datasource';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { Annotation, RULE_LIST_POLL_INTERVAL_MS } from 'app/features/alerting/unified/utils/constants';
|
||||
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
|
||||
import { labelsMatchMatchers, parseMatchers } from 'app/features/alerting/unified/utils/alertmanager';
|
||||
|
||||
export function UnifiedAlertList(props: PanelProps<UnifiedAlertListOptions>) {
|
||||
const dispatch = useDispatch();
|
||||
@ -151,11 +156,31 @@ function filterRules(options: PanelProps<UnifiedAlertListOptions>['options'], ru
|
||||
);
|
||||
});
|
||||
}
|
||||
if (options.alertInstanceLabelFilter) {
|
||||
const matchers = parseMatchers(options.alertInstanceLabelFilter);
|
||||
// Reduce rules and instances to only those that match
|
||||
filteredRules = filteredRules.reduce((rules, rule) => {
|
||||
const filteredAlerts = rule.rule.alerts.filter(({ labels }) => labelsMatchMatchers(labels, matchers));
|
||||
if (filteredAlerts.length) {
|
||||
rules.push({ ...rule, rule: { ...rule.rule, alerts: filteredAlerts } });
|
||||
}
|
||||
return rules;
|
||||
}, [] as PromRuleWithLocation[]);
|
||||
}
|
||||
if (options.folder) {
|
||||
filteredRules = filteredRules.filter((rule) => {
|
||||
return rule.namespaceName === options.folder.title;
|
||||
});
|
||||
}
|
||||
if (options.datasource) {
|
||||
const isGrafanaDS = options.datasource === GRAFANA_DATASOURCE_NAME;
|
||||
|
||||
filteredRules = filteredRules.filter(
|
||||
isGrafanaDS
|
||||
? ({ dataSourceName }) => dataSourceName === GRAFANA_RULES_SOURCE_NAME
|
||||
: ({ dataSourceName }) => dataSourceName === options.datasource
|
||||
);
|
||||
}
|
||||
|
||||
return filteredRules;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { AlertList } from './AlertList';
|
||||
import { UnifiedAlertList } from './UnifiedAlertList';
|
||||
import { AlertListOptions, ShowOption, SortOrder, UnifiedAlertListOptions } from './types';
|
||||
import { alertListPanelMigrationHandler } from './AlertListMigrationHandler';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { config, DataSourcePicker } from '@grafana/runtime';
|
||||
import { RuleFolderPicker } from 'app/features/alerting/unified/components/rule-editor/RuleFolderPicker';
|
||||
import {
|
||||
ALL_FOLDER,
|
||||
@ -221,9 +221,29 @@ const unifiedAlertList = new PanelPlugin<UnifiedAlertListOptions>(UnifiedAlertLi
|
||||
},
|
||||
category: ['Filter'],
|
||||
})
|
||||
.addCustomEditor({
|
||||
path: 'datasource',
|
||||
name: 'Datasource',
|
||||
description: 'Filter alerts from selected datasource',
|
||||
id: 'datasource',
|
||||
defaultValue: null,
|
||||
editor: function RenderDatasourcePicker(props) {
|
||||
return (
|
||||
<DataSourcePicker
|
||||
{...props}
|
||||
type={['prometheus', 'loki', 'grafana']}
|
||||
noDefault
|
||||
current={props.value}
|
||||
onChange={(ds) => props.onChange(ds.name)}
|
||||
onClear={() => props.onChange('')}
|
||||
/>
|
||||
);
|
||||
},
|
||||
category: ['Filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'stateFilter.firing',
|
||||
name: 'Alerting',
|
||||
name: 'Alerting / Firing',
|
||||
defaultValue: true,
|
||||
category: ['Alert state filter'],
|
||||
})
|
||||
@ -240,34 +260,22 @@ const unifiedAlertList = new PanelPlugin<UnifiedAlertListOptions>(UnifiedAlertLi
|
||||
category: ['Alert state filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'alertInstanceStateFilter.Alerting',
|
||||
name: 'Alerting',
|
||||
defaultValue: true,
|
||||
category: ['Alert instance state filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'alertInstanceStateFilter.Pending',
|
||||
name: 'Pending',
|
||||
defaultValue: true,
|
||||
category: ['Alert instance state filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'alertInstanceStateFilter.NoData',
|
||||
path: 'stateFilter.noData',
|
||||
name: 'No Data',
|
||||
defaultValue: false,
|
||||
category: ['Alert instance state filter'],
|
||||
category: ['Alert state filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'alertInstanceStateFilter.Normal',
|
||||
path: 'stateFilter.normal',
|
||||
name: 'Normal',
|
||||
defaultValue: false,
|
||||
category: ['Alert instance state filter'],
|
||||
category: ['Alert state filter'],
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'alertInstanceStateFilter.Error',
|
||||
path: 'stateFilter.error',
|
||||
name: 'Error',
|
||||
defaultValue: true,
|
||||
category: ['Alert instance state filter'],
|
||||
category: ['Alert state filter'],
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
import { GrafanaAlertState, PromAlertingRuleState } from 'app/types/unified-alerting-dto';
|
||||
|
||||
export enum SortOrder {
|
||||
AlphaAsc = 1,
|
||||
AlphaDesc,
|
||||
@ -32,6 +30,15 @@ export interface AlertListOptions {
|
||||
folderId: number;
|
||||
}
|
||||
|
||||
interface StateFilter {
|
||||
firing: boolean;
|
||||
pending: boolean;
|
||||
inactive: boolean;
|
||||
noData: boolean;
|
||||
normal: boolean;
|
||||
error: boolean;
|
||||
}
|
||||
|
||||
export interface UnifiedAlertListOptions {
|
||||
maxItems: number;
|
||||
sortOrder: SortOrder;
|
||||
@ -39,11 +46,7 @@ export interface UnifiedAlertListOptions {
|
||||
alertName: string;
|
||||
showInstances: boolean;
|
||||
folder: { id: number; title: string };
|
||||
stateFilter: {
|
||||
[K in PromAlertingRuleState]: boolean;
|
||||
};
|
||||
stateFilter: StateFilter;
|
||||
alertInstanceLabelFilter: string;
|
||||
alertInstanceStateFilter: {
|
||||
[K in GrafanaAlertState]: boolean;
|
||||
};
|
||||
datasource: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user