mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: allow creating/editing recording rules for Loki and Cortex (#38064)
This commit is contained in:
@@ -121,7 +121,7 @@ export const AlertRuleForm: FC<Props> = ({ existing }) => {
|
||||
{showStep2 && (
|
||||
<>
|
||||
<QueryStep />
|
||||
{type === RuleFormType.cloud ? <CloudConditionsStep /> : <GrafanaConditionsStep />}
|
||||
{type === RuleFormType.grafana ? <GrafanaConditionsStep /> : <CloudConditionsStep />}
|
||||
<DetailsStep />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -40,19 +40,24 @@ export const AlertTypeStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
if (contextSrv.isEditor) {
|
||||
result.push({
|
||||
label: 'Cortex/Loki managed alert',
|
||||
value: RuleFormType.cloud,
|
||||
value: RuleFormType.cloudAlerting,
|
||||
description: 'Alert based on a system or application behavior. Based on Prometheus.',
|
||||
});
|
||||
result.push({
|
||||
label: 'Cortex/Loki managed recording rule',
|
||||
value: RuleFormType.cloudRecording,
|
||||
description: 'Recording rule to pre-compute frequently needed or expensive calculations. Based on Prometheus.',
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<RuleEditorSection stepNo={1} title="Alert type">
|
||||
<RuleEditorSection stepNo={1} title="Rule type">
|
||||
<Field
|
||||
className={styles.formInput}
|
||||
label="Alert name"
|
||||
label="Rule name"
|
||||
error={errors?.name?.message}
|
||||
invalid={!!errors.name?.message}
|
||||
>
|
||||
@@ -65,7 +70,7 @@ export const AlertTypeStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
<div className={styles.flexRow}>
|
||||
<Field
|
||||
disabled={editingExistingRule}
|
||||
label="Alert type"
|
||||
label="Rule type"
|
||||
className={styles.formInput}
|
||||
error={errors.type?.message}
|
||||
invalid={!!errors.type?.message}
|
||||
@@ -87,7 +92,7 @@ export const AlertTypeStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
{ruleFormType === RuleFormType.cloud && (
|
||||
{(ruleFormType === RuleFormType.cloudRecording || ruleFormType === RuleFormType.cloudAlerting) && (
|
||||
<Field
|
||||
className={styles.formInput}
|
||||
label="Select data source"
|
||||
@@ -115,9 +120,9 @@ export const AlertTypeStep: FC<Props> = ({ editingExistingRule }) => {
|
||||
</Field>
|
||||
)}
|
||||
</div>
|
||||
{ruleFormType === RuleFormType.cloud && dataSourceName && (
|
||||
<GroupAndNamespaceFields dataSourceName={dataSourceName} />
|
||||
)}
|
||||
{(ruleFormType === RuleFormType.cloudRecording || ruleFormType === RuleFormType.cloudAlerting) &&
|
||||
dataSourceName && <GroupAndNamespaceFields dataSourceName={dataSourceName} />}
|
||||
|
||||
{ruleFormType === RuleFormType.grafana && (
|
||||
<Field
|
||||
label="Folder"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { css } from '@emotion/css';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { Field, Input, InputControl, Select, useStyles } from '@grafana/ui';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { RuleFormValues } from '../../types/rule-form';
|
||||
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
|
||||
import { timeOptions } from '../../utils/time';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
import { PreviewRule } from './PreviewRule';
|
||||
@@ -13,9 +13,17 @@ export const CloudConditionsStep: FC = () => {
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useFormContext<RuleFormValues>();
|
||||
|
||||
const type = watch('type');
|
||||
|
||||
// cloud recording rules do not have alert conditions
|
||||
if (type === RuleFormType.cloudRecording) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RuleEditorSection stepNo={3} title="Define alert conditions">
|
||||
<Field label="For" description="Expression has to be true for this long for the alert to be fired.">
|
||||
|
||||
@@ -2,15 +2,27 @@ import React, { FC } from 'react';
|
||||
import LabelsField from './LabelsField';
|
||||
import AnnotationsField from './AnnotationsField';
|
||||
import { RuleEditorSection } from './RuleEditorSection';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
|
||||
|
||||
export const DetailsStep: FC = () => {
|
||||
const { watch } = useFormContext<RuleFormValues>();
|
||||
|
||||
const type = watch('type');
|
||||
|
||||
return (
|
||||
<RuleEditorSection
|
||||
stepNo={4}
|
||||
title="Add details for your alert"
|
||||
description="Write a summary and add labels to help you better manage your alerts"
|
||||
stepNo={type === RuleFormType.cloudRecording ? 3 : 4}
|
||||
title={
|
||||
type === RuleFormType.cloudRecording ? 'Add details for your recording rule' : 'Add details for your alert'
|
||||
}
|
||||
description={
|
||||
type === RuleFormType.cloudRecording
|
||||
? 'Add labels to help you better manage your rules'
|
||||
: 'Write a summary and add labels to help you better manage your alerts'
|
||||
}
|
||||
>
|
||||
<AnnotationsField />
|
||||
{type !== RuleFormType.cloudRecording && <AnnotationsField />}
|
||||
<LabelsField />
|
||||
</RuleEditorSection>
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ export function PreviewRule(): React.ReactElement | null {
|
||||
const { getValues } = useFormContext();
|
||||
const [type] = getValues(fields);
|
||||
|
||||
if (type === RuleFormType.cloud) {
|
||||
if (type === RuleFormType.cloudRecording || type === RuleFormType.cloudAlerting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ function createPreviewRequest(values: any[]): PreviewRuleRequest {
|
||||
const [type, dataSourceName, condition, queries, expression] = values;
|
||||
|
||||
switch (type) {
|
||||
case RuleFormType.cloud:
|
||||
case RuleFormType.cloudAlerting:
|
||||
return {
|
||||
dataSourceName,
|
||||
expr: expression,
|
||||
|
||||
@@ -15,8 +15,11 @@ export const QueryStep: FC = () => {
|
||||
const type = watch('type');
|
||||
const dataSourceName = watch('dataSourceName');
|
||||
return (
|
||||
<RuleEditorSection stepNo={2} title="Create a query to be alerted on">
|
||||
{type === RuleFormType.cloud && dataSourceName && (
|
||||
<RuleEditorSection
|
||||
stepNo={2}
|
||||
title={type === RuleFormType.cloudRecording ? 'Create a query to be recorded' : 'Create a query to be alerted on'}
|
||||
>
|
||||
{(type === RuleFormType.cloudRecording || type === RuleFormType.cloudAlerting) && dataSourceName && (
|
||||
<Field error={errors.expression?.message} invalid={!!errors.expression?.message}>
|
||||
<InputControl
|
||||
name="expression"
|
||||
|
||||
Reference in New Issue
Block a user