diff --git a/conf/defaults.ini b/conf/defaults.ini index 49e05c3b519..2a7f9ab558e 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -593,6 +593,8 @@ notification_timeout_seconds = 30 # Default setting for max attempts to sending alert notifications. Default value is 3 max_attempts = 3 +# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend +min_interval_seconds = 1 #################################### Explore ############################# [explore] diff --git a/conf/sample.ini b/conf/sample.ini index 7c51acbaf32..25f3d999f04 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -584,6 +584,9 @@ # Default setting for max attempts to sending alert notifications. Default value is 3 ;max_attempts = 3 +# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend +;min_interval_seconds = 1 + #################################### Explore ############################# [explore] # Enable the Explore section diff --git a/docs/sources/alerting/rules.md b/docs/sources/alerting/rules.md index 70699a969f3..c7c86b9c6b2 100755 --- a/docs/sources/alerting/rules.md +++ b/docs/sources/alerting/rules.md @@ -45,6 +45,7 @@ Currently only the graph panel supports alert rules. ### Name and Evaluation interval Here you can specify the name of the alert rule and how often the scheduler should evaluate the alert rule. +**Note:** You can set a minimum interval in the `alerting.min_interval_seconds` config field, to set a minimum time between evaluations. Check out the [[configuration]]({{< relref "../installation/configuration.md" >}}#min-interval-seconds) page for more information. ### For diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index 0850b88311d..830e5dae389 100755 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -722,6 +722,12 @@ Default setting for alert notification timeout. Default value is `30` Default setting for max attempts to sending alert notifications. Default value is `3` +### min_interval_seconds + +Default setting for minimum interval between rule evaluations. Default value is `1` + +> **Note.** This setting has precedence over each individual rule frequency. Therefore, if a rule frequency is lower than this value, this value will be enforced. + ## [rendering] Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer. diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index 44869a478da..3da9f814845 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -34,6 +34,7 @@ export class GrafanaBootConfig { alertingEnabled = false; alertingErrorOrTimeout = ''; alertingNoDataOrNullValues = ''; + alertingMinInterval = 1; authProxyEnabled = false; exploreEnabled = false; ldapEnabled = false; diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 72c38900b43..003d23b50fc 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -176,6 +176,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf "alertingEnabled": setting.AlertingEnabled, "alertingErrorOrTimeout": setting.AlertingErrorOrTimeout, "alertingNoDataOrNullValues": setting.AlertingNoDataOrNullValues, + "alertingMinInterval": setting.AlertingMinInterval, "exploreEnabled": setting.ExploreEnabled, "googleAnalyticsId": setting.GoogleAnalyticsId, "disableLoginForm": setting.DisableLoginForm, diff --git a/pkg/services/alerting/scheduler.go b/pkg/services/alerting/scheduler.go index 39589256e69..a4ed799f613 100644 --- a/pkg/services/alerting/scheduler.go +++ b/pkg/services/alerting/scheduler.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/setting" ) type schedulerImpl struct { @@ -61,7 +62,13 @@ func (s *schedulerImpl) Tick(tickTime time.Time, execQueue chan *Job) { continue } - if now%job.Rule.Frequency == 0 { + // Check the job frequency against the minimum interval required + interval := job.Rule.Frequency + if interval < setting.AlertingMinInterval { + interval = setting.AlertingMinInterval + } + + if now%interval == 0 { if job.Offset > 0 { job.OffsetWait = true } else { diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index ae8ab9bd87a..a7269d741a7 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -201,6 +201,7 @@ var ( AlertingEvaluationTimeout time.Duration AlertingNotificationTimeout time.Duration AlertingMaxAttempts int + AlertingMinInterval int64 // Explore UI ExploreEnabled bool @@ -961,6 +962,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { notificationTimeoutSeconds := alerting.Key("notification_timeout_seconds").MustInt64(30) AlertingNotificationTimeout = time.Second * time.Duration(notificationTimeoutSeconds) AlertingMaxAttempts = alerting.Key("max_attempts").MustInt(3) + AlertingMinInterval = alerting.Key("min_interval_seconds").MustInt64(1) explore := iniFile.Section("explore") ExploreEnabled = explore.Key("enabled").MustBool(true) diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts index 064d46eb9c1..0101e8e516c 100644 --- a/public/app/features/alerting/AlertTabCtrl.ts +++ b/public/app/features/alerting/AlertTabCtrl.ts @@ -12,6 +12,7 @@ import { DataQuery, DataSourceApi } from '@grafana/data'; import { PanelModel } from 'app/features/dashboard/state'; import { getDefaultCondition } from './getAlertingValidationMessage'; import { CoreEvents } from 'app/types'; +import kbn from 'app/core/utils/kbn'; export class AlertTabCtrl { panel: PanelModel; @@ -31,6 +32,9 @@ export class AlertTabCtrl { appSubUrl: string; alertHistory: any; newAlertRuleTag: any; + alertingMinIntervalSecs: number; + alertingMinInterval: string; + frequencyWarning: any; /** @ngInject */ constructor( @@ -51,6 +55,8 @@ export class AlertTabCtrl { this.executionErrorModes = alertDef.executionErrorModes; this.appSubUrl = config.appSubUrl; this.panelCtrl._enableAlert = this.enable; + this.alertingMinIntervalSecs = config.alertingMinInterval; + this.alertingMinInterval = kbn.secondsToHms(config.alertingMinInterval); } $onInit() { @@ -178,6 +184,8 @@ export class AlertTabCtrl { return; } + this.checkFrequency(); + alert.conditions = alert.conditions || []; if (alert.conditions.length === 0) { alert.conditions.push(getDefaultCondition()); @@ -232,6 +240,23 @@ export class AlertTabCtrl { this.panelCtrl.render(); } + checkFrequency() { + this.frequencyWarning = ''; + + try { + const frequencySecs = kbn.interval_to_seconds(this.alert.frequency); + if (frequencySecs < this.alertingMinIntervalSecs) { + this.frequencyWarning = + 'A minimum evaluation interval of ' + + this.alertingMinInterval + + ' have been configured in Grafana and will be used for this alert rule. ' + + 'Please contact the administrator to configure a lower interval.'; + } + } catch (err) { + this.frequencyWarning = err; + } + } + graphThresholdChanged(evt: any) { for (const condition of this.alert.conditions) { if (condition.type === 'query') { diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html index 5b9f241d8d0..2e5e66c744a 100644 --- a/public/app/features/alerting/partials/alert_tab.html +++ b/public/app/features/alerting/partials/alert_tab.html @@ -13,7 +13,7 @@