Alerting: Remove feature toggle for custom recovery threshold (#104455)

This commit is contained in:
Gilles De Mey
2025-04-24 11:58:17 -04:00
committed by GitHub
parent 674fdd1d32
commit 109267ab03
13 changed files with 247 additions and 312 deletions
@@ -46,7 +46,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
| `formatString` | Enable format string transformer | Yes |
| `kubernetesClientDashboardsFolders` | Route the folder and dashboard service requests to k8s | Yes |
| `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes |
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
| `addFieldFromCalculationStatFunctions` | Add cumulative and window functions to the add field from calculation transformation | Yes |
| `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes |
@@ -354,11 +354,6 @@ export interface FeatureToggles {
*/
cloudWatchBatchQueries?: boolean;
/**
* Enables feature recovery threshold (aka hysteresis) for threshold server-side expression
* @default true
*/
recoveryThreshold?: boolean;
/**
* Enables the loki data source to request structured metadata from the Loki server
* @default true
*/
+1 -1
View File
@@ -161,7 +161,7 @@ func buildCMDNode(rn *rawNode, toggles featuremgmt.FeatureToggles, sqlExpression
case TypeClassicConditions:
node.Command, err = classic.UnmarshalConditionsCmd(rn.Query, rn.RefID)
case TypeThreshold:
node.Command, err = UnmarshalThresholdCommand(rn, toggles)
node.Command, err = UnmarshalThresholdCommand(rn)
case TypeSQL:
node.Command, err = UnmarshalSQLCommand(rn, sqlExpressionCellLimit)
default:
+1 -1
View File
@@ -158,7 +158,7 @@ func (h *ExpressionQueryReader) ReadQuery(
eq.Command = threshold
eq.Properties = q
if firstCondition.UnloadEvaluator != nil && h.features.IsEnabledGlobally(featuremgmt.FlagRecoveryThreshold) {
if firstCondition.UnloadEvaluator != nil {
unloading, err := NewThresholdCommand(common.RefID, referenceVar, firstCondition.UnloadEvaluator.Type, firstCondition.UnloadEvaluator.Params)
unloading.Invert = true
if err != nil {
+2 -3
View File
@@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana/pkg/expr/mathexp"
"github.com/grafana/grafana/pkg/expr/metrics"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/util"
)
@@ -131,7 +130,7 @@ type ConditionEvalJSON struct {
}
// UnmarshalResampleCommand creates a ResampleCMD from Grafana's frontend query.
func UnmarshalThresholdCommand(rn *rawNode, features featuremgmt.FeatureToggles) (Command, error) {
func UnmarshalThresholdCommand(rn *rawNode) (Command, error) {
cmdConfig := ThresholdCommandConfig{}
if err := json.Unmarshal(rn.QueryRaw, &cmdConfig); err != nil {
return nil, fmt.Errorf("failed to parse the threshold command: %w", err)
@@ -151,7 +150,7 @@ func UnmarshalThresholdCommand(rn *rawNode, features featuremgmt.FeatureToggles)
if err != nil {
return nil, fmt.Errorf("invalid condition: %w", err)
}
if firstCondition.UnloadEvaluator != nil && features.IsEnabledGlobally(featuremgmt.FlagRecoveryThreshold) {
if firstCondition.UnloadEvaluator != nil {
unloading, err := NewThresholdCommand(rn.RefID, referenceVar, firstCondition.UnloadEvaluator.Type, firstCondition.UnloadEvaluator.Params)
if err != nil {
return nil, fmt.Errorf("invalid unloadCondition: %w", err)
+2 -3
View File
@@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/expr/mathexp"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/util"
)
@@ -277,7 +276,7 @@ func TestUnmarshalThresholdCommand(t *testing.T) {
QueryRaw: []byte(tc.query),
QueryType: "",
DataSource: nil,
}, featuremgmt.WithFeatures(featuremgmt.FlagRecoveryThreshold))
})
if tc.shouldError {
require.Nil(t, cmd)
@@ -466,7 +465,7 @@ func TestSetLoadedDimensionsToHysteresisCommand(t *testing.T) {
cmd, err := UnmarshalThresholdCommand(&rawNode{
RefID: "B",
QueryRaw: raw,
}, featuremgmt.WithFeatures(featuremgmt.FlagRecoveryThreshold))
})
require.NoError(t, err)
require.Equal(t, fingerprints, cmd.(*HysteresisCommand).LoadedDimensions)
-9
View File
@@ -590,15 +590,6 @@ var (
Stage: FeatureStagePublicPreview,
Owner: awsDatasourcesSquad,
},
{
Name: "recoveryThreshold",
Description: "Enables feature recovery threshold (aka hysteresis) for threshold server-side expression",
Stage: FeatureStageGeneralAvailability,
FrontendOnly: false,
Owner: grafanaAlertingSquad,
RequiresRestart: true,
Expression: "true",
},
{
Name: "lokiStructuredMetadata",
Description: "Enables the loki data source to request structured metadata from the Loki server",
-1
View File
@@ -77,7 +77,6 @@ queryServiceRewrite,experimental,@grafana/grafana-datasources-core-services,fals
queryServiceFromUI,experimental,@grafana/grafana-datasources-core-services,false,false,true
queryServiceFromExplore,experimental,@grafana/grafana-datasources-core-services,false,false,true
cloudWatchBatchQueries,preview,@grafana/aws-datasources,false,false,false
recoveryThreshold,GA,@grafana/alerting-squad,false,true,false
lokiStructuredMetadata,GA,@grafana/observability-logs,false,false,false
cachingOptimizeSerializationMemoryUsage,experimental,@grafana/grafana-operator-experience-squad,false,false,false
prometheusCodeModeMetricNamesSearch,experimental,@grafana/oss-big-tent,false,false,true
1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
77 queryServiceFromUI experimental @grafana/grafana-datasources-core-services false false true
78 queryServiceFromExplore experimental @grafana/grafana-datasources-core-services false false true
79 cloudWatchBatchQueries preview @grafana/aws-datasources false false false
recoveryThreshold GA @grafana/alerting-squad false true false
80 lokiStructuredMetadata GA @grafana/observability-logs false false false
81 cachingOptimizeSerializationMemoryUsage experimental @grafana/grafana-operator-experience-squad false false false
82 prometheusCodeModeMetricNamesSearch experimental @grafana/oss-big-tent false false true
-4
View File
@@ -319,10 +319,6 @@ const (
// Runs CloudWatch metrics queries as separate batches
FlagCloudWatchBatchQueries = "cloudWatchBatchQueries"
// FlagRecoveryThreshold
// Enables feature recovery threshold (aka hysteresis) for threshold server-side expression
FlagRecoveryThreshold = "recoveryThreshold"
// FlagLokiStructuredMetadata
// Enables the loki data source to request structured metadata from the Loki server
FlagLokiStructuredMetadata = "lokiStructuredMetadata"
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -710,7 +710,7 @@ func TestCreate_HysteresisCommand(t *testing.T) {
cache: cacheService,
pluginsStore: store,
})
evaluator := NewEvaluatorFactory(setting.UnifiedAlertingSettings{}, cacheService, expr.ProvideService(&setting.Cfg{ExpressionsEnabled: true}, nil, nil, featuremgmt.WithFeatures(featuremgmt.FlagRecoveryThreshold), nil, tracing.InitializeTracerForTest()))
evaluator := NewEvaluatorFactory(setting.UnifiedAlertingSettings{}, cacheService, expr.ProvideService(&setting.Cfg{ExpressionsEnabled: true}, nil, nil, featuremgmt.WithFeatures(), nil, tracing.InitializeTracerForTest()))
evalCtx := NewContextWithPreviousResults(context.Background(), u, testCase.reader)
eval, err := evaluator.Create(evalCtx, condition)
+1 -1
View File
@@ -4297,7 +4297,7 @@ func TestIntegrationHysteresisRule(t *testing.T) {
DisableAnonymous: true,
AppModeProduction: true,
NGAlertSchedulerBaseInterval: 1 * time.Second,
EnableFeatureToggles: []string{featuremgmt.FlagConfigurableSchedulerTick, featuremgmt.FlagRecoveryThreshold},
EnableFeatureToggles: []string{featuremgmt.FlagConfigurableSchedulerTick},
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)
@@ -6,7 +6,6 @@ import { FormEvent, useEffect, useReducer } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { InlineField, InlineFieldRow, InlineSwitch, Input, Select, Stack, useStyles2 } from '@grafana/ui';
import { config } from 'app/core/config';
import { t } from 'app/core/internationalization';
import { EvalFunction } from 'app/features/alerting/state/alertDef';
@@ -86,8 +85,6 @@ export const Threshold = ({ labelWidth, onChange, refIds, query, onError, useHys
conditionInState.evaluator.type === EvalFunction.IsOutsideRangeIncluded ||
conditionInState.evaluator.type === EvalFunction.IsWithinRangeIncluded;
const hysteresisEnabled = Boolean(config.featureToggles?.recoveryThreshold) && useHysteresis;
const id = uniqueId('threshold-');
return (
@@ -125,7 +122,7 @@ export const Threshold = ({ labelWidth, onChange, refIds, query, onError, useHys
/>
)}
</InlineFieldRow>
{hysteresisEnabled && <HysteresisSection isRange={isRange} onError={onError} />}
{useHysteresis && <HysteresisSection isRange={isRange} onError={onError} />}
</>
);
interface HysteresisSectionProps {