Commit d8736a25 by Carl Bergquist Committed by GitHub

Alerting: golint fixes for alerting (#17246)

parent 60ddad8f
-include local/Makefile -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 := GO111MODULE=on go
GO_FILES := ./pkg/... GO_FILES := ./pkg/...
...@@ -84,6 +84,11 @@ revive: scripts/go/bin/revive ...@@ -84,6 +84,11 @@ revive: scripts/go/bin/revive
-config ./scripts/go/configs/revive.toml \ -config ./scripts/go/configs/revive.toml \
$(GO_FILES) $(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 # create docker-compose file with provided sources and start them
# example: make devenv sources=postgres,openldap # example: make devenv sources=postgres,openldap
ifeq ($(sources),) ifeq ($(sources),)
......
...@@ -131,9 +131,9 @@ func AlertTest(c *m.ReqContext, dto dtos.AlertTestCommand) Response { ...@@ -131,9 +131,9 @@ func AlertTest(c *m.ReqContext, dto dtos.AlertTestCommand) Response {
} }
backendCmd := alerting.AlertTestCommand{ backendCmd := alerting.AlertTestCommand{
OrgId: c.OrgId, OrgID: c.OrgId,
Dashboard: dto.Dashboard, Dashboard: dto.Dashboard,
PanelId: dto.PanelId, PanelID: dto.PanelId,
User: c.SignedInUser, User: c.SignedInUser,
} }
......
...@@ -14,22 +14,25 @@ var ( ...@@ -14,22 +14,25 @@ var (
rangedTypes = []string{"within_range", "outside_range"} 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 { type AlertEvaluator interface {
Eval(reducedValue null.Float) bool 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 return !reducedValue.Valid
} }
type ThresholdEvaluator struct { type thresholdEvaluator struct {
Type string Type string
Threshold float64 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() params := model.Get("params").MustArray()
if len(params) == 0 { if len(params) == 0 {
return nil, fmt.Errorf("Evaluator missing threshold parameter") return nil, fmt.Errorf("Evaluator missing threshold parameter")
...@@ -40,12 +43,12 @@ func newThresholdEvaluator(typ string, model *simplejson.Json) (*ThresholdEvalua ...@@ -40,12 +43,12 @@ func newThresholdEvaluator(typ string, model *simplejson.Json) (*ThresholdEvalua
return nil, fmt.Errorf("Evaluator has invalid parameter") return nil, fmt.Errorf("Evaluator has invalid parameter")
} }
defaultEval := &ThresholdEvaluator{Type: typ} defaultEval := &thresholdEvaluator{Type: typ}
defaultEval.Threshold, _ = firstParam.Float64() defaultEval.Threshold, _ = firstParam.Float64()
return defaultEval, nil return defaultEval, nil
} }
func (e *ThresholdEvaluator) Eval(reducedValue null.Float) bool { func (e *thresholdEvaluator) Eval(reducedValue null.Float) bool {
if !reducedValue.Valid { if !reducedValue.Valid {
return false return false
} }
...@@ -60,13 +63,13 @@ func (e *ThresholdEvaluator) Eval(reducedValue null.Float) bool { ...@@ -60,13 +63,13 @@ func (e *ThresholdEvaluator) Eval(reducedValue null.Float) bool {
return false return false
} }
type RangedEvaluator struct { type rangedEvaluator struct {
Type string Type string
Lower float64 Lower float64
Upper 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() params := model.Get("params").MustArray()
if len(params) == 0 { if len(params) == 0 {
return nil, alerting.ValidationError{Reason: "Evaluator missing threshold parameter"} return nil, alerting.ValidationError{Reason: "Evaluator missing threshold parameter"}
...@@ -82,13 +85,13 @@ func newRangedEvaluator(typ string, model *simplejson.Json) (*RangedEvaluator, e ...@@ -82,13 +85,13 @@ func newRangedEvaluator(typ string, model *simplejson.Json) (*RangedEvaluator, e
return nil, alerting.ValidationError{Reason: "Evaluator has invalid second parameter"} return nil, alerting.ValidationError{Reason: "Evaluator has invalid second parameter"}
} }
rangedEval := &RangedEvaluator{Type: typ} rangedEval := &rangedEvaluator{Type: typ}
rangedEval.Lower, _ = firstParam.Float64() rangedEval.Lower, _ = firstParam.Float64()
rangedEval.Upper, _ = secondParam.Float64() rangedEval.Upper, _ = secondParam.Float64()
return rangedEval, nil return rangedEval, nil
} }
func (e *RangedEvaluator) Eval(reducedValue null.Float) bool { func (e *rangedEvaluator) Eval(reducedValue null.Float) bool {
if !reducedValue.Valid { if !reducedValue.Valid {
return false return false
} }
...@@ -105,6 +108,8 @@ func (e *RangedEvaluator) Eval(reducedValue null.Float) bool { ...@@ -105,6 +108,8 @@ func (e *RangedEvaluator) Eval(reducedValue null.Float) bool {
return false return false
} }
// NewAlertEvaluator is a factory function for returning
// an `AlertEvaluator` depending on the json model.
func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) { func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) {
typ := model.Get("type").MustString() typ := model.Get("type").MustString()
if typ == "" { if typ == "" {
...@@ -120,7 +125,7 @@ func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) { ...@@ -120,7 +125,7 @@ func NewAlertEvaluator(model *simplejson.Json) (AlertEvaluator, error) {
} }
if typ == "no_value" { if typ == "no_value" {
return &NoValueEvaluator{}, nil return &noValueEvaluator{}, nil
} }
return nil, fmt.Errorf("Evaluator invalid evaluator type: %s", typ) return nil, fmt.Errorf("Evaluator invalid evaluator type: %s", typ)
......
...@@ -17,26 +17,31 @@ import ( ...@@ -17,26 +17,31 @@ import (
func init() { func init() {
alerting.RegisterCondition("query", func(model *simplejson.Json, index int) (alerting.Condition, error) { 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 { type QueryCondition struct {
Index int Index int
Query AlertQuery Query AlertQuery
Reducer QueryReducer Reducer *queryReducer
Evaluator AlertEvaluator Evaluator AlertEvaluator
Operator string Operator string
HandleRequest tsdb.HandleRequestFunc HandleRequest tsdb.HandleRequestFunc
} }
// AlertQuery contains information about what datasource a query
// should be sent to and the query object.
type AlertQuery struct { type AlertQuery struct {
Model *simplejson.Json Model *simplejson.Json
DatasourceId int64 DatasourceID int64
From string From string
To string To string
} }
// Eval evaluates the `QueryCondition`.
func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.ConditionResult, error) { func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.ConditionResult, error) {
timeRange := tsdb.NewTimeRange(c.Query.From, c.Query.To) timeRange := tsdb.NewTimeRange(c.Query.From, c.Query.To)
...@@ -101,8 +106,8 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.Conditio ...@@ -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) { func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange *tsdb.TimeRange) (tsdb.TimeSeriesSlice, error) {
getDsInfo := &models.GetDataSourceByIdQuery{ getDsInfo := &models.GetDataSourceByIdQuery{
Id: c.Query.DatasourceId, Id: c.Query.DatasourceID,
OrgId: context.Rule.OrgId, OrgId: context.Rule.OrgID,
} }
if err := bus.Dispatch(getDsInfo); err != nil { if err := bus.Dispatch(getDsInfo); err != nil {
...@@ -154,16 +159,16 @@ func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, t ...@@ -154,16 +159,16 @@ func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, t
return req return req
} }
func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, error) { func newQueryCondition(model *simplejson.Json, index int) (*QueryCondition, error) {
condition := QueryCondition{} condition := QueryCondition{}
condition.Index = index condition.Index = index
condition.HandleRequest = tsdb.HandleRequest condition.HandleRequest = tsdb.HandleRequest
queryJson := model.Get("query") queryJSON := model.Get("query")
condition.Query.Model = queryJson.Get("model") condition.Query.Model = queryJSON.Get("model")
condition.Query.From = queryJson.Get("params").MustArray()[1].(string) condition.Query.From = queryJSON.Get("params").MustArray()[1].(string)
condition.Query.To = queryJson.Get("params").MustArray()[2].(string) condition.Query.To = queryJSON.Get("params").MustArray()[2].(string)
if err := validateFromValue(condition.Query.From); err != nil { if err := validateFromValue(condition.Query.From); err != nil {
return nil, err return nil, err
...@@ -173,20 +178,20 @@ func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, erro ...@@ -173,20 +178,20 @@ func NewQueryCondition(model *simplejson.Json, index int) (*QueryCondition, erro
return nil, err return nil, err
} }
condition.Query.DatasourceId = queryJson.Get("datasourceId").MustInt64() condition.Query.DatasourceID = queryJSON.Get("datasourceId").MustInt64()
reducerJson := model.Get("reducer") reducerJSON := model.Get("reducer")
condition.Reducer = NewSimpleReducer(reducerJson.Get("type").MustString()) condition.Reducer = newSimpleReducer(reducerJSON.Get("type").MustString())
evaluatorJson := model.Get("evaluator") evaluatorJSON := model.Get("evaluator")
evaluator, err := NewAlertEvaluator(evaluatorJson) evaluator, err := NewAlertEvaluator(evaluatorJSON)
if err != nil { if err != nil {
return nil, err return nil, err
} }
condition.Evaluator = evaluator condition.Evaluator = evaluator
operatorJson := model.Get("operator") operatorJSON := model.Get("operator")
operator := operatorJson.Get("type").MustString("and") operator := operatorJSON.Get("type").MustString("and")
condition.Operator = operator condition.Operator = operator
return &condition, nil return &condition, nil
......
...@@ -27,16 +27,15 @@ func TestQueryCondition(t *testing.T) { ...@@ -27,16 +27,15 @@ func TestQueryCondition(t *testing.T) {
So(ctx.condition.Query.From, ShouldEqual, "5m") So(ctx.condition.Query.From, ShouldEqual, "5m")
So(ctx.condition.Query.To, ShouldEqual, "now") 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() { Convey("Can read query reducer", func() {
reducer, ok := ctx.condition.Reducer.(*SimpleReducer) reducer := ctx.condition.Reducer
So(ok, ShouldBeTrue)
So(reducer.Type, ShouldEqual, "avg") So(reducer.Type, ShouldEqual, "avg")
}) })
Convey("Can read evaluator", func() { Convey("Can read evaluator", func() {
evaluator, ok := ctx.condition.Evaluator.(*ThresholdEvaluator) evaluator, ok := ctx.condition.Evaluator.(*thresholdEvaluator)
So(ok, ShouldBeTrue) So(ok, ShouldBeTrue)
So(evaluator.Type, ShouldEqual, "gt") So(evaluator.Type, ShouldEqual, "gt")
}) })
...@@ -163,7 +162,7 @@ func (ctx *queryConditionTestContext) exec() (*alerting.ConditionResult, error) ...@@ -163,7 +162,7 @@ func (ctx *queryConditionTestContext) exec() (*alerting.ConditionResult, error)
}`)) }`))
So(err, ShouldBeNil) So(err, ShouldBeNil)
condition, err := NewQueryCondition(jsonModel, 0) condition, err := newQueryCondition(jsonModel, 0)
So(err, ShouldBeNil) So(err, ShouldBeNil)
ctx.condition = condition ctx.condition = condition
......
...@@ -9,15 +9,15 @@ import ( ...@@ -9,15 +9,15 @@ import (
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
) )
type QueryReducer interface { // queryReducer reduces an timeserie to a nullable float
Reduce(timeSeries *tsdb.TimeSeries) null.Float type queryReducer struct {
}
type SimpleReducer struct { // Type is how the timeserie should be reduced.
// Ex avg, sum, max, min, count
Type string 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 { if len(series.Points) == 0 {
return null.FloatFromPtr(nil) return null.FloatFromPtr(nil)
} }
...@@ -31,7 +31,7 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { ...@@ -31,7 +31,7 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float {
for _, point := range series.Points { for _, point := range series.Points {
if point[0].Valid { if point[0].Valid {
value += point[0].Float64 value += point[0].Float64
validPointsCount += 1 validPointsCount++
allNull = false allNull = false
} }
} }
...@@ -117,8 +117,8 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float { ...@@ -117,8 +117,8 @@ func (s *SimpleReducer) Reduce(series *tsdb.TimeSeries) null.Float {
return null.FloatFrom(value) return null.FloatFrom(value)
} }
func NewSimpleReducer(typ string) *SimpleReducer { func newSimpleReducer(t string) *queryReducer {
return &SimpleReducer{Type: typ} return &queryReducer{Type: t}
} }
func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) { func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
......
...@@ -53,7 +53,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -53,7 +53,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("median should ignore null values", func() { Convey("median should ignore null values", func() {
reducer := NewSimpleReducer("median") reducer := newSimpleReducer("median")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -76,7 +76,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -76,7 +76,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("avg with only nulls", func() { Convey("avg with only nulls", func() {
reducer := NewSimpleReducer("avg") reducer := newSimpleReducer("avg")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -87,7 +87,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -87,7 +87,7 @@ func TestSimpleReducer(t *testing.T) {
Convey("count_non_null", func() { Convey("count_non_null", func() {
Convey("with null values and real values", func() { Convey("with null values and real values", func() {
reducer := NewSimpleReducer("count_non_null") reducer := newSimpleReducer("count_non_null")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -102,7 +102,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -102,7 +102,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("with null values", func() { Convey("with null values", func() {
reducer := NewSimpleReducer("count_non_null") reducer := newSimpleReducer("count_non_null")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -115,7 +115,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -115,7 +115,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("avg of number values and null values should ignore nulls", func() { Convey("avg of number values and null values should ignore nulls", func() {
reducer := NewSimpleReducer("avg") reducer := newSimpleReducer("avg")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -144,7 +144,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -144,7 +144,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("diff with only nulls", func() { Convey("diff with only nulls", func() {
reducer := NewSimpleReducer("diff") reducer := newSimpleReducer("diff")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -171,7 +171,7 @@ func TestSimpleReducer(t *testing.T) { ...@@ -171,7 +171,7 @@ func TestSimpleReducer(t *testing.T) {
}) })
Convey("percent_diff with only nulls", func() { Convey("percent_diff with only nulls", func() {
reducer := NewSimpleReducer("percent_diff") reducer := newSimpleReducer("percent_diff")
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
...@@ -184,8 +184,8 @@ func TestSimpleReducer(t *testing.T) { ...@@ -184,8 +184,8 @@ func TestSimpleReducer(t *testing.T) {
}) })
} }
func testReducer(typ string, datapoints ...float64) float64 { func testReducer(reducerType string, datapoints ...float64) float64 {
reducer := NewSimpleReducer(typ) reducer := newSimpleReducer(reducerType)
series := &tsdb.TimeSeries{ series := &tsdb.TimeSeries{
Name: "test time serie", Name: "test time serie",
} }
......
...@@ -17,10 +17,10 @@ import ( ...@@ -17,10 +17,10 @@ import (
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
// AlertingService is the background process that // AlertEngine is the background process that
// schedules alert evaluations and makes sure notifications // schedules alert evaluations and makes sure notifications
// are sent. // are sent.
type AlertingService struct { type AlertEngine struct {
RenderService rendering.Service `inject:""` RenderService rendering.Service `inject:""`
execQueue chan *Job execQueue chan *Job
...@@ -33,16 +33,16 @@ type AlertingService struct { ...@@ -33,16 +33,16 @@ type AlertingService struct {
} }
func init() { func init() {
registry.RegisterService(&AlertingService{}) registry.RegisterService(&AlertEngine{})
} }
// IsDisabled returns true if the alerting service is disable for this instance. // 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 return !setting.AlertingEnabled || !setting.ExecuteAlerts
} }
// Init initalizes the AlertingService. // 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.ticker = NewTicker(time.Now(), time.Second*0, clock.New())
e.execQueue = make(chan *Job, 1000) e.execQueue = make(chan *Job, 1000)
e.scheduler = newScheduler() e.scheduler = newScheduler()
...@@ -54,7 +54,7 @@ func (e *AlertingService) Init() error { ...@@ -54,7 +54,7 @@ func (e *AlertingService) Init() error {
} }
// Run starts the alerting service background process. // 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, ctx := errgroup.WithContext(ctx)
alertGroup.Go(func() error { return e.alertingTicker(ctx) }) alertGroup.Go(func() error { return e.alertingTicker(ctx) })
alertGroup.Go(func() error { return e.runJobDispatcher(ctx) }) alertGroup.Go(func() error { return e.runJobDispatcher(ctx) })
...@@ -63,7 +63,7 @@ func (e *AlertingService) Run(ctx context.Context) error { ...@@ -63,7 +63,7 @@ func (e *AlertingService) Run(ctx context.Context) error {
return err return err
} }
func (e *AlertingService) alertingTicker(grafanaCtx context.Context) error { func (e *AlertEngine) alertingTicker(grafanaCtx context.Context) error {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
e.log.Error("Scheduler Panic: stopping alertingTicker", "error", err, "stack", log.Stack(1)) 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 { ...@@ -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) dispatcherGroup, alertCtx := errgroup.WithContext(grafanaCtx)
for { for {
...@@ -105,7 +105,7 @@ var ( ...@@ -105,7 +105,7 @@ var (
unfinishedWorkTimeout = time.Second * 5 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() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
e.log.Error("Alert Panic", "error", err, "stack", log.Stack(1)) e.log.Error("Alert Panic", "error", err, "stack", log.Stack(1))
...@@ -140,7 +140,7 @@ func (e *AlertingService) processJobWithRetry(grafanaCtx context.Context, job *J ...@@ -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 job.Running = false
close(cancelChan) close(cancelChan)
for cancelFn := range cancelChan { for cancelFn := range cancelChan {
...@@ -149,7 +149,7 @@ func (e *AlertingService) endJob(err error, cancelChan chan context.CancelFunc, ...@@ -149,7 +149,7 @@ func (e *AlertingService) endJob(err error, cancelChan chan context.CancelFunc,
return err 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() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
e.log.Error("Alert Panic", "error", err, "stack", log.Stack(1)) 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 ...@@ -180,8 +180,8 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel
e.evalHandler.Eval(evalContext) e.evalHandler.Eval(evalContext)
span.SetTag("alertId", evalContext.Rule.Id) span.SetTag("alertId", evalContext.Rule.ID)
span.SetTag("dashboardId", evalContext.Rule.DashboardId) span.SetTag("dashboardId", evalContext.Rule.DashboardID)
span.SetTag("firing", evalContext.Firing) span.SetTag("firing", evalContext.Firing)
span.SetTag("nodatapoints", evalContext.NoDataFound) span.SetTag("nodatapoints", evalContext.NoDataFound)
span.SetTag("attemptID", attemptID) span.SetTag("attemptID", attemptID)
...@@ -194,7 +194,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel ...@@ -194,7 +194,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel
) )
if attemptID < setting.AlertingMaxAttempts { if attemptID < setting.AlertingMaxAttempts {
span.Finish() 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) attemptChan <- (attemptID + 1)
return return
} }
...@@ -212,7 +212,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel ...@@ -212,7 +212,7 @@ func (e *AlertingService) processJob(attemptID int, attemptChan chan int, cancel
evalContext.Rule.State = evalContext.GetNewState() evalContext.Rule.State = evalContext.GetNewState()
e.resultHandler.handle(evalContext) e.resultHandler.handle(evalContext)
span.Finish() 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) close(attemptChan)
}() }()
} }
...@@ -17,7 +17,7 @@ import ( ...@@ -17,7 +17,7 @@ import (
func TestEngineTimeouts(t *testing.T) { func TestEngineTimeouts(t *testing.T) {
Convey("Alerting engine timeout tests", t, func() { Convey("Alerting engine timeout tests", t, func() {
engine := &AlertingService{} engine := &AlertEngine{}
engine.Init() engine.Init()
setting.AlertingNotificationTimeout = 30 * time.Second setting.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3 setting.AlertingMaxAttempts = 3
......
...@@ -39,7 +39,7 @@ func (handler *FakeResultHandler) handle(evalContext *EvalContext) error { ...@@ -39,7 +39,7 @@ func (handler *FakeResultHandler) handle(evalContext *EvalContext) error {
func TestEngineProcessJob(t *testing.T) { func TestEngineProcessJob(t *testing.T) {
Convey("Alerting engine job processing", t, func() { Convey("Alerting engine job processing", t, func() {
engine := &AlertingService{} engine := &AlertEngine{}
engine.Init() engine.Init()
setting.AlertingEvaluationTimeout = 30 * time.Second setting.AlertingEvaluationTimeout = 30 * time.Second
setting.AlertingNotificationTimeout = 30 * time.Second setting.AlertingNotificationTimeout = 30 * time.Second
......
...@@ -26,7 +26,7 @@ type EvalContext struct { ...@@ -26,7 +26,7 @@ type EvalContext struct {
dashboardRef *models.DashboardRef dashboardRef *models.DashboardRef
ImagePublicUrl string ImagePublicURL string
ImageOnDiskPath string ImageOnDiskPath string
NoDataFound bool NoDataFound bool
PrevAlertState models.AlertStateType PrevAlertState models.AlertStateType
...@@ -102,7 +102,7 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) { ...@@ -102,7 +102,7 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) {
return c.dashboardRef, nil 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 { if err := bus.Dispatch(uidQuery); err != nil {
return nil, err return nil, err
} }
...@@ -113,8 +113,8 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) { ...@@ -113,8 +113,8 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) {
const urlFormat = "%s?fullscreen&edit&tab=alert&panelId=%d&orgId=%d" const urlFormat = "%s?fullscreen&edit&tab=alert&panelId=%d&orgId=%d"
// GetRuleUrl returns the url to the dashboard containing the alert. // GetRuleURL returns the url to the dashboard containing the alert.
func (c *EvalContext) GetRuleUrl() (string, error) { func (c *EvalContext) GetRuleURL() (string, error) {
if c.IsTestRun { if c.IsTestRun {
return setting.AppUrl, nil return setting.AppUrl, nil
} }
...@@ -123,7 +123,7 @@ func (c *EvalContext) GetRuleUrl() (string, error) { ...@@ -123,7 +123,7 @@ func (c *EvalContext) GetRuleUrl() (string, error) {
if err != nil { if err != nil {
return "", err 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. // GetNewState returns the new state from the alert rule evaluation.
...@@ -148,7 +148,7 @@ func (c *EvalContext) GetNewState() models.AlertStateType { ...@@ -148,7 +148,7 @@ func (c *EvalContext) GetNewState() models.AlertStateType {
func getNewStateInternal(c *EvalContext) models.AlertStateType { func getNewStateInternal(c *EvalContext) models.AlertStateType {
if c.Error != nil { if c.Error != nil {
c.log.Error("Alert Rule Result Error", c.log.Error("Alert Rule Result Error",
"ruleId", c.Rule.Id, "ruleId", c.Rule.ID,
"name", c.Rule.Name, "name", c.Rule.Name,
"error", c.Error, "error", c.Error,
"changing state to", c.Rule.ExecutionErrorState.ToAlertState()) "changing state to", c.Rule.ExecutionErrorState.ToAlertState())
...@@ -165,7 +165,7 @@ func getNewStateInternal(c *EvalContext) models.AlertStateType { ...@@ -165,7 +165,7 @@ func getNewStateInternal(c *EvalContext) models.AlertStateType {
if c.NoDataFound { if c.NoDataFound {
c.log.Info("Alert Rule returned no data", c.log.Info("Alert Rule returned no data",
"ruleId", c.Rule.Id, "ruleId", c.Rule.ID,
"name", c.Rule.Name, "name", c.Rule.Name,
"changing state to", c.Rule.NoDataState.ToAlertState()) "changing state to", c.Rule.NoDataState.ToAlertState())
......
...@@ -25,7 +25,7 @@ type Notifier interface { ...@@ -25,7 +25,7 @@ type Notifier interface {
// ShouldNotify checks this evaluation should send an alert notification // ShouldNotify checks this evaluation should send an alert notification
ShouldNotify(ctx context.Context, evalContext *EvalContext, notificationState *models.AlertNotificationState) bool ShouldNotify(ctx context.Context, evalContext *EvalContext, notificationState *models.AlertNotificationState) bool
GetNotifierUid() string GetNotifierUID() string
GetIsDefault() bool GetIsDefault() bool
GetSendReminder() bool GetSendReminder() bool
GetDisableResolveMessage() bool GetDisableResolveMessage() bool
......
...@@ -35,7 +35,7 @@ type notificationService struct { ...@@ -35,7 +35,7 @@ type notificationService struct {
} }
func (n *notificationService) SendIfNeeded(context *EvalContext) error { 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 { if err != nil {
return err return err
} }
...@@ -56,13 +56,13 @@ func (n *notificationService) SendIfNeeded(context *EvalContext) error { ...@@ -56,13 +56,13 @@ func (n *notificationService) SendIfNeeded(context *EvalContext) error {
func (n *notificationService) sendAndMarkAsComplete(evalContext *EvalContext, notifierState *notifierState) error { func (n *notificationService) sendAndMarkAsComplete(evalContext *EvalContext, notifierState *notifierState) error {
notifier := notifierState.notifier 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() metrics.M_Alerting_Notification_Sent.WithLabelValues(notifier.GetType()).Inc()
err := notifier.Notify(evalContext) err := notifier.Notify(evalContext)
if err != nil { 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 { if evalContext.IsTestRun {
...@@ -106,7 +106,7 @@ func (n *notificationService) sendNotifications(evalContext *EvalContext, notifi ...@@ -106,7 +106,7 @@ func (n *notificationService) sendNotifications(evalContext *EvalContext, notifi
for _, notifierState := range notifierStates { for _, notifierState := range notifierStates {
err := n.sendNotification(evalContext, notifierState) err := n.sendNotification(evalContext, notifierState)
if err != nil { 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) { ...@@ -123,7 +123,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) {
Width: 1000, Width: 1000,
Height: 500, Height: 500,
Timeout: setting.AlertingEvaluationTimeout, Timeout: setting.AlertingEvaluationTimeout,
OrgId: context.Rule.OrgId, OrgId: context.Rule.OrgID,
OrgRole: models.ROLE_ADMIN, OrgRole: models.ROLE_ADMIN,
ConcurrentLimit: setting.AlertingRenderLimit, ConcurrentLimit: setting.AlertingRenderLimit,
} }
...@@ -133,7 +133,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { ...@@ -133,7 +133,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) {
return err 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) result, err := n.renderService.Render(context.Ctx, renderOpts)
if err != nil { if err != nil {
...@@ -141,13 +141,13 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) { ...@@ -141,13 +141,13 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) {
} }
context.ImageOnDiskPath = result.FilePath 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 { if err != nil {
return err return err
} }
if context.ImagePublicUrl != "" { if context.ImagePublicURL != "" {
n.log.Info("uploaded screenshot of alert to external image store", "url", context.ImagePublicUrl) n.log.Info("uploaded screenshot of alert to external image store", "url", context.ImagePublicURL)
} }
return nil return nil
...@@ -170,8 +170,8 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [ ...@@ -170,8 +170,8 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [
query := &models.GetOrCreateNotificationStateQuery{ query := &models.GetOrCreateNotificationStateQuery{
NotifierId: notification.Id, NotifierId: notification.Id,
AlertId: evalContext.Rule.Id, AlertId: evalContext.Rule.ID,
OrgId: evalContext.Rule.OrgId, OrgId: evalContext.Rule.OrgID,
} }
err = bus.DispatchCtx(evalContext.Ctx, query) err = bus.DispatchCtx(evalContext.Ctx, query)
......
...@@ -51,7 +51,7 @@ type AlertmanagerNotifier struct { ...@@ -51,7 +51,7 @@ type AlertmanagerNotifier struct {
// ShouldNotify returns true if the notifiers should be used depending on state // 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 { 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. // Do not notify when we become OK for the first time.
if (evalContext.PrevAlertState == models.AlertStatePending) && (evalContext.Rule.State == models.AlertStateOK) { if (evalContext.PrevAlertState == models.AlertStatePending) && (evalContext.Rule.State == models.AlertStateOK) {
...@@ -89,8 +89,8 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m ...@@ -89,8 +89,8 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m
if description != "" { if description != "" {
alertJSON.SetPath([]string{"annotations", "description"}, description) alertJSON.SetPath([]string{"annotations", "description"}, description)
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
alertJSON.SetPath([]string{"annotations", "image"}, evalContext.ImagePublicUrl) alertJSON.SetPath([]string{"annotations", "image"}, evalContext.ImagePublicURL)
} }
// Labels (from metrics tags + mandatory alertname). // Labels (from metrics tags + mandatory alertname).
...@@ -111,9 +111,9 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m ...@@ -111,9 +111,9 @@ func (am *AlertmanagerNotifier) createAlert(evalContext *alerting.EvalContext, m
// Notify sends alert notifications to the alert manager // Notify sends alert notifications to the alert manager
func (am *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error { 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 { if err != nil {
am.log.Error("Failed get rule link", "error", err) am.log.Error("Failed get rule link", "error", err)
return err return err
......
...@@ -120,8 +120,8 @@ func (n *NotifierBase) NeedsImage() bool { ...@@ -120,8 +120,8 @@ func (n *NotifierBase) NeedsImage() bool {
return n.UploadImage return n.UploadImage
} }
// GetNotifierUid returns the notifier `uid`. // GetNotifierUID returns the notifier `uid`.
func (n *NotifierBase) GetNotifierUid() string { func (n *NotifierBase) GetNotifierUID() string {
return n.UID return n.UID
} }
......
...@@ -64,7 +64,7 @@ type DingDingNotifier struct { ...@@ -64,7 +64,7 @@ type DingDingNotifier struct {
func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error {
dd.log.Info("Sending dingding") dd.log.Info("Sending dingding")
messageURL, err := evalContext.GetRuleUrl() messageURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
dd.log.Error("Failed to get messageUrl", "error", err, "dingding", dd.Name) dd.log.Error("Failed to get messageUrl", "error", err, "dingding", dd.Name)
messageURL = "" messageURL = ""
...@@ -82,7 +82,7 @@ func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -82,7 +82,7 @@ func (dd *DingDingNotifier) Notify(evalContext *alerting.EvalContext) error {
dd.log.Info("messageUrl:" + messageURL) dd.log.Info("messageUrl:" + messageURL)
message := evalContext.Rule.Message message := evalContext.Rule.Message
picURL := evalContext.ImagePublicUrl picURL := evalContext.ImagePublicURL
title := evalContext.GetNotificationTitle() title := evalContext.GetNotificationTitle()
if message == "" { if message == "" {
message = title message = title
......
...@@ -21,7 +21,7 @@ func init() { ...@@ -21,7 +21,7 @@ func init() {
Type: "discord", Type: "discord",
Name: "Discord", Name: "Discord",
Description: "Sends notifications to Discord", Description: "Sends notifications to Discord",
Factory: NewDiscordNotifier, Factory: newDiscordNotifier,
OptionsTemplate: ` OptionsTemplate: `
<h3 class="page-heading">Discord settings</h3> <h3 class="page-heading">Discord settings</h3>
<div class="gf-form max-width-30"> <div class="gf-form max-width-30">
...@@ -43,7 +43,7 @@ func init() { ...@@ -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() content := model.Settings.Get("content").MustString()
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
...@@ -58,6 +58,8 @@ func NewDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, err ...@@ -58,6 +58,8 @@ func NewDiscordNotifier(model *models.AlertNotification) (alerting.Notifier, err
}, nil }, nil
} }
// DiscordNotifier is responsible for sending alert
// notifications to discord.
type DiscordNotifier struct { type DiscordNotifier struct {
NotifierBase NotifierBase
Content string Content string
...@@ -65,20 +67,21 @@ type DiscordNotifier struct { ...@@ -65,20 +67,21 @@ type DiscordNotifier struct {
log log.Logger log log.Logger
} }
func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { // Notify send an alert notification to Discord.
this.log.Info("Sending alert notification to", "webhook_url", this.WebhookURL) 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 { if err != nil {
this.log.Error("Failed get rule link", "error", err) dn.log.Error("Failed get rule link", "error", err)
return err return err
} }
bodyJSON := simplejson.New() bodyJSON := simplejson.New()
bodyJSON.Set("username", "Grafana") bodyJSON.Set("username", "Grafana")
if this.Content != "" { if dn.Content != "" {
bodyJSON.Set("content", this.Content) bodyJSON.Set("content", dn.Content)
} }
fields := make([]map[string]interface{}, 0) fields := make([]map[string]interface{}, 0)
...@@ -103,7 +106,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -103,7 +106,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error {
embed.Set("title", evalContext.GetNotificationTitle()) embed.Set("title", evalContext.GetNotificationTitle())
//Discord takes integer for color //Discord takes integer for color
embed.Set("color", color) embed.Set("color", color)
embed.Set("url", ruleUrl) embed.Set("url", ruleURL)
embed.Set("description", evalContext.Rule.Message) embed.Set("description", evalContext.Rule.Message)
embed.Set("type", "rich") embed.Set("type", "rich")
embed.Set("fields", fields) embed.Set("fields", fields)
...@@ -112,9 +115,9 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -112,9 +115,9 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error {
var image map[string]interface{} var image map[string]interface{}
var embeddedImage = false var embeddedImage = false
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
image = map[string]interface{}{ image = map[string]interface{}{
"url": evalContext.ImagePublicUrl, "url": evalContext.ImagePublicURL,
} }
embed.Set("image", image) embed.Set("image", image)
} else { } else {
...@@ -130,7 +133,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -130,7 +133,7 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error {
json, _ := bodyJSON.MarshalJSON() json, _ := bodyJSON.MarshalJSON()
cmd := &models.SendWebhookSync{ cmd := &models.SendWebhookSync{
Url: this.WebhookURL, Url: dn.WebhookURL,
HttpMethod: "POST", HttpMethod: "POST",
ContentType: "application/json", ContentType: "application/json",
} }
...@@ -138,22 +141,22 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -138,22 +141,22 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error {
if !embeddedImage { if !embeddedImage {
cmd.Body = string(json) cmd.Body = string(json)
} else { } else {
err := this.embedImage(cmd, evalContext.ImageOnDiskPath, json) err := dn.embedImage(cmd, evalContext.ImageOnDiskPath, json)
if err != nil { if err != nil {
this.log.Error("failed to embed image", "error", err) dn.log.Error("failed to embed image", "error", err)
return err return err
} }
} }
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { 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 err
} }
return nil 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) f, err := os.Open(imagePath)
defer f.Close() defer f.Close()
if err != nil { if err != nil {
......
...@@ -22,7 +22,7 @@ func TestDiscordNotifier(t *testing.T) { ...@@ -22,7 +22,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewDiscordNotifier(model) _, err := newDiscordNotifier(model)
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
}) })
...@@ -40,7 +40,7 @@ func TestDiscordNotifier(t *testing.T) { ...@@ -40,7 +40,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewDiscordNotifier(model) not, err := newDiscordNotifier(model)
discordNotifier := not.(*DiscordNotifier) discordNotifier := not.(*DiscordNotifier)
So(err, ShouldBeNil) So(err, ShouldBeNil)
......
...@@ -67,7 +67,7 @@ func NewEmailNotifier(model *models.AlertNotification) (alerting.Notifier, error ...@@ -67,7 +67,7 @@ func NewEmailNotifier(model *models.AlertNotification) (alerting.Notifier, error
func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error { func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
en.log.Info("Sending alert notification to", "addresses", en.Addresses) en.log.Info("Sending alert notification to", "addresses", en.Addresses)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
en.log.Error("Failed get rule link", "error", err) en.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -100,8 +100,8 @@ func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -100,8 +100,8 @@ func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
}, },
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
cmd.Data["ImageLink"] = evalContext.ImagePublicUrl cmd.Data["ImageLink"] = evalContext.ImagePublicURL
} else { } else {
file, err := os.Stat(evalContext.ImageOnDiskPath) file, err := os.Stat(evalContext.ImageOnDiskPath)
if err == nil { if err == nil {
......
...@@ -120,7 +120,7 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -120,7 +120,7 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error {
"Content-Type": "application/json; charset=UTF-8", "Content-Type": "application/json; charset=UTF-8",
} }
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
gcn.log.Error("evalContext returned an invalid rule URL") gcn.log.Error("evalContext returned an invalid rule URL")
} }
...@@ -152,10 +152,10 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -152,10 +152,10 @@ func (gcn *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error {
widgets = append(widgets, fields) widgets = append(widgets, fields)
// if an image exists, add it as an image widget // if an image exists, add it as an image widget
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
widgets = append(widgets, imageWidget{ widgets = append(widgets, imageWidget{
Image: image{ Image: image{
ImageURL: evalContext.ImagePublicUrl, ImageURL: evalContext.ImagePublicURL,
}, },
}) })
} else { } else {
......
...@@ -81,9 +81,9 @@ type HipChatNotifier struct { ...@@ -81,9 +81,9 @@ type HipChatNotifier struct {
// Notify sends an alert notification to HipChat // Notify sends an alert notification to HipChat
func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error { 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 { if err != nil {
hc.log.Error("Failed get rule link", "error", err) hc.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -148,10 +148,10 @@ func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -148,10 +148,10 @@ func (hc *HipChatNotifier) Notify(evalContext *alerting.EvalContext) error {
"date": evalContext.EndTime.Unix(), "date": evalContext.EndTime.Unix(),
"attributes": attributes, "attributes": attributes,
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
card["thumbnail"] = map[string]interface{}{ card["thumbnail"] = map[string]interface{}{
"url": evalContext.ImagePublicUrl, "url": evalContext.ImagePublicURL,
"url@2x": evalContext.ImagePublicUrl, "url@2x": evalContext.ImagePublicURL,
"width": 1193, "width": 1193,
"height": 564, "height": 564,
} }
......
...@@ -78,20 +78,20 @@ func (kn *KafkaNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -78,20 +78,20 @@ func (kn *KafkaNotifier) Notify(evalContext *alerting.EvalContext) error {
bodyJSON.Set("description", evalContext.Rule.Name+" - "+evalContext.Rule.Message) bodyJSON.Set("description", evalContext.Rule.Name+" - "+evalContext.Rule.Message)
bodyJSON.Set("client", "Grafana") bodyJSON.Set("client", "Grafana")
bodyJSON.Set("details", customData) 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 { if err != nil {
kn.log.Error("Failed get rule link", "error", err) kn.log.Error("Failed get rule link", "error", err)
return err return err
} }
bodyJSON.Set("client_url", ruleURL) bodyJSON.Set("client_url", ruleURL)
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
contexts := make([]interface{}, 1) contexts := make([]interface{}, 1)
imageJSON := simplejson.New() imageJSON := simplejson.New()
imageJSON.Set("type", "image") imageJSON.Set("type", "image")
imageJSON.Set("src", evalContext.ImagePublicUrl) imageJSON.Set("src", evalContext.ImagePublicURL)
contexts[0] = imageJSON contexts[0] = imageJSON
bodyJSON.Set("contexts", contexts) bodyJSON.Set("contexts", contexts)
} }
......
...@@ -56,7 +56,7 @@ type LineNotifier struct { ...@@ -56,7 +56,7 @@ type LineNotifier struct {
// Notify send an alert notification to LINE // Notify send an alert notification to LINE
func (ln *LineNotifier) Notify(evalContext *alerting.EvalContext) error { 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 var err error
switch evalContext.Rule.State { switch evalContext.Rule.State {
...@@ -67,8 +67,8 @@ func (ln *LineNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -67,8 +67,8 @@ func (ln *LineNotifier) Notify(evalContext *alerting.EvalContext) error {
} }
func (ln *LineNotifier) createAlert(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) ln.log.Info("Creating Line notify", "ruleId", evalContext.Rule.ID, "notification", ln.Name)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
ln.log.Error("Failed get rule link", "error", err) ln.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -78,9 +78,9 @@ func (ln *LineNotifier) createAlert(evalContext *alerting.EvalContext) error { ...@@ -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) body := fmt.Sprintf("%s - %s\n%s", evalContext.Rule.Name, ruleURL, evalContext.Rule.Message)
form.Add("message", body) form.Add("message", body)
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
form.Add("imageThumbnail", evalContext.ImagePublicUrl) form.Add("imageThumbnail", evalContext.ImagePublicURL)
form.Add("imageFullsize", evalContext.ImagePublicUrl) form.Add("imageFullsize", evalContext.ImagePublicURL)
} }
cmd := &models.SendWebhookSync{ cmd := &models.SendWebhookSync{
......
...@@ -90,9 +90,9 @@ func (on *OpsGenieNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -90,9 +90,9 @@ func (on *OpsGenieNotifier) Notify(evalContext *alerting.EvalContext) error {
} }
func (on *OpsGenieNotifier) createAlert(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 { if err != nil {
on.log.Error("Failed get rule link", "error", err) on.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -106,13 +106,13 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error ...@@ -106,13 +106,13 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error
bodyJSON := simplejson.New() bodyJSON := simplejson.New()
bodyJSON.Set("message", evalContext.Rule.Name) bodyJSON.Set("message", evalContext.Rule.Name)
bodyJSON.Set("source", "Grafana") 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)) bodyJSON.Set("description", fmt.Sprintf("%s - %s\n%s\n%s", evalContext.Rule.Name, ruleURL, evalContext.Rule.Message, customData))
details := simplejson.New() details := simplejson.New()
details.Set("url", ruleURL) details.Set("url", ruleURL)
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
details.Set("image", evalContext.ImagePublicUrl) details.Set("image", evalContext.ImagePublicURL)
} }
bodyJSON.Set("details", details) bodyJSON.Set("details", details)
...@@ -136,14 +136,14 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error ...@@ -136,14 +136,14 @@ func (on *OpsGenieNotifier) createAlert(evalContext *alerting.EvalContext) error
} }
func (on *OpsGenieNotifier) closeAlert(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 := simplejson.New()
bodyJSON.Set("source", "Grafana") bodyJSON.Set("source", "Grafana")
body, _ := bodyJSON.MarshalJSON() body, _ := bodyJSON.MarshalJSON()
cmd := &models.SendWebhookSync{ 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), Body: string(body),
HttpMethod: "POST", HttpMethod: "POST",
HttpHeader: map[string]string{ HttpHeader: map[string]string{
......
...@@ -100,10 +100,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -100,10 +100,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error {
bodyJSON := simplejson.New() bodyJSON := simplejson.New()
bodyJSON.Set("routing_key", pn.Key) bodyJSON.Set("routing_key", pn.Key)
bodyJSON.Set("event_action", eventType) 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) bodyJSON.Set("payload", payloadJSON)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
pn.log.Error("Failed get rule link", "error", err) pn.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -116,10 +116,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -116,10 +116,10 @@ func (pn *PagerdutyNotifier) Notify(evalContext *alerting.EvalContext) error {
links[0] = linkJSON links[0] = linkJSON
bodyJSON.Set("links", links) bodyJSON.Set("links", links)
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
contexts := make([]interface{}, 1) contexts := make([]interface{}, 1)
imageJSON := simplejson.New() imageJSON := simplejson.New()
imageJSON.Set("src", evalContext.ImagePublicUrl) imageJSON.Set("src", evalContext.ImagePublicURL)
contexts[0] = imageJSON contexts[0] = imageJSON
bodyJSON.Set("images", contexts) bodyJSON.Set("images", contexts)
} }
......
...@@ -146,7 +146,7 @@ type PushoverNotifier struct { ...@@ -146,7 +146,7 @@ type PushoverNotifier struct {
// Notify sends a alert notification to Pushover // Notify sends a alert notification to Pushover
func (pn *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error { func (pn *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
pn.log.Error("Failed get rule link", "error", err) pn.log.Error("Failed get rule link", "error", err)
return err return err
......
...@@ -79,7 +79,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -79,7 +79,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error {
sn.log.Info("Sending sensu result") sn.log.Info("Sending sensu result")
bodyJSON := simplejson.New() bodyJSON := simplejson.New()
bodyJSON.Set("ruleId", evalContext.Rule.Id) bodyJSON.Set("ruleId", evalContext.Rule.ID)
// Sensu alerts cannot have spaces in them // Sensu alerts cannot have spaces in them
bodyJSON.Set("name", strings.Replace(evalContext.Rule.Name, " ", "_", -1)) bodyJSON.Set("name", strings.Replace(evalContext.Rule.Name, " ", "_", -1))
// Sensu alerts require a source. We set it to the user-specified value (optional), // 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 { ...@@ -87,7 +87,7 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error {
if sn.Source != "" { if sn.Source != "" {
bodyJSON.Set("source", sn.Source) bodyJSON.Set("source", sn.Source)
} else { } 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 // Finally, sensu expects an output
// We set it to a default output // We set it to a default output
...@@ -106,13 +106,13 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -106,13 +106,13 @@ func (sn *SensuNotifier) Notify(evalContext *alerting.EvalContext) error {
bodyJSON.Set("handler", sn.Handler) bodyJSON.Set("handler", sn.Handler)
} }
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err == nil { if err == nil {
bodyJSON.Set("ruleUrl", ruleURL) bodyJSON.Set("ruleUrl", ruleURL)
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
bodyJSON.Set("imageUrl", evalContext.ImagePublicUrl) bodyJSON.Set("imageUrl", evalContext.ImagePublicURL)
} }
if evalContext.Rule.Message != "" { if evalContext.Rule.Message != "" {
......
...@@ -145,9 +145,9 @@ type SlackNotifier struct { ...@@ -145,9 +145,9 @@ type SlackNotifier struct {
// Notify send alert notification to Slack. // Notify send alert notification to Slack.
func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error { 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 { if err != nil {
sn.log.Error("Failed get rule link", "error", err) sn.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -181,7 +181,7 @@ func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -181,7 +181,7 @@ func (sn *SlackNotifier) Notify(evalContext *alerting.EvalContext) error {
imageURL := "" imageURL := ""
// default to file.upload API method if a token is provided // default to file.upload API method if a token is provided
if sn.Token == "" { if sn.Token == "" {
imageURL = evalContext.ImagePublicUrl imageURL = evalContext.ImagePublicURL
} }
body := map[string]interface{}{ body := map[string]interface{}{
......
...@@ -50,9 +50,9 @@ type TeamsNotifier struct { ...@@ -50,9 +50,9 @@ type TeamsNotifier struct {
// Notify send an alert notification to Microsoft teams. // Notify send an alert notification to Microsoft teams.
func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { 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 { if err != nil {
tn.log.Error("Failed get rule link", "error", err) tn.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -83,9 +83,9 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -83,9 +83,9 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error {
} }
images := make([]map[string]interface{}, 0) images := make([]map[string]interface{}, 0)
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
images = append(images, map[string]interface{}{ images = append(images, map[string]interface{}{
"image": evalContext.ImagePublicUrl, "image": evalContext.ImagePublicURL,
}) })
} }
...@@ -122,7 +122,7 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -122,7 +122,7 @@ func (tn *TeamsNotifier) Notify(evalContext *alerting.EvalContext) error {
"name": "View Graph", "name": "View Graph",
"targets": []map[string]interface{}{ "targets": []map[string]interface{}{
{ {
"os": "default", "uri": evalContext.ImagePublicUrl, "os": "default", "uri": evalContext.ImagePublicURL,
}, },
}, },
}, },
......
...@@ -104,13 +104,13 @@ func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, send ...@@ -104,13 +104,13 @@ func (tn *TelegramNotifier) buildMessage(evalContext *alerting.EvalContext, send
func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalContext) *models.SendWebhookSync { func (tn *TelegramNotifier) buildMessageLinkedImage(evalContext *alerting.EvalContext) *models.SendWebhookSync {
message := fmt.Sprintf("<b>%s</b>\nState: %s\nMessage: %s\n", evalContext.GetNotificationTitle(), evalContext.Rule.Name, evalContext.Rule.Message) message := fmt.Sprintf("<b>%s</b>\nState: %s\nMessage: %s\n", evalContext.GetNotificationTitle(), evalContext.Rule.Name, evalContext.Rule.Message)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err == nil { if err == nil {
message = message + fmt.Sprintf("URL: %s\n", ruleURL) message = message + fmt.Sprintf("URL: %s\n", ruleURL)
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
message = message + fmt.Sprintf("Image: %s\n", evalContext.ImagePublicUrl) message = message + fmt.Sprintf("Image: %s\n", evalContext.ImagePublicURL)
} }
metrics := generateMetricsMessage(evalContext) metrics := generateMetricsMessage(evalContext)
...@@ -141,7 +141,7 @@ func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalCo ...@@ -141,7 +141,7 @@ func (tn *TelegramNotifier) buildMessageInlineImage(evalContext *alerting.EvalCo
return nil, err return nil, err
} }
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -232,7 +232,7 @@ func appendIfPossible(message string, extra string, sizeLimit int) string { ...@@ -232,7 +232,7 @@ func appendIfPossible(message string, extra string, sizeLimit int) string {
// Notify send an alert notification to Telegram. // Notify send an alert notification to Telegram.
func (tn *TelegramNotifier) Notify(evalContext *alerting.EvalContext) error { func (tn *TelegramNotifier) Notify(evalContext *alerting.EvalContext) error {
var cmd *models.SendWebhookSync var cmd *models.SendWebhookSync
if evalContext.ImagePublicUrl == "" && tn.UploadImage { if evalContext.ImagePublicURL == "" && tn.UploadImage {
cmd = tn.buildMessage(evalContext, true) cmd = tn.buildMessage(evalContext, true)
} else { } else {
cmd = tn.buildMessage(evalContext, false) cmd = tn.buildMessage(evalContext, false)
......
...@@ -143,12 +143,12 @@ func (notifier *ThreemaNotifier) Notify(evalContext *alerting.EvalContext) error ...@@ -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", message := fmt.Sprintf("%s%s\n\n*State:* %s\n*Message:* %s\n",
stateEmoji, evalContext.GetNotificationTitle(), stateEmoji, evalContext.GetNotificationTitle(),
evalContext.Rule.Name, evalContext.Rule.Message) evalContext.Rule.Name, evalContext.Rule.Message)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err == nil { if err == nil {
message = message + fmt.Sprintf("*URL:* %s\n", ruleURL) message = message + fmt.Sprintf("*URL:* %s\n", ruleURL)
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
message = message + fmt.Sprintf("*Image:* %s\n", evalContext.ImagePublicUrl) message = message + fmt.Sprintf("*Image:* %s\n", evalContext.ImagePublicURL)
} }
data.Set("text", message) data.Set("text", message)
......
...@@ -70,9 +70,9 @@ type VictoropsNotifier struct { ...@@ -70,9 +70,9 @@ type VictoropsNotifier struct {
// Notify sends notification to Victorops via POST to URL endpoint // Notify sends notification to Victorops via POST to URL endpoint
func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error { 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 { if err != nil {
vn.log.Error("Failed get rule link", "error", err) vn.log.Error("Failed get rule link", "error", err)
return err return err
...@@ -116,8 +116,8 @@ func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -116,8 +116,8 @@ func (vn *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error {
bodyJSON.Set("error_message", evalContext.Error.Error()) bodyJSON.Set("error_message", evalContext.Error.Error())
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
bodyJSON.Set("image_url", evalContext.ImagePublicUrl) bodyJSON.Set("image_url", evalContext.ImagePublicURL)
} }
data, _ := bodyJSON.MarshalJSON() data, _ := bodyJSON.MarshalJSON()
......
...@@ -76,18 +76,18 @@ func (wn *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error { ...@@ -76,18 +76,18 @@ func (wn *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error {
bodyJSON := simplejson.New() bodyJSON := simplejson.New()
bodyJSON.Set("title", evalContext.GetNotificationTitle()) 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("ruleName", evalContext.Rule.Name)
bodyJSON.Set("state", evalContext.Rule.State) bodyJSON.Set("state", evalContext.Rule.State)
bodyJSON.Set("evalMatches", evalContext.EvalMatches) bodyJSON.Set("evalMatches", evalContext.EvalMatches)
ruleURL, err := evalContext.GetRuleUrl() ruleURL, err := evalContext.GetRuleURL()
if err == nil { if err == nil {
bodyJSON.Set("ruleUrl", ruleURL) bodyJSON.Set("ruleUrl", ruleURL)
} }
if evalContext.ImagePublicUrl != "" { if evalContext.ImagePublicURL != "" {
bodyJSON.Set("imageUrl", evalContext.ImagePublicUrl) bodyJSON.Set("imageUrl", evalContext.ImagePublicURL)
} }
if evalContext.Rule.Message != "" { if evalContext.Rule.Message != "" {
......
...@@ -46,11 +46,11 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error { ...@@ -46,11 +46,11 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error {
metrics.M_Alerting_Result_State.WithLabelValues(string(evalContext.Rule.State)).Inc() metrics.M_Alerting_Result_State.WithLabelValues(string(evalContext.Rule.State)).Inc()
if evalContext.shouldUpdateAlertState() { 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{ cmd := &models.SetAlertStateCommand{
AlertId: evalContext.Rule.Id, AlertId: evalContext.Rule.ID,
OrgId: evalContext.Rule.OrgId, OrgId: evalContext.Rule.OrgID,
State: evalContext.Rule.State, State: evalContext.Rule.State,
Error: executionError, Error: executionError,
EvalData: annotationData, EvalData: annotationData,
...@@ -81,10 +81,10 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error { ...@@ -81,10 +81,10 @@ func (handler *defaultResultHandler) handle(evalContext *EvalContext) error {
// save annotation // save annotation
item := annotations.Item{ item := annotations.Item{
OrgId: evalContext.Rule.OrgId, OrgId: evalContext.Rule.OrgID,
DashboardId: evalContext.Rule.DashboardId, DashboardId: evalContext.Rule.DashboardID,
PanelId: evalContext.Rule.PanelId, PanelId: evalContext.Rule.PanelID,
AlertId: evalContext.Rule.Id, AlertId: evalContext.Rule.ID,
Text: "", Text: "",
NewState: string(evalContext.Rule.State), NewState: string(evalContext.Rule.State),
PrevState: string(evalContext.PrevAlertState), PrevState: string(evalContext.PrevAlertState),
......
...@@ -21,10 +21,10 @@ var ( ...@@ -21,10 +21,10 @@ var (
// Rule is the in-memory version of an alert rule. // Rule is the in-memory version of an alert rule.
type Rule struct { type Rule struct {
Id int64 ID int64
OrgId int64 OrgID int64
DashboardId int64 DashboardID int64
PanelId int64 PanelID int64
Frequency int64 Frequency int64
Name string Name string
Message string Message string
...@@ -44,23 +44,23 @@ type Rule struct { ...@@ -44,23 +44,23 @@ type Rule struct {
type ValidationError struct { type ValidationError struct {
Reason string Reason string
Err error Err error
Alertid int64 AlertID int64
DashboardId int64 DashboardID int64
PanelId int64 PanelID int64
} }
func (e ValidationError) Error() string { func (e ValidationError) Error() string {
extraInfo := e.Reason extraInfo := e.Reason
if e.Alertid != 0 { if e.AlertID != 0 {
extraInfo = fmt.Sprintf("%s AlertId: %v", extraInfo, e.Alertid) extraInfo = fmt.Sprintf("%s AlertId: %v", extraInfo, e.AlertID)
} }
if e.PanelId != 0 { if e.PanelID != 0 {
extraInfo = fmt.Sprintf("%s PanelId: %v", extraInfo, e.PanelId) extraInfo = fmt.Sprintf("%s PanelId: %v", extraInfo, e.PanelID)
} }
if e.DashboardId != 0 { if e.DashboardID != 0 {
extraInfo = fmt.Sprintf("%s DashboardId: %v", extraInfo, e.DashboardId) extraInfo = fmt.Sprintf("%s DashboardId: %v", extraInfo, e.DashboardID)
} }
if e.Err != nil { if e.Err != nil {
...@@ -113,10 +113,10 @@ func getTimeDurationStringToSeconds(str string) (int64, error) { ...@@ -113,10 +113,10 @@ func getTimeDurationStringToSeconds(str string) (int64, error) {
// alert to an in-memory version. // alert to an in-memory version.
func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) {
model := &Rule{} model := &Rule{}
model.Id = ruleDef.Id model.ID = ruleDef.Id
model.OrgId = ruleDef.OrgId model.OrgID = ruleDef.OrgId
model.DashboardId = ruleDef.DashboardId model.DashboardID = ruleDef.DashboardId
model.PanelId = ruleDef.PanelId model.PanelID = ruleDef.PanelId
model.Name = ruleDef.Name model.Name = ruleDef.Name
model.Message = ruleDef.Message model.Message = ruleDef.Message
model.State = ruleDef.State model.State = ruleDef.State
...@@ -140,7 +140,7 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { ...@@ -140,7 +140,7 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) {
} else { } else {
uid, err := jsonModel.Get("uid").String() uid, err := jsonModel.Get("uid").String()
if err != nil { 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) model.Notifications = append(model.Notifications, uid)
} }
...@@ -151,11 +151,11 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) { ...@@ -151,11 +151,11 @@ func NewRuleFromDBAlert(ruleDef *models.Alert) (*Rule, error) {
conditionType := conditionModel.Get("type").MustString() conditionType := conditionModel.Get("type").MustString()
factory, exist := conditionFactories[conditionType] factory, exist := conditionFactories[conditionType]
if !exist { 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) queryCondition, err := factory(conditionModel, index)
if err != nil { 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) model.Conditions = append(model.Conditions, queryCondition)
} }
......
...@@ -27,8 +27,8 @@ func (s *schedulerImpl) Update(rules []*Rule) { ...@@ -27,8 +27,8 @@ func (s *schedulerImpl) Update(rules []*Rule) {
for i, rule := range rules { for i, rule := range rules {
var job *Job var job *Job
if s.jobs[rule.Id] != nil { if s.jobs[rule.ID] != nil {
job = s.jobs[rule.Id] job = s.jobs[rule.ID]
} else { } else {
job = &Job{ job = &Job{
Running: false, Running: false,
...@@ -42,7 +42,7 @@ func (s *schedulerImpl) Update(rules []*Rule) { ...@@ -42,7 +42,7 @@ func (s *schedulerImpl) Update(rules []*Rule) {
if job.Offset == 0 { //zero offset causes division with 0 panics. if job.Offset == 0 { //zero offset causes division with 0 panics.
job.Offset = 1 job.Offset = 1
} }
jobs[rule.Id] = job jobs[rule.ID] = job
} }
s.jobs = jobs s.jobs = jobs
...@@ -73,6 +73,6 @@ func (s *schedulerImpl) Tick(tickTime time.Time, execQueue chan *Job) { ...@@ -73,6 +73,6 @@ func (s *schedulerImpl) Tick(tickTime time.Time, execQueue chan *Job) {
} }
func (s *schedulerImpl) enqueue(job *Job, 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 execQueue <- job
} }
...@@ -49,8 +49,8 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error { ...@@ -49,8 +49,8 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error {
func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext { func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {
testRule := &Rule{ testRule := &Rule{
DashboardId: 1, DashboardID: 1,
PanelId: 1, PanelID: 1,
Name: "Test notification", Name: "Test notification",
Message: "Someone is testing the alert notification within grafana.", Message: "Someone is testing the alert notification within grafana.",
State: models.AlertStateAlerting, State: models.AlertStateAlerting,
...@@ -58,7 +58,7 @@ func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext { ...@@ -58,7 +58,7 @@ func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {
ctx := NewEvalContext(context.Background(), testRule) ctx := NewEvalContext(context.Background(), testRule)
if cmd.Settings.Get("uploadImage").MustBool(true) { 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.IsTestRun = true
ctx.Firing = true ctx.Firing = true
......
...@@ -13,8 +13,8 @@ import ( ...@@ -13,8 +13,8 @@ import (
// of an alert rule. // of an alert rule.
type AlertTestCommand struct { type AlertTestCommand struct {
Dashboard *simplejson.Json Dashboard *simplejson.Json
PanelId int64 PanelID int64
OrgId int64 OrgID int64
User *models.SignedInUser User *models.SignedInUser
Result *EvalContext Result *EvalContext
...@@ -28,14 +28,14 @@ func handleAlertTestCommand(cmd *AlertTestCommand) error { ...@@ -28,14 +28,14 @@ func handleAlertTestCommand(cmd *AlertTestCommand) error {
dash := models.NewDashboardFromJson(cmd.Dashboard) dash := models.NewDashboardFromJson(cmd.Dashboard)
extractor := NewDashAlertExtractor(dash, cmd.OrgId, cmd.User) extractor := NewDashAlertExtractor(dash, cmd.OrgID, cmd.User)
alerts, err := extractor.GetAlerts() alerts, err := extractor.GetAlerts()
if err != nil { if err != nil {
return err return err
} }
for _, alert := range alerts { for _, alert := range alerts {
if alert.PanelId == cmd.PanelId { if alert.PanelId == cmd.PanelID {
rule, err := NewRuleFromDBAlert(alert) rule, err := NewRuleFromDBAlert(alert)
if err != nil { if err != nil {
return err return err
...@@ -46,7 +46,7 @@ func handleAlertTestCommand(cmd *AlertTestCommand) error { ...@@ -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 { func testAlertRule(rule *Rule) *EvalContext {
......
...@@ -36,4 +36,5 @@ exit_if_fail golangci-lint run --deadline 10m --disable-all \ ...@@ -36,4 +36,5 @@ exit_if_fail golangci-lint run --deadline 10m --disable-all \
exit_if_fail go vet ./pkg/... exit_if_fail go vet ./pkg/...
exit_if_fail make revive exit_if_fail make revive
exit_if_fail make revive-alerting
exit_if_fail make gosec exit_if_fail make gosec
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment