feat: move anomaly detection behind ff and show beta (#6180)

This commit is contained in:
Yunus M 2024-10-14 12:18:55 +05:30 committed by GitHub
parent 2728ddd255
commit 701b8803ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 92 additions and 46 deletions

View File

@ -22,4 +22,5 @@ export enum FeatureKeys {
GATEWAY = 'GATEWAY', GATEWAY = 'GATEWAY',
PREMIUM_SUPPORT = 'PREMIUM_SUPPORT', PREMIUM_SUPPORT = 'PREMIUM_SUPPORT',
QUERY_BUILDER_SEARCH_V2 = 'QUERY_BUILDER_SEARCH_V2', QUERY_BUILDER_SEARCH_V2 = 'QUERY_BUILDER_SEARCH_V2',
ANOMALY_DETECTION = 'ANOMALY_DETECTION',
} }

View File

@ -3,12 +3,11 @@ import { AlertTypes } from 'types/api/alerts/alertTypes';
import { OptionType } from './types'; import { OptionType } from './types';
export const getOptionList = (t: TFunction): OptionType[] => [ export const getOptionList = (
{ t: TFunction,
title: t('anomaly_based_alert'), isAnomalyDetectionEnabled: boolean,
selection: AlertTypes.ANOMALY_BASED_ALERT, ): OptionType[] => {
description: t('anomaly_based_alert_desc'), const optionList: OptionType[] = [
},
{ {
title: t('metric_based_alert'), title: t('metric_based_alert'),
selection: AlertTypes.METRICS_BASED_ALERT, selection: AlertTypes.METRICS_BASED_ALERT,
@ -29,4 +28,16 @@ export const getOptionList = (t: TFunction): OptionType[] => [
selection: AlertTypes.EXCEPTIONS_BASED_ALERT, selection: AlertTypes.EXCEPTIONS_BASED_ALERT,
description: t('exceptions_based_alert_desc'), description: t('exceptions_based_alert_desc'),
}, },
]; ];
if (isAnomalyDetectionEnabled) {
optionList.unshift({
title: t('anomaly_based_alert'),
selection: AlertTypes.ANOMALY_BASED_ALERT,
description: t('anomaly_based_alert_desc'),
isBeta: true,
});
}
return optionList;
};

View File

@ -1,6 +1,8 @@
import { Row, Typography } from 'antd'; import { Row, Tag, Typography } from 'antd';
import logEvent from 'api/common/logEvent'; import logEvent from 'api/common/logEvent';
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts'; import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
import { FeatureKeys } from 'constants/features';
import useFeatureFlags from 'hooks/useFeatureFlag';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { AlertTypes } from 'types/api/alerts/alertTypes'; import { AlertTypes } from 'types/api/alerts/alertTypes';
@ -12,7 +14,10 @@ import { OptionType } from './types';
function SelectAlertType({ onSelect }: SelectAlertTypeProps): JSX.Element { function SelectAlertType({ onSelect }: SelectAlertTypeProps): JSX.Element {
const { t } = useTranslation(['alerts']); const { t } = useTranslation(['alerts']);
const optionList = getOptionList(t); const isAnomalyDetectionEnabled =
useFeatureFlags(FeatureKeys.ANOMALY_DETECTION)?.active || false;
const optionList = getOptionList(t, isAnomalyDetectionEnabled);
function handleRedirection(option: AlertTypes): void { function handleRedirection(option: AlertTypes): void {
let url = ''; let url = '';
@ -56,6 +61,13 @@ function SelectAlertType({ onSelect }: SelectAlertTypeProps): JSX.Element {
<AlertTypeCard <AlertTypeCard
key={option.selection} key={option.selection}
title={option.title} title={option.title}
extra={
option.isBeta ? (
<Tag bordered={false} color="geekblue">
Beta
</Tag>
) : undefined
}
onClick={(): void => { onClick={(): void => {
onSelect(option.selection); onSelect(option.selection);
}} }}

View File

@ -4,4 +4,5 @@ export interface OptionType {
title: string; title: string;
selection: AlertTypes; selection: AlertTypes;
description: string; description: string;
isBeta?: boolean;
} }

View File

@ -3,6 +3,7 @@ import './ChartPreview.styles.scss';
import { InfoCircleOutlined } from '@ant-design/icons'; import { InfoCircleOutlined } from '@ant-design/icons';
import Spinner from 'components/Spinner'; import Spinner from 'components/Spinner';
import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { DEFAULT_ENTITY_VERSION } from 'constants/app';
import { FeatureKeys } from 'constants/features';
import { QueryParams } from 'constants/query'; import { QueryParams } from 'constants/query';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder'; import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import AnomalyAlertEvaluationView from 'container/AnomalyAlertEvaluationView'; import AnomalyAlertEvaluationView from 'container/AnomalyAlertEvaluationView';
@ -17,6 +18,7 @@ import {
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange'; import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useIsDarkMode } from 'hooks/useDarkMode'; import { useIsDarkMode } from 'hooks/useDarkMode';
import { useResizeObserver } from 'hooks/useDimensions'; import { useResizeObserver } from 'hooks/useDimensions';
import useFeatureFlags from 'hooks/useFeatureFlag';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import GetMinMax from 'lib/getMinMax'; import GetMinMax from 'lib/getMinMax';
import getTimeString from 'lib/getTimeString'; import getTimeString from 'lib/getTimeString';
@ -259,6 +261,9 @@ function ChartPreview({
const chartDataAvailable = const chartDataAvailable =
chartData && !queryResponse.isError && !queryResponse.isLoading; chartData && !queryResponse.isError && !queryResponse.isLoading;
const isAnomalyDetectionEnabled =
useFeatureFlags(FeatureKeys.ANOMALY_DETECTION)?.active || false;
return ( return (
<div className="alert-chart-container" ref={graphRef}> <div className="alert-chart-container" ref={graphRef}>
<ChartContainer> <ChartContainer>
@ -291,6 +296,7 @@ function ChartPreview({
{chartDataAvailable && {chartDataAvailable &&
isAnomalyDetectionAlert && isAnomalyDetectionAlert &&
isAnomalyDetectionEnabled &&
queryResponse?.data?.payload?.data?.resultType === 'anomaly' && ( queryResponse?.data?.payload?.data?.resultType === 'anomaly' && (
<AnomalyAlertEvaluationView <AnomalyAlertEvaluationView
data={queryResponse?.data?.payload} data={queryResponse?.data?.payload}

View File

@ -23,7 +23,10 @@ import PlotTag from 'container/NewWidget/LeftContainer/WidgetGraph/PlotTag';
import { BuilderUnitsFilter } from 'container/QueryBuilder/filters'; import { BuilderUnitsFilter } from 'container/QueryBuilder/filters';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl'; import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag'; import useFeatureFlag, {
MESSAGE,
useIsFeatureDisabled,
} from 'hooks/useFeatureFlag';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history'; import history from 'lib/history';
@ -665,6 +668,7 @@ function FormAlertRules({
{ {
value: AlertDetectionTypes.ANOMALY_DETECTION_ALERT, value: AlertDetectionTypes.ANOMALY_DETECTION_ALERT,
label: 'Anomaly Detection Alert', label: 'Anomaly Detection Alert',
isBeta: true,
}, },
]; ];
@ -677,6 +681,9 @@ function FormAlertRules({
setDetectionMethod(value); setDetectionMethod(value);
}; };
const isAnomalyDetectionEnabled =
useFeatureFlag(FeatureKeys.ANOMALY_DETECTION)?.active || false;
return ( return (
<> <>
{Element} {Element}
@ -730,7 +737,8 @@ function FormAlertRules({
</StepContainer> </StepContainer>
<div className="steps-container"> <div className="steps-container">
{alertDef.alertType === AlertTypes.METRICS_BASED_ALERT && ( {alertDef.alertType === AlertTypes.METRICS_BASED_ALERT &&
isAnomalyDetectionEnabled && (
<div className="detection-method-container"> <div className="detection-method-container">
<StepHeading> {t('alert_form_step1')}</StepHeading> <StepHeading> {t('alert_form_step1')}</StepHeading>

View File

@ -1,7 +1,7 @@
import './Tabs2.styles.scss'; import './Tabs2.styles.scss';
import { Color } from '@signozhq/design-tokens'; import { Color } from '@signozhq/design-tokens';
import { Button } from 'antd'; import { Button, Tag } from 'antd';
import { TimelineFilter } from 'container/AlertHistory/types'; import { TimelineFilter } from 'container/AlertHistory/types';
import { Undo } from 'lucide-react'; import { Undo } from 'lucide-react';
import { useState } from 'react'; import { useState } from 'react';
@ -11,6 +11,7 @@ interface Tab {
label: string | JSX.Element; label: string | JSX.Element;
disabled?: boolean; disabled?: boolean;
icon?: string | JSX.Element; icon?: string | JSX.Element;
isBeta?: boolean;
} }
interface TimelineTabsProps { interface TimelineTabsProps {
@ -63,6 +64,12 @@ function Tabs2({
style={{ minWidth: buttonMinWidth }} style={{ minWidth: buttonMinWidth }}
> >
{tab.label} {tab.label}
{tab.isBeta && (
<Tag bordered={false} color="geekblue">
Beta
</Tag>
)}
</Button> </Button>
))} ))}
</Button.Group> </Button.Group>