Alerting: Move alert rule name to the top left in alert form (#58579)
* Move alert rule name to the top left in alert form, and add a placeholder * Update docs * Fix lint error
This commit is contained in:
@@ -23,21 +23,22 @@ Watch this video to learn more about creating alerts: {{< vimeo 720001934 >}}
|
||||
|
||||
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
|
||||
1. Click **New alert rule**. The new alerting rule page opens where the Grafana managed alerts option is selected by default.
|
||||
1. In Step 1, add queries and expressions to evaluate, and then select the alert condition.
|
||||
1. In Step 1, add the rule name.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 2, add queries and expressions to evaluate, and then select the alert condition.
|
||||
- For queries, select a data source from the drop-down.
|
||||
- Add one or more [queries]({{< relref "../../panels-visualizations/query-transform-data/#add-a-query/" >}}) or [expressions]({{< relref "../../panels-visualizations/query-transform-data/expression-queries/" >}}).
|
||||
- For each expression, select either **Classic condition** to create a single alert rule, or choose from **Math**, **Reduce**, **Resample** options to generate separate alert for each series. For details on these options, see [Single and multi dimensional rule](#single-and-multi-dimensional-rule).
|
||||
- Click **Run queries** to verify that the query is successful.
|
||||
- Next, select the query or expression for your alert condition.
|
||||
1. In Step 2, specify the alert evaluation interval.
|
||||
1. In Step 3, specify the alert evaluation interval.
|
||||
- From the **Condition** drop-down, select the query or expression to trigger the alert rule.
|
||||
- For **Evaluate every**, specify the frequency of evaluation. Must be a multiple of 10 seconds. For examples, `1m`, `30s`.
|
||||
- For **Evaluate for**, specify the duration for which the condition must be true before an alert fires.
|
||||
> **Note:** Once a condition is breached, the alert goes into the Pending state. If the condition remains breached for the duration specified, the alert transitions to the `Firing` state, otherwise it reverts back to the `Normal` state.
|
||||
- In **Configure no data and error handling**, configure alerting behavior in the absence of data. Use the guidelines in [No data and error handling](#no-data-and-error-handling).
|
||||
- Click **Preview alerts** to check the result of running the query at this moment. Preview excludes no data and error handling.
|
||||
1. In Step 3, add the rule name, storage location, rule group, as well as additional metadata associated with the rule.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 4, add the storage location, rule group, as well as additional metadata associated with the rule.
|
||||
- From the **Folder** drop-down, select the folder where you want to store the rule.
|
||||
- For **Group**, specify a pre-defined group. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
|
||||
|
||||
@@ -37,11 +37,12 @@ To create a Grafana Mimir or Loki managed recording rule
|
||||
|
||||
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
|
||||
1. Click **New alert rule**. The new alerting rule page opens where the **Grafana managed alert** option is selected by default.
|
||||
1. In Step 1, select **Mimir or Loki recording rule** option.
|
||||
1. In Step 1, add the rule name.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 2, select **Mimir or Loki recording rule** option.
|
||||
- Select your Loki or Prometheus data source, add the query to evaluate, and then select the alert condition.
|
||||
- Enter a PromQL or LogQL expression. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
|
||||
1. In Step 2, add the rule name, namespace, rule group, as well as additional metadata associated with the rule.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 3, add the namespace, rule group, as well as additional metadata associated with the rule.
|
||||
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click Add new and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose. For more information, see [Grafana Mimir or Loki rule groups and namespaces]({{< relref "edit-mimir-loki-namespace-group/" >}}).
|
||||
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
|
||||
@@ -52,17 +53,18 @@ To create a Grafana Mimir or Loki managed recording rule
|
||||
|
||||
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
|
||||
1. Click **New alert rule**.
|
||||
1. In Step 1, add the rule name, type, and storage location.
|
||||
1. In Step 1, add the rule name.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 2, add the type, and storage location.
|
||||
- From the **Rule type** drop-down, select **Mimir / Loki managed alert**.
|
||||
- From the **Select data source** drop-down, select an external Prometheus, an external Loki, or a Grafana Cloud data source.
|
||||
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose.
|
||||
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
{{< figure src="/static/img/docs/alerting/unified/rule-edit-mimir-alert-type-8-0.png" max-width="550px" caption="Alert details" >}}
|
||||
1. In Step 2, add the query to evaluate.
|
||||
1. In Step 3, add the query to evaluate.
|
||||
- Enter a PromQL or LogQL expression. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
|
||||
{{< figure src="/static/img/docs/alerting/unified/rule-edit-mimir-query-8-0.png" max-width="550px" caption="Alert details" >}}
|
||||
1. In Step 3, add additional metadata associated with the rule.
|
||||
1. In Step 4, add additional metadata associated with the rule.
|
||||
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
|
||||
- Add Runbook URL, panel, dashboard, and alert IDs.
|
||||
- Add custom labels.
|
||||
|
||||
@@ -37,14 +37,15 @@ Watch this video to learn more about how to create a Mimir managed alert rule: {
|
||||
|
||||
1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page listing existing alerts.
|
||||
1. Click **New alert rule**. The new alerting rule page opens where the Grafana managed alerts option is selected by default.
|
||||
1. In Step 1, select **Mimir or Loki alert** option.
|
||||
1. In Step 1, add the rule name.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 2, select **Mimir or Loki alert** option.
|
||||
- Next, select your Loki or Prometheus data source and add the query to evaluate.
|
||||
- Enter a PromQL or LogQL expression to query. The rule fires if the evaluation result has at least one series with a value that is greater than 0. An alert is created for each series.
|
||||
1. In Step 2, specify the alert evaluation interval.
|
||||
1. In Step 3, specify the alert evaluation interval.
|
||||
- In the **For** text box, specify the duration for which the condition must be true before an alert fires. If you specify `5m`, the condition must be true for 5 minutes before the alert fires.
|
||||
> **Note:** Once a condition is met, the alert goes into the `Pending` state. If the condition remains active for the duration specified, the alert transitions to the `Firing` state, else it reverts to the `Normal` state.
|
||||
1. In Step 3, add the rule name, namespace, rule group, as well as additional metadata associated with the rule.
|
||||
- In **Rule name**, add a descriptive name. This name is displayed in the alert rule list. It is also the `alertname` label for every alert instance that is created from this rule.
|
||||
1. In Step 4, add the namespace, rule group, as well as additional metadata associated with the rule.
|
||||
- From the **Namespace** drop-down, select an existing rule namespace. Otherwise, click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and only have an organizational purpose. For more information, see [Grafana Mimir or Loki rule groups and namespaces]({{< relref "edit-mimir-loki-namespace-group/" >}}).
|
||||
- From the **Group** drop-down, select an existing group within the selected namespace. Otherwise, click **Add new** and enter a name to create a new one. Newly created rules are appended to the end of the group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
- Add a description and summary to customize alert messages. Use the guidelines in [Annotations and labels for alerting]({{< relref "../fundamentals/annotation-label/" >}}).
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
||||
import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector';
|
||||
import { byRole, byTestId, byText } from 'testing-library-selector';
|
||||
|
||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@@ -76,7 +76,7 @@ function renderRuleEditor(identifier?: string) {
|
||||
|
||||
const ui = {
|
||||
inputs: {
|
||||
name: byLabelText('Rule name'),
|
||||
name: byRole('textbox', { name: /rule name name for the alert rule\./i }),
|
||||
alertType: byTestId('alert-type-picker'),
|
||||
dataSource: byTestId('datasource-picker'),
|
||||
folder: byTestId('folder-picker'),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { FC, useMemo, useState } from 'react';
|
||||
import { FormProvider, useForm, UseFormWatch } from 'react-hook-form';
|
||||
import { FormProvider, useForm, useFormContext, UseFormWatch } from 'react-hook-form';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { logInfo } from '@grafana/runtime';
|
||||
import { Button, ConfirmModal, CustomScrollbar, Spinner, useStyles2, HorizontalGroup } from '@grafana/ui';
|
||||
import { Button, ConfirmModal, CustomScrollbar, Spinner, useStyles2, HorizontalGroup, Field, Input } from '@grafana/ui';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { useCleanup } from 'app/core/hooks/useCleanup';
|
||||
import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
@@ -24,8 +24,57 @@ import { CloudEvaluationBehavior } from './CloudEvaluationBehavior';
|
||||
import { DetailsStep } from './DetailsStep';
|
||||
import { GrafanaEvaluationBehavior } from './GrafanaEvaluationBehavior';
|
||||
import { NotificationsStep } from './NotificationsStep';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
import { RuleInspector } from './RuleInspector';
|
||||
import { QueryAndExpressionsStep } from './query-and-alert-condition/QueryAndExpressionsStep';
|
||||
import { checkForPathSeparator } from './util';
|
||||
|
||||
const recordingRuleNameValidationPattern = {
|
||||
message:
|
||||
'Recording rule name must be valid metric name. It may only contain letters, numbers, and colons. It may not contain whitespace.',
|
||||
value: /^[a-zA-Z_:][a-zA-Z0-9_:]*$/,
|
||||
};
|
||||
|
||||
const AlertRuleNameInput = () => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const {
|
||||
register,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useFormContext<RuleFormValues & { location?: string }>();
|
||||
|
||||
const ruleFormType = watch('type');
|
||||
return (
|
||||
<RuleEditorSection stepNo={1} title="Set an alert rule name">
|
||||
<Field
|
||||
className={styles.formInput}
|
||||
label="Rule name"
|
||||
description="Name for the alert rule."
|
||||
error={errors?.name?.message}
|
||||
invalid={!!errors.name?.message}
|
||||
>
|
||||
<Input
|
||||
id="name"
|
||||
{...register('name', {
|
||||
required: { value: true, message: 'Must enter an alert name' },
|
||||
pattern: ruleFormType === RuleFormType.cloudRecording ? recordingRuleNameValidationPattern : undefined,
|
||||
validate: {
|
||||
pathSeparator: (value: string) => {
|
||||
// we use the alert rule name as the "groupname" for Grafana managed alerts, so we can't allow path separators
|
||||
if (ruleFormType === RuleFormType.grafana) {
|
||||
return checkForPathSeparator(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
})}
|
||||
placeholder="Give your alert rule a name."
|
||||
/>
|
||||
</Field>
|
||||
</RuleEditorSection>
|
||||
);
|
||||
};
|
||||
|
||||
type Props = {
|
||||
existing?: RuleWithLocation;
|
||||
@@ -160,6 +209,7 @@ export const AlertRuleForm: FC<Props> = ({ existing }) => {
|
||||
<div className={styles.contentOuter}>
|
||||
<CustomScrollbar autoHeightMin="100%" hideHorizontalTrack={true}>
|
||||
<div className={styles.contentInner}>
|
||||
<AlertRuleNameInput />
|
||||
<QueryAndExpressionsStep editingExistingRule={!!existing} />
|
||||
{showStep2 && (
|
||||
<>
|
||||
@@ -222,5 +272,12 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
`,
|
||||
formInput: css`
|
||||
width: 275px;
|
||||
|
||||
& + & {
|
||||
margin-left: ${theme.spacing(3)};
|
||||
}
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export const CloudEvaluationBehavior = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<RuleEditorSection stepNo={2} title="Alert evaluation behavior">
|
||||
<RuleEditorSection stepNo={3} title="Alert evaluation behavior">
|
||||
<Field label="For" description="Expression has to be true for this long for the alert to be fired.">
|
||||
<div className={styles.flexRow}>
|
||||
<Field invalid={!!errors.forTime?.message} error={errors.forTime?.message} className={styles.inlineField}>
|
||||
|
||||
@@ -19,12 +19,6 @@ import { RuleEditorSection } from './RuleEditorSection';
|
||||
import { RuleFolderPicker, Folder, containsSlashes } from './RuleFolderPicker';
|
||||
import { checkForPathSeparator } from './util';
|
||||
|
||||
const recordingRuleNameValidationPattern = {
|
||||
message:
|
||||
'Recording rule name must be valid metric name. It may only contain letters, numbers, and colons. It may not contain whitespace.',
|
||||
value: /^[a-zA-Z_:][a-zA-Z0-9_:]*$/,
|
||||
};
|
||||
|
||||
interface DetailsStepProps {
|
||||
initialFolder: RuleForm | null;
|
||||
}
|
||||
@@ -46,7 +40,7 @@ export const DetailsStep = ({ initialFolder }: DetailsStepProps) => {
|
||||
|
||||
return (
|
||||
<RuleEditorSection
|
||||
stepNo={type === RuleFormType.cloudRecording ? 2 : 3}
|
||||
stepNo={type === RuleFormType.cloudRecording ? 3 : 4}
|
||||
title={
|
||||
type === RuleFormType.cloudRecording ? 'Add details for your recording rule' : 'Add details for your alert'
|
||||
}
|
||||
@@ -56,31 +50,6 @@ export const DetailsStep = ({ initialFolder }: DetailsStepProps) => {
|
||||
: 'Write a summary and add labels to help you better manage your alerts'
|
||||
}
|
||||
>
|
||||
<Field
|
||||
className={styles.formInput}
|
||||
label="Rule name"
|
||||
error={errors?.name?.message}
|
||||
invalid={!!errors.name?.message}
|
||||
>
|
||||
<Input
|
||||
id="name"
|
||||
{...register('name', {
|
||||
required: { value: true, message: 'Must enter an alert name' },
|
||||
pattern: ruleFormType === RuleFormType.cloudRecording ? recordingRuleNameValidationPattern : undefined,
|
||||
validate: {
|
||||
pathSeparator: (value: string) => {
|
||||
// we use the alert rule name as the "groupname" for Grafana managed alerts, so we can't allow path separators
|
||||
if (ruleFormType === RuleFormType.grafana) {
|
||||
return checkForPathSeparator(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
{(ruleFormType === RuleFormType.cloudRecording || ruleFormType === RuleFormType.cloudAlerting) &&
|
||||
dataSourceName && <GroupAndNamespaceFields rulesSourceName={dataSourceName} />}
|
||||
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ export const GrafanaEvaluationBehavior = () => {
|
||||
|
||||
return (
|
||||
// TODO remove "and alert condition" for recording rules
|
||||
<RuleEditorSection stepNo={2} title="Alert evaluation behavior">
|
||||
<RuleEditorSection stepNo={3} title="Alert evaluation behavior">
|
||||
<Field
|
||||
label="Evaluate"
|
||||
description="Evaluation interval applies to every rule within a group. It can overwrite the interval of an existing alert rule."
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useFormContext } from 'react-hook-form';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Card, Link, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
|
||||
import { RuleFormValues } from '../../types/rule-form';
|
||||
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';
|
||||
|
||||
import LabelsField from './LabelsField';
|
||||
@@ -15,14 +15,15 @@ export const NotificationsStep = () => {
|
||||
const [hideFlowChart, setHideFlowChart] = useState(false);
|
||||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
const { watch } = useFormContext<RuleFormValues & { location?: string }>();
|
||||
|
||||
const { watch } = useFormContext<RuleFormValues>();
|
||||
const type = watch('type');
|
||||
|
||||
const dataSourceName = watch('dataSourceName') ?? GRAFANA_RULES_SOURCE_NAME;
|
||||
|
||||
return (
|
||||
<RuleEditorSection
|
||||
stepNo={4}
|
||||
stepNo={type === RuleFormType.cloudRecording ? 4 : 5}
|
||||
title="Notifications"
|
||||
description="Grafana handles the notifications for alerts by assigning labels to alerts. These labels connect alerts to contact points and silence alert instances that have matching labels."
|
||||
>
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ export const QueryAndExpressionsStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
}, [condition, queries, setValue]);
|
||||
|
||||
return (
|
||||
<RuleEditorSection stepNo={1} title="Set a query and alert condition">
|
||||
<RuleEditorSection stepNo={2} title="Set a query and alert condition">
|
||||
<AlertType editingExistingRule={editingExistingRule} />
|
||||
|
||||
{/* This is the PromQL Editor for Cloud rules and recording rules */}
|
||||
|
||||
Reference in New Issue
Block a user