diff --git a/Makefile b/Makefile index 5b89b178e97..7025dff42aa 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -include local/Makefile -.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go test-go test-js test run clean gosec revive devenv devenv-down +.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go test-go test-js test run clean gosec revive devenv devenv-down revive-alerting GO := GO111MODULE=on go GO_FILES := ./pkg/... @@ -84,6 +84,11 @@ revive: scripts/go/bin/revive -config ./scripts/go/configs/revive.toml \ $(GO_FILES) +revive-alerting: scripts/go/bin/revive + @scripts/go/bin/revive \ + -formatter stylish \ + ./pkg/services/alerting/... + # create docker-compose file with provided sources and start them # example: make devenv sources=postgres,openldap ifeq ($(sources),) diff --git a/pkg/api/alerting.go b/pkg/api/alerting.go index 0cd00d3b015..e5e94326027 100644 --- a/pkg/api/alerting.go +++ b/pkg/api/alerting.go @@ -131,9 +131,9 @@ func AlertTest(c *m.ReqContext, dto dtos.AlertTestCommand) Response { } backendCmd := alerting.AlertTestCommand{ - OrgId: c.OrgId, + OrgID: c.OrgId, Dashboard: dto.Dashboard, - PanelId: dto.PanelId, + PanelID: dto.PanelId, User: c.SignedInUser, } diff --git a/pkg/services/alerting/conditions/evaluator.go b/pkg/services/alerting/conditions/evaluator.go index eef593d39e2..3045b633f1e 100644 --- a/pkg/services/alerting/conditions/evaluator.go +++ b/pkg/services/alerting/conditions/evaluator.go @@ -14,22 +14,25 @@ var ( rangedTypes = []string{"within_range", "outside_range"} ) +// AlertEvaluator evaluates the reduced value of a timeserie. +// Returning true if a timeserie is violating the condition +// ex: ThresholdEvaluator, NoValueEvaluator, RangeEvaluator type AlertEvaluator interface { Eval(reducedValue null.Float) bool } -type NoValueEvaluator struct{} +type noValueEvaluator struct{} -func (e *NoValueEvaluator) Eval(reducedValue null.Float) bool { +func (e *noValueEvaluator) Eval(reducedValue null.Float) bool { return !reducedValue.Valid } -type ThresholdEvaluator struct { +type thresholdEvaluator struct { Type string Threshold float64 } -func newThresholdEvaluator(typ string, model *simplejson.Json) (*ThresholdEvaluator, error) { +func newThresholdEvaluator(typ string, model *simplejson.Json) (*thresholdEvaluator, error) { params := model.Get("params").MustArray() if len(params) == 0 { return nil, fmt.Errorf("Evaluator missing threshold parameter") @@ -40,12 +43,12 @@ func newThresholdEvaluator(typ string, model *simplejson.Json) (*ThresholdEvalua return nil, fmt.Errorf("Evaluator has invalid parameter") } - defaultEval := &ThresholdEvaluator{Type: typ} + defaultEval := &thresholdEvaluator{Type: typ} defaultEval.Threshold, _ = firstParam.Float64() return defaultEval, nil } -func (e *ThresholdEvaluator) Eval(reducedValue null.Float) bool { +func (e *thresholdEvaluator) Eval(reducedValue null.Float) bool { if !reducedValue.Valid { return false } @@ -60,13 +63,13 @@ func (e *ThresholdEvaluator) Eval(reducedValue null.Float) bool { return false } -type RangedEvaluator struct { +type rangedEvaluator struct { Type string Lower float64 Upper float64 } -func newRangedEvaluator(typ string, model *simplejson.Json) (*RangedEvaluator, error) { +func newRangedEvaluator(typ string, model *simplejson.Json) (*rangedEvaluator, error) { params := model.Get("params").MustArray() if len(params) == 0 { return nil, alerting.ValidationError{Reason: "Evaluator missing threshold parameter"} @@ -82,13 +85,13 @@ func newRangedEvaluator(typ string, model *simplejson.Json) (*RangedEvaluator, e return nil, alerting.ValidationError{Reason: "Evaluator has invalid second parameter"} } - rangedEval := &RangedEvaluator{Type: typ} + rangedEval := &rangedEvaluator{Type: typ} rangedEval.Lower, _ = firstParam.Float64() rangedEval.Upper, _ = secondParam.Float64() return rangedEval, nil } -func (e *RangedEvaluator) Eval(reducedValue null.Float) bool { +func (e *rangedEvaluator) Eval(reducedValue null.Float) bool { if !reducedValue.Valid { return false } @@ -105,6 +108,8 @@ func (e *RangedEvaluator) Eval(reducedValue null.Float) bool { return false } +// NewAlertEvaluator is a factory function for returning +// an `AlertEvaluator` depending on the json model. func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) { typ := model.Get("type").MustString() if typ == "" { @@ -120,7 +125,7 @@ func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) { } if typ == "no_value" { - return &NoValueEvaluator{}, nil + return &noValueEvaluator{}, nil } return nil, fmt.Errorf("Evaluator invalid evaluator type: %s", typ) diff --git a/pkg/services/alerting/conditions/query.go b/pkg/services/alerting/conditions/query.go index 37dbd9b3f7a..b29f39b4916 100644 --- a/pkg/services/alerting/conditions/query.go +++ b/pkg/services/alerting/conditions/query.go @@ -17,26 +17,31 @@ import ( func init() { alerting.RegisterCondition("query", func(model *simplejson.Json, index int) (alerting.Condition, error) { - return NewQueryCondition(model, index) + return newQueryCondition(model, index) }) } +// QueryCondition is responsible for issue and query, reduce the +// timeseries into single values and evaluate if they are firing or not. type QueryCondition struct { Index int Query AlertQuery - Reducer QueryReducer + Reducer *queryReducer Evaluator AlertEvaluator Operator string HandleRequest tsdb.HandleRequestFunc } +// AlertQuery contains information about what datasource a query +// should be sent to and the query object. type AlertQuery struct { Model *simplejson.Json - DatasourceId int64 + DatasourceID int64 From string To string } +// Eval evaluates the `QueryCondition`. func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.ConditionResult, error) { timeRange := tsdb.NewTimeRange(c.Query.From, c.Query.To) @@ -101,8 +106,8 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.Conditio func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange *tsdb.TimeRange) (tsdb.TimeSeriesSlice, error) { getDsInfo := &models.GetDataSourceByIdQuery{ - Id: c.Query.DatasourceId, - OrgId: context.Rule.OrgId, + Id: c.Query.DatasourceID, + OrgId: context.Rule.OrgID, } if err := bus.Dispatch(getDsInfo); err != nil { @@ -154,16 +159,16 @@ func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, t return req } -func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, error) { +func newQueryCondition(model *simplejson.Json, index int) (*QueryCondition, error) { condition := QueryCondition{} condition.Index = index condition.HandleRequest = tsdb.HandleRequest - queryJson := model.Get("query") + queryJSON := model.Get("query") - condition.Query.Model = queryJson.Get("model") - condition.Query.From = queryJson.Get("params").MustArray()[1].(string) - condition.Query.To = queryJson.Get("params").MustArray()[2].(string) + condition.Query.Model = queryJSON.Get("model") + condition.Query.From = queryJSON.Get("params").MustArray()[1].(string) + condition.Query.To = queryJSON.Get("params").MustArray()[2].(string) if err := validateFromValue(condition.Query.From); err != nil { return nil, err @@ -173,20 +178,20 @@ func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, erro return nil, err } - condition.Query.DatasourceId = queryJson.Get("datasourceId").MustInt64() + condition.Query.DatasourceID = queryJSON.Get("datasourceId").MustInt64() - reducerJson := model.Get("reducer") - condition.Reducer = NewSimpleReducer(reducerJson.Get("type").MustString()) + reducerJSON := model.Get("reducer") + condition.Reducer = newSimpleReducer(reducerJSON.Get("type").MustString()) - evaluatorJson := model.Get("evaluator") - evaluator, err := NewAlertEvaluator(evaluatorJson) + evaluatorJSON := model.Get("evaluator") + evaluator, err := NewAlertEvaluator(evaluatorJSON) if err != nil { return nil, err } condition.Evaluator = evaluator - operatorJson := model.Get("operator") - operator := operatorJson.Get("type").MustString("and") + operatorJSON := model.Get("operator") + operator := operatorJSON.Get("type").MustString("and") condition.Operator = operator return &condition, nil diff --git a/pkg/services/alerting/conditions/query_test.go b/pkg/services/alerting/conditions/query_test.go index 2e1ecf5f39c..4c2b1689277 100644 --- a/pkg/services/alerting/conditions/query_test.go +++ b/pkg/services/alerting/conditions/query_test.go @@ -27,16 +27,15 @@ func TestQueryCondition(t *testing.T) { So(ctx.condition.Query.From, ShouldEqual, "5m") So(ctx.condition.Query.To, ShouldEqual, "now") - So(ctx.condition.Query.DatasourceId, ShouldEqual, 1) + So(ctx.condition.Query.DatasourceID, ShouldEqual, 1) Convey("Can read query reducer", func() { - reducer, ok := ctx.condition.Reducer.(*SimpleReducer) - So(ok, ShouldBeTrue) + reducer := ctx.condition.Reducer So(reducer.Type, ShouldEqual, "avg") }) Convey("Can read evaluator", func() { - evaluator, ok := ctx.condition.Evaluator.(*ThresholdEvaluator) + evaluator, ok := ctx.condition.Evaluator.(*thresholdEvaluator) So(ok, ShouldBeTrue) So(evaluator.Type, ShouldEqual, "gt") }) @@ -163,7 +162,7 @@ func (ctx *queryConditionTestContext) exec() (*alerting.ConditionResult, error) }`)) So(err, ShouldBeNil) - condition, err := NewQueryCondition(jsonModel, 0) + condition, err := newQueryCondition(jsonModel, 0) So(err, ShouldBeNil) ctx.condition = condition diff --git a/pkg/services/alerting/conditions/reducer.go b/pkg/services/alerting/conditions/reducer.go index f55545be311..bf57110ea1c 100644 --- a/pkg/services/alerting/conditions/reducer.go +++ b/pkg/services/alerting/conditions/reducer.go @@ -9,15 +9,15 @@ import ( "github.com/grafana/grafana/pkg/tsdb" ) -type QueryReducer interface { - Reduce(timeSeries *tsdb.TimeSeries) null.Float -} +// queryReducer reduces an timeserie to a nullable float +type queryReducer struct { -type SimpleReducer struct { + // Type is how the timeserie should be reduced. + // Ex avg, sum, max, min, count Type string } -func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { +func (s *queryReducer) Reduce(series *tsdb.TimeSeries) null.Float { if len(series.Points) == 0 { return null.FloatFromPtr(nil) } @@ -31,7 +31,7 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { for _, point := range series.Points { if point[0].Valid { value += point[0].Float64 - validPointsCount += 1 + validPointsCount++ allNull = false } } @@ -117,8 +117,8 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { return null.FloatFrom(value) } -func NewSimpleReducer(typ string) *SimpleReducer { - return &SimpleReducer{Type: typ} +func newSimpleReducer(t string) *queryReducer { + return &queryReducer{Type: t} } func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) { diff --git a/pkg/services/alerting/conditions/reducer_test.go b/pkg/services/alerting/conditions/reducer_test.go index d2c21771d0b..eac71378f3d 100644 --- a/pkg/services/alerting/conditions/reducer_test.go +++ b/pkg/services/alerting/conditions/reducer_test.go @@ -53,7 +53,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("median should ignore null values", func() { - reducer := NewSimpleReducer("median") + reducer := newSimpleReducer("median") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -76,7 +76,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("avg with only nulls", func() { - reducer := NewSimpleReducer("avg") + reducer := newSimpleReducer("avg") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -87,7 +87,7 @@ func TestSimpleReducer(t *testing.T) { Convey("count_non_null", func() { Convey("with null values and real values", func() { - reducer := NewSimpleReducer("count_non_null") + reducer := newSimpleReducer("count_non_null") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -102,7 +102,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("with null values", func() { - reducer := NewSimpleReducer("count_non_null") + reducer := newSimpleReducer("count_non_null") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -115,7 +115,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("avg of number values and null values should ignore nulls", func() { - reducer := NewSimpleReducer("avg") + reducer := newSimpleReducer("avg") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -144,7 +144,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("diff with only nulls", func() { - reducer := NewSimpleReducer("diff") + reducer := newSimpleReducer("diff") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -171,7 +171,7 @@ func TestSimpleReducer(t *testing.T) { }) Convey("percent_diff with only nulls", func() { - reducer := NewSimpleReducer("percent_diff") + reducer := newSimpleReducer("percent_diff") series := &tsdb.TimeSeries{ Name: "test time serie", } @@ -184,8 +184,8 @@ func TestSimpleReducer(t *testing.T) { }) } -func testReducer(typ string, datapoints ...float64) float64 { - reducer := NewSimpleReducer(typ) +func testReducer(reducerType string, datapoints ...float64) float64 { + reducer := newSimpleReducer(reducerType) series := &tsdb.TimeSeries{ Name: "test time serie", } diff --git a/pkg/services/alerting/engine.go b/pkg/services/alerting/engine.go index f2fd002704a..8794eb51c32 100644 --- a/pkg/services/alerting/engine.go +++ b/pkg/services/alerting/engine.go @@ -17,10 +17,10 @@ import ( "golang.org/x/sync/errgroup" ) -// AlertingService is the background process that +// AlertEngine is the background process that // schedules alert evaluations and makes sure notifications // are sent. -type AlertingService struct { +type AlertEngine struct { RenderService rendering.Service `inject:""` execQueue chan *Job @@ -33,16 +33,16 @@ type AlertingService struct { } func init() { - registry.RegisterService(&AlertingService{}) + registry.RegisterService(&AlertEngine{}) } // IsDisabled returns true if the alerting service is disable for this instance. -func (e *AlertingService) IsDisabled() bool { +func (e *AlertEngine) IsDisabled() bool { return !setting.AlertingEnabled || !setting.ExecuteAlerts } // Init initalizes the AlertingService. -func (e *AlertingService) Init() error { +func (e *AlertEngine) Init() error { e.ticker = NewTicker(time.Now(), time.Second*0, clock.New()) e.execQueue = make(chan *Job, 1000) e.scheduler = newScheduler() @@ -54,7 +54,7 @@ func (e *AlertingService) Init() error { } // Run starts the alerting service background process. -func (e *AlertingService) Run(ctx context.Context) error { +func (e *AlertEngine) Run(ctx context.Context) error { alertGroup, ctx := errgroup.WithContext(ctx) alertGroup.Go(func() error { return e.alertingTicker(ctx) }) alertGroup.Go(func() error { return e.runJobDispatcher(ctx) }) @@ -63,7 +63,7 @@ func (e *AlertingService) Run(ctx context.Context) error { return err } -func (e *AlertingService) alertingTicker(grafanaCtx context.Context) error { +func (e *AlertEngine) alertingTicker(grafanaCtx context.Context) error { defer func() { if err := recover(); err != nil { e.log.Error("Scheduler Panic: stopping alertingTicker", "error", err, "stack", log.Stack(1)) @@ -88,7 +88,7 @@ func (e *AlertingService) alertingTicker(grafanaCtx context.Context) error { } } -func (e *AlertingService) runJobDispatcher(grafanaCtx context.Context) error { +func (e *AlertEngine) runJobDispatcher(grafanaCtx context.Context) error { dispatcherGroup, alertCtx := errgroup.WithContext(grafanaCtx) for { @@ -105,7 +105,7 @@ var ( unfinishedWorkTimeout = time.Second * 5 ) -func (e *AlertingService) processJobWithRetry(grafanaCtx context.Context, job *Job) error { +func (e *AlertEngine) processJobWithRetry(grafanaCtx context.Context, job *Job) error { defer func() { if err := recover(); err != nil { e.log.Error("Alert Panic", "error", err, "stack", log.Stack(1)) @@ -140,7 +140,7 @@ func (e *AlertingService) processJobWithRetry(grafanaCtx context.Context, job *J } } -func (e *AlertingService) endJob(err error, cancelChan chan context.CancelFunc, job *Job) error { +func (e *AlertEngine) endJob(err error, cancelChan chan context.CancelFunc, job *Job) error { job.Running = false close(cancelChan) for cancelFn := range cancelChan { @@ -149,7 +149,7 @@ func (e *AlertingService) endJob(err error, cancelChan chan context.CancelFunc, return err } -func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancelChan chan context.CancelFunc, job *Job) { +func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan chan context.CancelFunc, job *Job) { defer func() { if err := recover(); err != nil { e.log.Error("Alert Panic", "error", err, "stack", log.Stack(1)) @@ -180,8 +180,8 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel e.evalHandler.Eval(evalContext) - span.SetTag("alertId", evalContext.Rule.Id) - span.SetTag("dashboardId", evalContext.Rule.DashboardId) + span.SetTag("alertId", evalContext.Rule.ID) + span.SetTag("dashboardId", evalContext.Rule.DashboardID) span.SetTag("firing", evalContext.Firing) span.SetTag("nodatapoints", evalContext.NoDataFound) span.SetTag("attemptID", attemptID) @@ -194,7 +194,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel ) if attemptID < setting.AlertingMaxAttempts { span.Finish() - e.log.Debug("Job Execution attempt triggered retry", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.Id, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID) + e.log.Debug("Job Execution attempt triggered retry", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.ID, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID) attemptChan <- (attemptID + 1) return } @@ -212,7 +212,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel evalContext.Rule.State = evalContext.GetNewState() e.resultHandler.handle(evalContext) span.Finish() - e.log.Debug("Job Execution completed", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.Id, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID) + e.log.Debug("Job Execution completed", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.ID, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID) close(attemptChan) }() } diff --git a/pkg/services/alerting/engine_integration_test.go b/pkg/services/alerting/engine_integration_test.go index 7d0d3360ad5..6b6fab389d0 100644 --- a/pkg/services/alerting/engine_integration_test.go +++ b/pkg/services/alerting/engine_integration_test.go @@ -17,7 +17,7 @@ import ( func TestEngineTimeouts(t *testing.T) { Convey("Alerting engine timeout tests", t, func() { - engine := &AlertingService{} + engine := &AlertEngine{} engine.Init() setting.AlertingNotificationTimeout = 30 * time.Second setting.AlertingMaxAttempts = 3 diff --git a/pkg/services/alerting/engine_test.go b/pkg/services/alerting/engine_test.go index 4ed317d982f..86980c21bd4 100644 --- a/pkg/services/alerting/engine_test.go +++ b/pkg/services/alerting/engine_test.go @@ -39,7 +39,7 @@ func (handler *FakeResultHandler) handle(evalContext *EvalContext) error { func TestEngineProcessJob(t *testing.T) { Convey("Alerting engine job processing", t, func() { - engine := &AlertingService{} + engine := &AlertEngine{} engine.Init() setting.AlertingEvaluationTimeout = 30 * time.Second setting.AlertingNotificationTimeout = 30 * time.Second diff --git a/pkg/services/alerting/eval_context.go b/pkg/services/alerting/eval_context.go index 480303fa6d7..8436e9c9a78 100644 --- a/pkg/services/alerting/eval_context.go +++ b/pkg/services/alerting/eval_context.go @@ -26,7 +26,7 @@ type EvalContext struct { dashboardRef *models.DashboardRef - ImagePublicUrl string + ImagePublicURL string ImageOnDiskPath string NoDataFound bool PrevAlertState models.AlertStateType @@ -102,7 +102,7 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) { return c.dashboardRef, nil } - uidQuery := &models.GetDashboardRefByIdQuery{Id: c.Rule.DashboardId} + uidQuery := &models.GetDashboardRefByIdQuery{Id: c.Rule.DashboardID} if err := bus.Dispatch(uidQuery); err != nil { return nil, err } @@ -113,8 +113,8 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) { const urlFormat = "%s?fullscreen&edit&tab=alert&panelId=%d&orgId=%d" -// GetRuleUrl returns the url to the dashboard containing the alert. -func (c *EvalContext) GetRuleUrl() (string, error) { +// GetRuleURL returns the url to the dashboard containing the alert. +func (c *EvalContext) GetRuleURL() (string, error) { if c.IsTestRun { return setting.AppUrl, nil } @@ -123,7 +123,7 @@ func (c *EvalContext) GetRuleUrl() (string, error) { if err != nil { return "", err } - return fmt.Sprintf(urlFormat, models.GetFullDashboardUrl(ref.Uid, ref.Slug), c.Rule.PanelId, c.Rule.OrgId), nil + return fmt.Sprintf(urlFormat, models.GetFullDashboardUrl(ref.Uid, ref.Slug), c.Rule.PanelID, c.Rule.OrgID), nil } // GetNewState returns the new state from the alert rule evaluation. @@ -148,7 +148,7 @@ func (c *EvalContext) GetNewState() models.AlertStateType { func getNewStateInternal(c *EvalContext) models.AlertStateType { if c.Error != nil { c.log.Error("Alert Rule Result Error", - "ruleId", c.Rule.Id, + "ruleId", c.Rule.ID, "name", c.Rule.Name, "error", c.Error, "changing state to", c.Rule.ExecutionErrorState.ToAlertState()) @@ -165,7 +165,7 @@ func getNewStateInternal(c *EvalContext) models.AlertStateType { if c.NoDataFound { c.log.Info("Alert Rule returned no data", - "ruleId", c.Rule.Id, + "ruleId", c.Rule.ID, "name", c.Rule.Name, "changing state to", c.Rule.NoDataState.ToAlertState()) diff --git a/pkg/services/alerting/interfaces.go b/pkg/services/alerting/interfaces.go index be364d6f4cc..93d3127d6bd 100644 --- a/pkg/services/alerting/interfaces.go +++ b/pkg/services/alerting/interfaces.go @@ -25,7 +25,7 @@ type Notifier interface { // ShouldNotify checks this evaluation should send an alert notification ShouldNotify(ctx context.Context, evalContext *EvalContext, notificationState *models.AlertNotificationState) bool - GetNotifierUid() string + GetNotifierUID() string GetIsDefault() bool GetSendReminder() bool GetDisableResolveMessage() bool diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index de6d74239ae..84a26e9a64a 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -35,7 +35,7 @@ type notificationService struct { } func (n *notificationService) SendIfNeeded(context *EvalContext) error { - notifierStates, err := n.getNeededNotifiers(context.Rule.OrgId, context.Rule.Notifications, context) + notifierStates, err := n.getNeededNotifiers(context.Rule.OrgID, context.Rule.Notifications, context) if err != nil { return err } @@ -56,13 +56,13 @@ func (n *notificationService) SendIfNeeded(context *EvalContext) error { func (n *notificationService) sendAndMarkAsComplete(evalContext *EvalContext, notifierState *notifierState) error { notifier := notifierState.notifier - n.log.Debug("Sending notification", "type", notifier.GetType(), "uid", notifier.GetNotifierUid(), "isDefault", notifier.GetIsDefault()) + n.log.Debug("Sending notification", "type", notifier.GetType(), "uid", notifier.GetNotifierUID(), "isDefault", notifier.GetIsDefault()) metrics.M_Alerting_Notification_Sent.WithLabelValues(notifier.GetType()).Inc() err := notifier.Notify(evalContext) if err != nil { - n.log.Error("failed to send notification", "uid", notifier.GetNotifierUid(), "error", err) + n.log.Error("failed to send notification", "uid", notifier.GetNotifierUID(), "error", err) } if evalContext.IsTestRun { @@ -106,7 +106,7 @@ func (n *notificationService) sendNotifications(evalContext *EvalContext, notifi for _, notifierState := range notifierStates { err := n.sendNotification(evalContext, notifierState) if err != nil { - n.log.Error("failed to send notification", "uid", notifierState.notifier.GetNotifierUid(), "error", err) + n.log.Error("failed to send notification", "uid", notifierState.notifier.GetNotifierUID(), "error", err) } } @@ -123,7 +123,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { Width: 1000, Height: 500, Timeout: setting.AlertingEvaluationTimeout, - OrgId: context.Rule.OrgId, + OrgId: context.Rule.OrgID, OrgRole: models.ROLE_ADMIN, ConcurrentLimit: setting.AlertingRenderLimit, } @@ -133,7 +133,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { return err } - renderOpts.Path = fmt.Sprintf("d-solo/%s/%s?orgId=%d&panelId=%d", ref.Uid, ref.Slug, context.Rule.OrgId, context.Rule.PanelId) + renderOpts.Path = fmt.Sprintf("d-solo/%s/%s?orgId=%d&panelId=%d", ref.Uid, ref.Slug, context.Rule.OrgID, context.Rule.PanelID) result, err := n.renderService.Render(context.Ctx, renderOpts) if err != nil { @@ -141,13 +141,13 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { } context.ImageOnDiskPath = result.FilePath - context.ImagePublicUrl, err = uploader.Upload(context.Ctx, context.ImageOnDiskPath) + context.ImagePublicURL, err = uploader.Upload(context.Ctx, context.ImageOnDiskPath) if err != nil { return err } - if context.ImagePublicUrl != "" { - n.log.Info("uploaded screenshot of alert to external image store", "url", context.ImagePublicUrl) + if context.ImagePublicURL != "" { + n.log.Info("uploaded screenshot of alert to external image store", "url", context.ImagePublicURL) } return nil @@ -170,8 +170,8 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [ query := &models.GetOrCreateNotificationStateQuery{ NotifierId: notification.Id, - AlertId: evalContext.Rule.Id, - OrgId: evalContext.Rule.OrgId, + AlertId: evalContext.Rule.ID, + OrgId: evalContext.Rule.OrgID, } err = bus.DispatchCtx(evalContext.Ctx, query) diff --git a/pkg/services/alerting/notifiers/alertmanager.go b/pkg/services/alerting/notifiers/alertmanager.go index bc2807d0d3c..a8fd7db2f5e 100644 --- a/pkg/services/alerting/notifiers/alertmanager.go +++ b/pkg/services/alerting/notifiers/alertmanager.go @@ -51,7 +51,7 @@ type AlertmanagerNotifier struct { // ShouldNotify returns true if the notifiers should be used depending on state func (am *AlertmanagerNotifier) ShouldNotify(ctx context.Context, evalContext *alerting.EvalContext, notificationState *models.AlertNotificationState) bool { - am.log.Debug("Should notify", "ruleId", evalContext.Rule.Id, "state", evalContext.Rule.State, "previousState", evalContext.PrevAlertState) + am.log.Debug("Should notify", "ruleId", evalContext.Rule.ID, "state", evalContext.Rule.State, "previousState", evalContext.PrevAlertState) // Do not notify when we become OK for the first time. if (evalContext.PrevAlertState == models.AlertStatePending) && (evalContext.Rule.State == models.AlertStateOK) { @@ -89,8 +89,8 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m if description != "" { alertJSON.SetPath([]string{"annotations", "description"}, description) } - if evalContext.ImagePublicUrl != "" { - alertJSON.SetPath([]string{"annotations", "image"}, evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + alertJSON.SetPath([]string{"annotations", "image"}, evalContext.ImagePublicURL) } // Labels (from metrics tags + mandatory alertname). @@ -111,9 +111,9 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m // Notify sends alert notifications to the alert manager func (am *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error { - am.log.Info("Sending Alertmanager alert", "ruleId", evalContext.Rule.Id, "notification", am.Name) + am.log.Info("Sending Alertmanager alert", "ruleId", evalContext.Rule.ID, "notification", am.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { am.log.Error("Failed get rule link", "error", err) return err diff --git a/pkg/services/alerting/notifiers/base.go b/pkg/services/alerting/notifiers/base.go index 3ebe23c2d1b..f31c8b36d9c 100644 --- a/pkg/services/alerting/notifiers/base.go +++ b/pkg/services/alerting/notifiers/base.go @@ -120,8 +120,8 @@ func (n *NotifierBase) NeedsImage() bool { return n.UploadImage } -// GetNotifierUid returns the notifier `uid`. -func (n *NotifierBase) GetNotifierUid() string { +// GetNotifierUID returns the notifier `uid`. +func (n *NotifierBase) GetNotifierUID() string { return n.UID } diff --git a/pkg/services/alerting/notifiers/dingding.go b/pkg/services/alerting/notifiers/dingding.go index a418adc7e65..fc8ce477ecb 100644 --- a/pkg/services/alerting/notifiers/dingding.go +++ b/pkg/services/alerting/notifiers/dingding.go @@ -64,7 +64,7 @@ type DingDingNotifier struct { func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { dd.log.Info("Sending dingding") - messageURL, err := evalContext.GetRuleUrl() + messageURL, err := evalContext.GetRuleURL() if err != nil { dd.log.Error("Failed to get messageUrl", "error", err, "dingding", dd.Name) messageURL = "" @@ -82,7 +82,7 @@ func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { dd.log.Info("messageUrl:" + messageURL) message := evalContext.Rule.Message - picURL := evalContext.ImagePublicUrl + picURL := evalContext.ImagePublicURL title := evalContext.GetNotificationTitle() if message == "" { message = title diff --git a/pkg/services/alerting/notifiers/discord.go b/pkg/services/alerting/notifiers/discord.go index 160c76528dd..e011ec0c3e9 100644 --- a/pkg/services/alerting/notifiers/discord.go +++ b/pkg/services/alerting/notifiers/discord.go @@ -21,7 +21,7 @@ func init() { Type: "discord", Name: "Discord", Description: "Sends notifications to Discord", - Factory: NewDiscordNotifier, + Factory: newDiscordNotifier, OptionsTemplate: `

Discord settings

@@ -43,7 +43,7 @@ func init() { }) } -func NewDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, error) { +func newDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, error) { content := model.Settings.Get("content").MustString() url := model.Settings.Get("url").MustString() if url == "" { @@ -58,6 +58,8 @@ func NewDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, err }, nil } +// DiscordNotifier is responsible for sending alert +// notifications to discord. type DiscordNotifier struct { NotifierBase Content string @@ -65,20 +67,21 @@ type DiscordNotifier struct { log log.Logger } -func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { - this.log.Info("Sending alert notification to", "webhook_url", this.WebhookURL) +// Notify send an alert notification to Discord. +func (dn *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { + dn.log.Info("Sending alert notification to", "webhook_url", dn.WebhookURL) - ruleUrl, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { - this.log.Error("Failed get rule link", "error", err) + dn.log.Error("Failed get rule link", "error", err) return err } bodyJSON := simplejson.New() bodyJSON.Set("username", "Grafana") - if this.Content != "" { - bodyJSON.Set("content", this.Content) + if dn.Content != "" { + bodyJSON.Set("content", dn.Content) } fields := make([]map[string]interface{}, 0) @@ -103,7 +106,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { embed.Set("title", evalContext.GetNotificationTitle()) //Discord takes integer for color embed.Set("color", color) - embed.Set("url", ruleUrl) + embed.Set("url", ruleURL) embed.Set("description", evalContext.Rule.Message) embed.Set("type", "rich") embed.Set("fields", fields) @@ -112,9 +115,9 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { var image map[string]interface{} var embeddedImage = false - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { image = map[string]interface{}{ - "url": evalContext.ImagePublicUrl, + "url": evalContext.ImagePublicURL, } embed.Set("image", image) } else { @@ -130,7 +133,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { json, _ := bodyJSON.MarshalJSON() cmd := &models.SendWebhookSync{ - Url: this.WebhookURL, + Url: dn.WebhookURL, HttpMethod: "POST", ContentType: "application/json", } @@ -138,22 +141,22 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { if !embeddedImage { cmd.Body = string(json) } else { - err := this.embedImage(cmd, evalContext.ImageOnDiskPath, json) + err := dn.embedImage(cmd, evalContext.ImageOnDiskPath, json) if err != nil { - this.log.Error("failed to embed image", "error", err) + dn.log.Error("failed to embed image", "error", err) return err } } if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { - this.log.Error("Failed to send notification to Discord", "error", err) + dn.log.Error("Failed to send notification to Discord", "error", err) return err } return nil } -func (this *DiscordNotifier) embedImage(cmd *models.SendWebhookSync, imagePath string, existingJSONBody []byte) error { +func (dn *DiscordNotifier) embedImage(cmd *models.SendWebhookSync, imagePath string, existingJSONBody []byte) error { f, err := os.Open(imagePath) defer f.Close() if err != nil { diff --git a/pkg/services/alerting/notifiers/discord_test.go b/pkg/services/alerting/notifiers/discord_test.go index 5fe700245e2..d1cbff6b859 100644 --- a/pkg/services/alerting/notifiers/discord_test.go +++ b/pkg/services/alerting/notifiers/discord_test.go @@ -22,7 +22,7 @@ func TestDiscordNotifier(t *testing.T) { Settings: settingsJSON, } - _, err := NewDiscordNotifier(model) + _, err := newDiscordNotifier(model) So(err, ShouldNotBeNil) }) @@ -40,7 +40,7 @@ func TestDiscordNotifier(t *testing.T) { Settings: settingsJSON, } - not, err := NewDiscordNotifier(model) + not, err := newDiscordNotifier(model) discordNotifier := not.(*DiscordNotifier) So(err, ShouldBeNil) diff --git a/pkg/services/alerting/notifiers/email.go b/pkg/services/alerting/notifiers/email.go index 44a6b97653e..5d3422e608b 100644 --- a/pkg/services/alerting/notifiers/email.go +++ b/pkg/services/alerting/notifiers/email.go @@ -67,7 +67,7 @@ func NewEmailNotifier(model *models.AlertNotification) (alerting.Notifier, error func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error { en.log.Info("Sending alert notification to", "addresses", en.Addresses) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { en.log.Error("Failed get rule link", "error", err) return err @@ -100,8 +100,8 @@ func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error { }, } - if evalContext.ImagePublicUrl != "" { - cmd.Data["ImageLink"] = evalContext.ImagePublicUrl + if evalContext.ImagePublicURL != "" { + cmd.Data["ImageLink"] = evalContext.ImagePublicURL } else { file, err := os.Stat(evalContext.ImageOnDiskPath) if err == nil { diff --git a/pkg/services/alerting/notifiers/googlechat.go b/pkg/services/alerting/notifiers/googlechat.go index a7e452991b0..2d81787fb91 100644 --- a/pkg/services/alerting/notifiers/googlechat.go +++ b/pkg/services/alerting/notifiers/googlechat.go @@ -120,7 +120,7 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { "Content-Type": "application/json; charset=UTF-8", } - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { gcn.log.Error("evalContext returned an invalid rule URL") } @@ -152,10 +152,10 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { widgets = append(widgets, fields) // if an image exists, add it as an image widget - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { widgets = append(widgets, imageWidget{ Image: image{ - ImageURL: evalContext.ImagePublicUrl, + ImageURL: evalContext.ImagePublicURL, }, }) } else { diff --git a/pkg/services/alerting/notifiers/hipchat.go b/pkg/services/alerting/notifiers/hipchat.go index e817fe9a076..2e8be00576b 100644 --- a/pkg/services/alerting/notifiers/hipchat.go +++ b/pkg/services/alerting/notifiers/hipchat.go @@ -81,9 +81,9 @@ type HipChatNotifier struct { // Notify sends an alert notification to HipChat func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error { - hc.log.Info("Executing hipchat notification", "ruleId", evalContext.Rule.Id, "notification", hc.Name) + hc.log.Info("Executing hipchat notification", "ruleId", evalContext.Rule.ID, "notification", hc.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { hc.log.Error("Failed get rule link", "error", err) return err @@ -148,10 +148,10 @@ func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error { "date": evalContext.EndTime.Unix(), "attributes": attributes, } - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { card["thumbnail"] = map[string]interface{}{ - "url": evalContext.ImagePublicUrl, - "url@2x": evalContext.ImagePublicUrl, + "url": evalContext.ImagePublicURL, + "url@2x": evalContext.ImagePublicURL, "width": 1193, "height": 564, } diff --git a/pkg/services/alerting/notifiers/kafka.go b/pkg/services/alerting/notifiers/kafka.go index 9761adf2f6a..ed795453c42 100644 --- a/pkg/services/alerting/notifiers/kafka.go +++ b/pkg/services/alerting/notifiers/kafka.go @@ -78,20 +78,20 @@ func (kn *KafkaNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON.Set("description", evalContext.Rule.Name+" - "+evalContext.Rule.Message) bodyJSON.Set("client", "Grafana") bodyJSON.Set("details", customData) - bodyJSON.Set("incident_key", "alertId-"+strconv.FormatInt(evalContext.Rule.Id, 10)) + bodyJSON.Set("incident_key", "alertId-"+strconv.FormatInt(evalContext.Rule.ID, 10)) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { kn.log.Error("Failed get rule link", "error", err) return err } bodyJSON.Set("client_url", ruleURL) - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { contexts := make([]interface{}, 1) imageJSON := simplejson.New() imageJSON.Set("type", "image") - imageJSON.Set("src", evalContext.ImagePublicUrl) + imageJSON.Set("src", evalContext.ImagePublicURL) contexts[0] = imageJSON bodyJSON.Set("contexts", contexts) } diff --git a/pkg/services/alerting/notifiers/line.go b/pkg/services/alerting/notifiers/line.go index 6b84ba8f091..2048495b646 100644 --- a/pkg/services/alerting/notifiers/line.go +++ b/pkg/services/alerting/notifiers/line.go @@ -56,7 +56,7 @@ type LineNotifier struct { // Notify send an alert notification to LINE func (ln *LineNotifier) Notify(evalContext *alerting.EvalContext) error { - ln.log.Info("Executing line notification", "ruleId", evalContext.Rule.Id, "notification", ln.Name) + ln.log.Info("Executing line notification", "ruleId", evalContext.Rule.ID, "notification", ln.Name) var err error switch evalContext.Rule.State { @@ -67,8 +67,8 @@ func (ln *LineNotifier) Notify(evalContext *alerting.EvalContext) error { } func (ln *LineNotifier) createAlert(evalContext *alerting.EvalContext) error { - ln.log.Info("Creating Line notify", "ruleId", evalContext.Rule.Id, "notification", ln.Name) - ruleURL, err := evalContext.GetRuleUrl() + ln.log.Info("Creating Line notify", "ruleId", evalContext.Rule.ID, "notification", ln.Name) + ruleURL, err := evalContext.GetRuleURL() if err != nil { ln.log.Error("Failed get rule link", "error", err) return err @@ -78,9 +78,9 @@ func (ln *LineNotifier) createAlert(evalContext *alerting.EvalContext) error { body := fmt.Sprintf("%s - %s\n%s", evalContext.Rule.Name, ruleURL, evalContext.Rule.Message) form.Add("message", body) - if evalContext.ImagePublicUrl != "" { - form.Add("imageThumbnail", evalContext.ImagePublicUrl) - form.Add("imageFullsize", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + form.Add("imageThumbnail", evalContext.ImagePublicURL) + form.Add("imageFullsize", evalContext.ImagePublicURL) } cmd := &models.SendWebhookSync{ diff --git a/pkg/services/alerting/notifiers/opsgenie.go b/pkg/services/alerting/notifiers/opsgenie.go index 3adcdbc74ad..833927dee9f 100644 --- a/pkg/services/alerting/notifiers/opsgenie.go +++ b/pkg/services/alerting/notifiers/opsgenie.go @@ -90,9 +90,9 @@ func (on *OpsGenieNotifier) Notify(evalContext *alerting.EvalContext) error { } func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error { - on.log.Info("Creating OpsGenie alert", "ruleId", evalContext.Rule.Id, "notification", on.Name) + on.log.Info("Creating OpsGenie alert", "ruleId", evalContext.Rule.ID, "notification", on.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { on.log.Error("Failed get rule link", "error", err) return err @@ -106,13 +106,13 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error bodyJSON := simplejson.New() bodyJSON.Set("message", evalContext.Rule.Name) bodyJSON.Set("source", "Grafana") - bodyJSON.Set("alias", "alertId-"+strconv.FormatInt(evalContext.Rule.Id, 10)) + bodyJSON.Set("alias", "alertId-"+strconv.FormatInt(evalContext.Rule.ID, 10)) bodyJSON.Set("description", fmt.Sprintf("%s - %s\n%s\n%s", evalContext.Rule.Name, ruleURL, evalContext.Rule.Message, customData)) details := simplejson.New() details.Set("url", ruleURL) - if evalContext.ImagePublicUrl != "" { - details.Set("image", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + details.Set("image", evalContext.ImagePublicURL) } bodyJSON.Set("details", details) @@ -136,14 +136,14 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error } func (on *OpsGenieNotifier) closeAlert(evalContext *alerting.EvalContext) error { - on.log.Info("Closing OpsGenie alert", "ruleId", evalContext.Rule.Id, "notification", on.Name) + on.log.Info("Closing OpsGenie alert", "ruleId", evalContext.Rule.ID, "notification", on.Name) bodyJSON := simplejson.New() bodyJSON.Set("source", "Grafana") body, _ := bodyJSON.MarshalJSON() cmd := &models.SendWebhookSync{ - Url: fmt.Sprintf("%s/alertId-%d/close?identifierType=alias", on.APIUrl, evalContext.Rule.Id), + Url: fmt.Sprintf("%s/alertId-%d/close?identifierType=alias", on.APIUrl, evalContext.Rule.ID), Body: string(body), HttpMethod: "POST", HttpHeader: map[string]string{ diff --git a/pkg/services/alerting/notifiers/pagerduty.go b/pkg/services/alerting/notifiers/pagerduty.go index 99302c1af77..d771bfd1ad6 100644 --- a/pkg/services/alerting/notifiers/pagerduty.go +++ b/pkg/services/alerting/notifiers/pagerduty.go @@ -100,10 +100,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON := simplejson.New() bodyJSON.Set("routing_key", pn.Key) bodyJSON.Set("event_action", eventType) - bodyJSON.Set("dedup_key", "alertId-"+strconv.FormatInt(evalContext.Rule.Id, 10)) + bodyJSON.Set("dedup_key", "alertId-"+strconv.FormatInt(evalContext.Rule.ID, 10)) bodyJSON.Set("payload", payloadJSON) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { pn.log.Error("Failed get rule link", "error", err) return err @@ -116,10 +116,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error { links[0] = linkJSON bodyJSON.Set("links", links) - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { contexts := make([]interface{}, 1) imageJSON := simplejson.New() - imageJSON.Set("src", evalContext.ImagePublicUrl) + imageJSON.Set("src", evalContext.ImagePublicURL) contexts[0] = imageJSON bodyJSON.Set("images", contexts) } diff --git a/pkg/services/alerting/notifiers/pushover.go b/pkg/services/alerting/notifiers/pushover.go index 19de6ce08a2..5da1a457e67 100644 --- a/pkg/services/alerting/notifiers/pushover.go +++ b/pkg/services/alerting/notifiers/pushover.go @@ -146,7 +146,7 @@ type PushoverNotifier struct { // Notify sends a alert notification to Pushover func (pn *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error { - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { pn.log.Error("Failed get rule link", "error", err) return err diff --git a/pkg/services/alerting/notifiers/sensu.go b/pkg/services/alerting/notifiers/sensu.go index 7650cb222d9..7f60178d10f 100644 --- a/pkg/services/alerting/notifiers/sensu.go +++ b/pkg/services/alerting/notifiers/sensu.go @@ -79,7 +79,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { sn.log.Info("Sending sensu result") bodyJSON := simplejson.New() - bodyJSON.Set("ruleId", evalContext.Rule.Id) + bodyJSON.Set("ruleId", evalContext.Rule.ID) // Sensu alerts cannot have spaces in them bodyJSON.Set("name", strings.Replace(evalContext.Rule.Name, " ", "_", -1)) // Sensu alerts require a source. We set it to the user-specified value (optional), @@ -87,7 +87,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { if sn.Source != "" { bodyJSON.Set("source", sn.Source) } else { - bodyJSON.Set("source", "grafana_rule_"+strconv.FormatInt(evalContext.Rule.Id, 10)) + bodyJSON.Set("source", "grafana_rule_"+strconv.FormatInt(evalContext.Rule.ID, 10)) } // Finally, sensu expects an output // We set it to a default output @@ -106,13 +106,13 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON.Set("handler", sn.Handler) } - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err == nil { bodyJSON.Set("ruleUrl", ruleURL) } - if evalContext.ImagePublicUrl != "" { - bodyJSON.Set("imageUrl", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + bodyJSON.Set("imageUrl", evalContext.ImagePublicURL) } if evalContext.Rule.Message != "" { diff --git a/pkg/services/alerting/notifiers/slack.go b/pkg/services/alerting/notifiers/slack.go index f8cad904270..b9a10c4d5d1 100644 --- a/pkg/services/alerting/notifiers/slack.go +++ b/pkg/services/alerting/notifiers/slack.go @@ -145,9 +145,9 @@ type SlackNotifier struct { // Notify send alert notification to Slack. func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error { - sn.log.Info("Executing slack notification", "ruleId", evalContext.Rule.Id, "notification", sn.Name) + sn.log.Info("Executing slack notification", "ruleId", evalContext.Rule.ID, "notification", sn.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { sn.log.Error("Failed get rule link", "error", err) return err @@ -181,7 +181,7 @@ func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error { imageURL := "" // default to file.upload API method if a token is provided if sn.Token == "" { - imageURL = evalContext.ImagePublicUrl + imageURL = evalContext.ImagePublicURL } body := map[string]interface{}{ diff --git a/pkg/services/alerting/notifiers/teams.go b/pkg/services/alerting/notifiers/teams.go index 4a2cfa1ca91..4d0c47ddad2 100644 --- a/pkg/services/alerting/notifiers/teams.go +++ b/pkg/services/alerting/notifiers/teams.go @@ -50,9 +50,9 @@ type TeamsNotifier struct { // Notify send an alert notification to Microsoft teams. func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { - tn.log.Info("Executing teams notification", "ruleId", evalContext.Rule.Id, "notification", tn.Name) + tn.log.Info("Executing teams notification", "ruleId", evalContext.Rule.ID, "notification", tn.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { tn.log.Error("Failed get rule link", "error", err) return err @@ -83,9 +83,9 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { } images := make([]map[string]interface{}, 0) - if evalContext.ImagePublicUrl != "" { + if evalContext.ImagePublicURL != "" { images = append(images, map[string]interface{}{ - "image": evalContext.ImagePublicUrl, + "image": evalContext.ImagePublicURL, }) } @@ -122,7 +122,7 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { "name": "View Graph", "targets": []map[string]interface{}{ { - "os": "default", "uri": evalContext.ImagePublicUrl, + "os": "default", "uri": evalContext.ImagePublicURL, }, }, }, diff --git a/pkg/services/alerting/notifiers/telegram.go b/pkg/services/alerting/notifiers/telegram.go index 0c2e8557982..be354bc2733 100644 --- a/pkg/services/alerting/notifiers/telegram.go +++ b/pkg/services/alerting/notifiers/telegram.go @@ -104,13 +104,13 @@ func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, send func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalContext) *models.SendWebhookSync { message := fmt.Sprintf("%s\nState: %s\nMessage: %s\n", evalContext.GetNotificationTitle(), evalContext.Rule.Name, evalContext.Rule.Message) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err == nil { message = message + fmt.Sprintf("URL: %s\n", ruleURL) } - if evalContext.ImagePublicUrl != "" { - message = message + fmt.Sprintf("Image: %s\n", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + message = message + fmt.Sprintf("Image: %s\n", evalContext.ImagePublicURL) } metrics := generateMetricsMessage(evalContext) @@ -141,7 +141,7 @@ func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalCo return nil, err } - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { return nil, err } @@ -232,7 +232,7 @@ func appendIfPossible(message string, extra string, sizeLimit int) string { // Notify send an alert notification to Telegram. func (tn *TelegramNotifier) Notify(evalContext *alerting.EvalContext) error { var cmd *models.SendWebhookSync - if evalContext.ImagePublicUrl == "" && tn.UploadImage { + if evalContext.ImagePublicURL == "" && tn.UploadImage { cmd = tn.buildMessage(evalContext, true) } else { cmd = tn.buildMessage(evalContext, false) diff --git a/pkg/services/alerting/notifiers/threema.go b/pkg/services/alerting/notifiers/threema.go index 621a04a85d5..560e8c12e80 100644 --- a/pkg/services/alerting/notifiers/threema.go +++ b/pkg/services/alerting/notifiers/threema.go @@ -143,12 +143,12 @@ func (notifier *ThreemaNotifier) Notify(evalContext *alerting.EvalContext) error message := fmt.Sprintf("%s%s\n\n*State:* %s\n*Message:* %s\n", stateEmoji, evalContext.GetNotificationTitle(), evalContext.Rule.Name, evalContext.Rule.Message) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err == nil { message = message + fmt.Sprintf("*URL:* %s\n", ruleURL) } - if evalContext.ImagePublicUrl != "" { - message = message + fmt.Sprintf("*Image:* %s\n", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + message = message + fmt.Sprintf("*Image:* %s\n", evalContext.ImagePublicURL) } data.Set("text", message) diff --git a/pkg/services/alerting/notifiers/victorops.go b/pkg/services/alerting/notifiers/victorops.go index c118d811b9c..d19ea356547 100644 --- a/pkg/services/alerting/notifiers/victorops.go +++ b/pkg/services/alerting/notifiers/victorops.go @@ -70,9 +70,9 @@ type VictoropsNotifier struct { // Notify sends notification to Victorops via POST to URL endpoint func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error { - vn.log.Info("Executing victorops notification", "ruleId", evalContext.Rule.Id, "notification", vn.Name) + vn.log.Info("Executing victorops notification", "ruleId", evalContext.Rule.ID, "notification", vn.Name) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err != nil { vn.log.Error("Failed get rule link", "error", err) return err @@ -116,8 +116,8 @@ func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON.Set("error_message", evalContext.Error.Error()) } - if evalContext.ImagePublicUrl != "" { - bodyJSON.Set("image_url", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + bodyJSON.Set("image_url", evalContext.ImagePublicURL) } data, _ := bodyJSON.MarshalJSON() diff --git a/pkg/services/alerting/notifiers/webhook.go b/pkg/services/alerting/notifiers/webhook.go index 3c10c50c5d0..f5ee9924512 100644 --- a/pkg/services/alerting/notifiers/webhook.go +++ b/pkg/services/alerting/notifiers/webhook.go @@ -76,18 +76,18 @@ func (wn *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error { bodyJSON := simplejson.New() bodyJSON.Set("title", evalContext.GetNotificationTitle()) - bodyJSON.Set("ruleId", evalContext.Rule.Id) + bodyJSON.Set("ruleId", evalContext.Rule.ID) bodyJSON.Set("ruleName", evalContext.Rule.Name) bodyJSON.Set("state", evalContext.Rule.State) bodyJSON.Set("evalMatches", evalContext.EvalMatches) - ruleURL, err := evalContext.GetRuleUrl() + ruleURL, err := evalContext.GetRuleURL() if err == nil { bodyJSON.Set("ruleUrl", ruleURL) } - if evalContext.ImagePublicUrl != "" { - bodyJSON.Set("imageUrl", evalContext.ImagePublicUrl) + if evalContext.ImagePublicURL != "" { + bodyJSON.Set("imageUrl", evalContext.ImagePublicURL) } if evalContext.Rule.Message != "" { diff --git a/pkg/services/alerting/result_handler.go b/pkg/services/alerting/result_handler.go index 7141c6cec46..814a3f8a21e 100644 --- a/pkg/services/alerting/result_handler.go +++ b/pkg/services/alerting/result_handler.go @@ -46,11 +46,11 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error { metrics.M_Alerting_Result_State.WithLabelValues(string(evalContext.Rule.State)).Inc() if evalContext.shouldUpdateAlertState() { - handler.log.Info("New state change", "alertId", evalContext.Rule.Id, "newState", evalContext.Rule.State, "prev state", evalContext.PrevAlertState) + handler.log.Info("New state change", "alertId", evalContext.Rule.ID, "newState", evalContext.Rule.State, "prev state", evalContext.PrevAlertState) cmd := &models.SetAlertStateCommand{ - AlertId: evalContext.Rule.Id, - OrgId: evalContext.Rule.OrgId, + AlertId: evalContext.Rule.ID, + OrgId: evalContext.Rule.OrgID, State: evalContext.Rule.State, Error: executionError, EvalData: annotationData, @@ -81,10 +81,10 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error { // save annotation item := annotations.Item{ - OrgId: evalContext.Rule.OrgId, - DashboardId: evalContext.Rule.DashboardId, - PanelId: evalContext.Rule.PanelId, - AlertId: evalContext.Rule.Id, + OrgId: evalContext.Rule.OrgID, + DashboardId: evalContext.Rule.DashboardID, + PanelId: evalContext.Rule.PanelID, + AlertId: evalContext.Rule.ID, Text: "", NewState: string(evalContext.Rule.State), PrevState: string(evalContext.PrevAlertState), diff --git a/pkg/services/alerting/rule.go b/pkg/services/alerting/rule.go index 422148bc42f..9a4065e279d 100644 --- a/pkg/services/alerting/rule.go +++ b/pkg/services/alerting/rule.go @@ -21,10 +21,10 @@ var ( // Rule is the in-memory version of an alert rule. type Rule struct { - Id int64 - OrgId int64 - DashboardId int64 - PanelId int64 + ID int64 + OrgID int64 + DashboardID int64 + PanelID int64 Frequency int64 Name string Message string @@ -44,23 +44,23 @@ type Rule struct { type ValidationError struct { Reason string Err error - Alertid int64 - DashboardId int64 - PanelId int64 + AlertID int64 + DashboardID int64 + PanelID int64 } func (e ValidationError) Error() string { extraInfo := e.Reason - if e.Alertid != 0 { - extraInfo = fmt.Sprintf("%s AlertId: %v", extraInfo, e.Alertid) + if e.AlertID != 0 { + extraInfo = fmt.Sprintf("%s AlertId: %v", extraInfo, e.AlertID) } - if e.PanelId != 0 { - extraInfo = fmt.Sprintf("%s PanelId: %v", extraInfo, e.PanelId) + if e.PanelID != 0 { + extraInfo = fmt.Sprintf("%s PanelId: %v", extraInfo, e.PanelID) } - if e.DashboardId != 0 { - extraInfo = fmt.Sprintf("%s DashboardId: %v", extraInfo, e.DashboardId) + if e.DashboardID != 0 { + extraInfo = fmt.Sprintf("%s DashboardId: %v", extraInfo, e.DashboardID) } if e.Err != nil { @@ -113,10 +113,10 @@ func getTimeDurationStringToSeconds(str string) (int64, error) { // alert to an in-memory version. func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { model := &Rule{} - model.Id = ruleDef.Id - model.OrgId = ruleDef.OrgId - model.DashboardId = ruleDef.DashboardId - model.PanelId = ruleDef.PanelId + model.ID = ruleDef.Id + model.OrgID = ruleDef.OrgId + model.DashboardID = ruleDef.DashboardId + model.PanelID = ruleDef.PanelId model.Name = ruleDef.Name model.Message = ruleDef.Message model.State = ruleDef.State @@ -140,7 +140,7 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { } else { uid, err := jsonModel.Get("uid").String() if err != nil { - return nil, ValidationError{Reason: "Neither id nor uid is specified, " + err.Error(), DashboardId: model.DashboardId, Alertid: model.Id, PanelId: model.PanelId} + return nil, ValidationError{Reason: "Neither id nor uid is specified, " + err.Error(), DashboardID: model.DashboardID, AlertID: model.ID, PanelID: model.PanelID} } model.Notifications = append(model.Notifications, uid) } @@ -151,11 +151,11 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { conditionType := conditionModel.Get("type").MustString() factory, exist := conditionFactories[conditionType] if !exist { - return nil, ValidationError{Reason: "Unknown alert condition: " + conditionType, DashboardId: model.DashboardId, Alertid: model.Id, PanelId: model.PanelId} + return nil, ValidationError{Reason: "Unknown alert condition: " + conditionType, DashboardID: model.DashboardID, AlertID: model.ID, PanelID: model.PanelID} } queryCondition, err := factory(conditionModel, index) if err != nil { - return nil, ValidationError{Err: err, DashboardId: model.DashboardId, Alertid: model.Id, PanelId: model.PanelId} + return nil, ValidationError{Err: err, DashboardID: model.DashboardID, AlertID: model.ID, PanelID: model.PanelID} } model.Conditions = append(model.Conditions, queryCondition) } diff --git a/pkg/services/alerting/scheduler.go b/pkg/services/alerting/scheduler.go index 62ef35298fc..b01618f4095 100644 --- a/pkg/services/alerting/scheduler.go +++ b/pkg/services/alerting/scheduler.go @@ -27,8 +27,8 @@ func (s *schedulerImpl) Update(rules []*Rule) { for i, rule := range rules { var job *Job - if s.jobs[rule.Id] != nil { - job = s.jobs[rule.Id] + if s.jobs[rule.ID] != nil { + job = s.jobs[rule.ID] } else { job = &Job{ Running: false, @@ -42,7 +42,7 @@ func (s *schedulerImpl) Update(rules []*Rule) { if job.Offset == 0 { //zero offset causes division with 0 panics. job.Offset = 1 } - jobs[rule.Id] = job + jobs[rule.ID] = job } s.jobs = jobs @@ -73,6 +73,6 @@ func (s *schedulerImpl) Tick(tickTime time.Time, execQueue chan *Job) { } func (s *schedulerImpl) enqueue(job *Job, execQueue chan *Job) { - s.log.Debug("Scheduler: Putting job on to exec queue", "name", job.Rule.Name, "id", job.Rule.Id) + s.log.Debug("Scheduler: Putting job on to exec queue", "name", job.Rule.Name, "id", job.Rule.ID) execQueue <- job } diff --git a/pkg/services/alerting/test_notification.go b/pkg/services/alerting/test_notification.go index 3651fffa68b..311109ed607 100644 --- a/pkg/services/alerting/test_notification.go +++ b/pkg/services/alerting/test_notification.go @@ -49,8 +49,8 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error { func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext { testRule := &Rule{ - DashboardId: 1, - PanelId: 1, + DashboardID: 1, + PanelID: 1, Name: "Test notification", Message: "Someone is testing the alert notification within grafana.", State: models.AlertStateAlerting, @@ -58,7 +58,7 @@ func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext { ctx := NewEvalContext(context.Background(), testRule) if cmd.Settings.Get("uploadImage").MustBool(true) { - ctx.ImagePublicUrl = "https://grafana.com/assets/img/blog/mixed_styles.png" + ctx.ImagePublicURL = "https://grafana.com/assets/img/blog/mixed_styles.png" } ctx.IsTestRun = true ctx.Firing = true diff --git a/pkg/services/alerting/test_rule.go b/pkg/services/alerting/test_rule.go index 7a44845614b..1575490ea32 100644 --- a/pkg/services/alerting/test_rule.go +++ b/pkg/services/alerting/test_rule.go @@ -13,8 +13,8 @@ import ( // of an alert rule. type AlertTestCommand struct { Dashboard *simplejson.Json - PanelId int64 - OrgId int64 + PanelID int64 + OrgID int64 User *models.SignedInUser Result *EvalContext @@ -28,14 +28,14 @@ func handleAlertTestCommand(cmd *AlertTestCommand) error { dash := models.NewDashboardFromJson(cmd.Dashboard) - extractor := NewDashAlertExtractor(dash, cmd.OrgId, cmd.User) + extractor := NewDashAlertExtractor(dash, cmd.OrgID, cmd.User) alerts, err := extractor.GetAlerts() if err != nil { return err } for _, alert := range alerts { - if alert.PanelId == cmd.PanelId { + if alert.PanelId == cmd.PanelID { rule, err := NewRuleFromDBAlert(alert) if err != nil { return err @@ -46,7 +46,7 @@ func handleAlertTestCommand(cmd *AlertTestCommand) error { } } - return fmt.Errorf("Could not find alert with panel id %d", cmd.PanelId) + return fmt.Errorf("Could not find alert with panel id %d", cmd.PanelID) } func testAlertRule(rule *Rule) *EvalContext { diff --git a/scripts/backend-lint.sh b/scripts/backend-lint.sh index 6e7305364fd..09b035bff6e 100755 --- a/scripts/backend-lint.sh +++ b/scripts/backend-lint.sh @@ -36,4 +36,5 @@ exit_if_fail golangci-lint run --deadline 10m --disable-all \ exit_if_fail go vet ./pkg/... exit_if_fail make revive +exit_if_fail make revive-alerting exit_if_fail make gosec