diff --git a/conf/defaults.ini b/conf/defaults.ini index 94e864591cc..922cb5985aa 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -964,6 +964,10 @@ upload_external_image_storage = false # For example: `disabled_labels=grafana_folder` disabled_labels = +[unified_alerting.state_history] +# Enable the state history functionality in Unified Alerting. The previous states of alert rules will be visible in panels and in the UI. +enabled = true + #################################### Alerting ############################ [alerting] # Enable the legacy alerting sub-system and interface. If Unified Alerting is already enabled and you try to go back to legacy alerting, all data that is part of Unified Alerting will be deleted. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details. diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index b3f6f783afc..bdad7dd76ce 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -200,8 +200,13 @@ func (ng *AlertNG) init() error { AlertSender: alertsRouter, } - historian := historian.NewAnnotationHistorian(ng.annotationsRepo, ng.dashboardService) - stateManager := state.NewManager(ng.Metrics.GetStateMetrics(), appUrl, store, ng.imageService, clk, historian) + var history state.Historian + if ng.Cfg.UnifiedAlerting.StateHistory.Enabled { + history = historian.NewAnnotationHistorian(ng.annotationsRepo, ng.dashboardService) + } else { + history = historian.NewNopHistorian() + } + stateManager := state.NewManager(ng.Metrics.GetStateMetrics(), appUrl, store, ng.imageService, clk, history) scheduler := schedule.NewScheduler(schedCfg, stateManager) // if it is required to include folder title to the alerts, we need to subscribe to changes of alert title diff --git a/pkg/services/ngalert/state/historian/noop.go b/pkg/services/ngalert/state/historian/noop.go new file mode 100644 index 00000000000..76c40643772 --- /dev/null +++ b/pkg/services/ngalert/state/historian/noop.go @@ -0,0 +1,18 @@ +package historian + +import ( + "context" + + "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/ngalert/state" +) + +// NoOpHistorian is a state.Historian that does nothing with the resulting data, to be used in contexts where history is not needed. +type NoOpHistorian struct{} + +func NewNopHistorian() *NoOpHistorian { + return &NoOpHistorian{} +} + +func (f *NoOpHistorian) RecordStatesAsync(ctx context.Context, _ *models.AlertRule, _ []state.StateTransition) { +} diff --git a/pkg/setting/setting_unified_alerting.go b/pkg/setting/setting_unified_alerting.go index f2c9725ea17..b134e1810d9 100644 --- a/pkg/setting/setting_unified_alerting.go +++ b/pkg/setting/setting_unified_alerting.go @@ -60,6 +60,7 @@ const ( SchedulerBaseInterval = 10 * time.Second // DefaultRuleEvaluationInterval indicates a default interval of for how long a rule should be evaluated to change state from Pending to Alerting DefaultRuleEvaluationInterval = SchedulerBaseInterval * 6 // == 60 seconds + stateHistoryDefaultEnabled = true ) type UnifiedAlertingSettings struct { @@ -85,6 +86,7 @@ type UnifiedAlertingSettings struct { DefaultRuleEvaluationInterval time.Duration Screenshots UnifiedAlertingScreenshotSettings ReservedLabels UnifiedAlertingReservedLabelSettings + StateHistory UnifiedAlertingStateHistorySettings } type UnifiedAlertingScreenshotSettings struct { @@ -98,6 +100,10 @@ type UnifiedAlertingReservedLabelSettings struct { DisabledLabels map[string]struct{} } +type UnifiedAlertingStateHistorySettings struct { + Enabled bool +} + // IsEnabled returns true if UnifiedAlertingSettings.Enabled is either nil or true. // It hides the implementation details of the Enabled and simplifies its usage. func (u *UnifiedAlertingSettings) IsEnabled() bool { @@ -304,6 +310,12 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error { } uaCfg.ReservedLabels = uaCfgReservedLabels + stateHistory := iniFile.Section("unified_alerting.state_history") + uaCfgStateHistory := UnifiedAlertingStateHistorySettings{ + Enabled: stateHistory.Key("enabled").MustBool(stateHistoryDefaultEnabled), + } + uaCfg.StateHistory = uaCfgStateHistory + cfg.UnifiedAlerting = uaCfg return nil }