The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/alerting/unified/utils/rules.ts

118 lines
3.7 KiB

import { AlertState } from '@grafana/data';
import {
GrafanaAlertState,
PromAlertingRuleState,
PromRuleType,
RulerAlertingRuleDTO,
RulerGrafanaRuleDTO,
RulerRecordingRuleDTO,
RulerRuleDTO,
} from 'app/types/unified-alerting-dto';
import {
Alert,
AlertingRule,
CloudRuleIdentifier,
GrafanaRuleIdentifier,
PrometheusRuleIdentifier,
PromRuleWithLocation,
RecordingRule,
Rule,
RuleIdentifier,
RuleNamespace,
} from 'app/types/unified-alerting';
import { AsyncRequestState } from './redux';
import { RULER_NOT_SUPPORTED_MSG } from './constants';
import { capitalize } from 'lodash';
import { State } from '../components/StateTag';
export function isAlertingRule(rule: Rule | undefined): rule is AlertingRule {
return typeof rule === 'object' && rule.type === PromRuleType.Alerting;
}
export function isRecordingRule(rule: Rule): rule is RecordingRule {
return rule.type === PromRuleType.Recording;
}
export function isAlertingRulerRule(rule?: RulerRuleDTO): rule is RulerAlertingRuleDTO {
return typeof rule === 'object' && 'alert' in rule;
}
export function isRecordingRulerRule(rule?: RulerRuleDTO): rule is RulerRecordingRuleDTO {
return typeof rule === 'object' && 'record' in rule;
}
export function isGrafanaRulerRule(rule?: RulerRuleDTO): rule is RulerGrafanaRuleDTO {
return typeof rule === 'object' && 'grafana_alert' in rule;
}
export function alertInstanceKey(alert: Alert): string {
return JSON.stringify(alert.labels);
}
export function isRulerNotSupportedResponse(resp: AsyncRequestState<any>) {
return resp.error && resp.error?.message === RULER_NOT_SUPPORTED_MSG;
}
export function isGrafanaRuleIdentifier(identifier: RuleIdentifier): identifier is GrafanaRuleIdentifier {
return 'uid' in identifier;
}
export function isCloudRuleIdentifier(identifier: RuleIdentifier): identifier is CloudRuleIdentifier {
return 'rulerRuleHash' in identifier;
}
export function isPrometheusRuleIdentifier(identifier: RuleIdentifier): identifier is PrometheusRuleIdentifier {
return 'ruleHash' in identifier;
}
export function alertStateToReadable(state: PromAlertingRuleState | GrafanaAlertState | AlertState): string {
if (state === PromAlertingRuleState.Inactive) {
return 'Normal';
}
return capitalize(state);
}
export const flattenRules = (rules: RuleNamespace[]) => {
return rules.reduce<PromRuleWithLocation[]>((acc, { dataSourceName, name: namespaceName, groups }) => {
groups.forEach(({ name: groupName, rules }) => {
rules.forEach((rule) => {
if (isAlertingRule(rule)) {
acc.push({ dataSourceName, namespaceName, groupName, rule });
}
});
});
return acc;
}, []);
};
export const alertStateToState: Record<PromAlertingRuleState | GrafanaAlertState | AlertState, State> = {
[PromAlertingRuleState.Inactive]: 'good',
[PromAlertingRuleState.Firing]: 'bad',
[PromAlertingRuleState.Pending]: 'warning',
[GrafanaAlertState.Alerting]: 'bad',
[GrafanaAlertState.Error]: 'bad',
[GrafanaAlertState.NoData]: 'info',
[GrafanaAlertState.Normal]: 'good',
[GrafanaAlertState.Pending]: 'warning',
[AlertState.NoData]: 'info',
[AlertState.Paused]: 'warning',
[AlertState.Alerting]: 'bad',
[AlertState.OK]: 'good',
[AlertState.Pending]: 'warning',
[AlertState.Unknown]: 'info',
};
export function getFirstActiveAt(promRule: AlertingRule) {
if (!promRule.alerts) {
return null;
}
return promRule.alerts.reduce((prev, alert) => {
if (alert.activeAt && alert.state !== GrafanaAlertState.Normal) {
const activeAt = new Date(alert.activeAt);
if (prev === null || prev.getTime() > activeAt.getTime()) {
return activeAt;
}
}
return prev;
}, null as Date | null);
}