mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Update VictorOps notifier w/ auto resolve and image URL (#8431)
* Fixed newline JSON buy in VictorOps integration * Fixed payload sent to VictorOps so that link displays correctly * Fixed formatted to resolve go error * Add auto resolve incidents and image URL to VictorOps notifier
This commit is contained in:
committed by
Torkel Ödegaard
parent
878121bb46
commit
f7215608e9
@@ -1,10 +1,10 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/metrics"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
// AlertStateCritical - Victorops uses "CRITICAL" string to indicate "Alerting" state
|
||||
const AlertStateCritical = "CRITICAL"
|
||||
|
||||
const AlertStateRecovery = "RECOVERY"
|
||||
|
||||
func init() {
|
||||
alerting.RegisterNotifier(&alerting.NotifierPlugin{
|
||||
Type: "victorops",
|
||||
@@ -27,6 +29,15 @@ func init() {
|
||||
<span class="gf-form-label width-6">Url</span>
|
||||
<input type="text" required class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="VictorOps url"></input>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<gf-form-switch
|
||||
class="gf-form"
|
||||
label="Auto resolve incidents"
|
||||
label-class="width-14"
|
||||
checked="ctrl.model.settings.autoResolve"
|
||||
tooltip="Resolve incidents in VictorOps once the alert goes back to ok.">
|
||||
</gf-form-switch>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
}
|
||||
@@ -34,6 +45,7 @@ func init() {
|
||||
// NewVictoropsNotifier creates an instance of VictoropsNotifier that
|
||||
// handles posting notifications to Victorops REST API
|
||||
func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
autoResolve := model.Settings.Get("autoResolve").MustBool(true)
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find victorops url property in settings"}
|
||||
@@ -42,6 +54,7 @@ func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, e
|
||||
return &VictoropsNotifier{
|
||||
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.Settings),
|
||||
URL: url,
|
||||
AutoResolve: autoResolve,
|
||||
log: log.New("alerting.notifier.victorops"),
|
||||
}, nil
|
||||
}
|
||||
@@ -51,8 +64,9 @@ func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, e
|
||||
// Victorops specifications (http://victorops.force.com/knowledgebase/articles/Integration/Alert-Ingestion-API-Documentation/)
|
||||
type VictoropsNotifier struct {
|
||||
NotifierBase
|
||||
URL string
|
||||
log log.Logger
|
||||
URL string
|
||||
AutoResolve bool
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
// Notify sends notification to Victorops via POST to URL endpoint
|
||||
@@ -66,6 +80,11 @@ func (this *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if evalContext.Rule.State == models.AlertStateOK && !this.AutoResolve {
|
||||
this.log.Info("Not alerting VictorOps", "state", evalContext.Rule.State, "auto resolve", this.AutoResolve)
|
||||
return nil
|
||||
}
|
||||
|
||||
fields := make([]map[string]interface{}, 0)
|
||||
fieldLimitCount := 4
|
||||
for index, evt := range evalContext.EvalMatches {
|
||||
@@ -92,20 +111,28 @@ func (this *VictoropsNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
messageType = AlertStateCritical
|
||||
}
|
||||
|
||||
body := map[string]interface{}{
|
||||
"message_type": messageType,
|
||||
"entity_id": evalContext.Rule.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
"state_start_time": evalContext.StartTime.Unix(),
|
||||
"state_message": evalContext.Rule.Message + "\n" + ruleUrl,
|
||||
"monitoring_tool": "Grafana v" + setting.BuildVersion,
|
||||
if evalContext.Rule.State == models.AlertStateOK {
|
||||
messageType = AlertStateRecovery
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(&body)
|
||||
bodyJSON := simplejson.New()
|
||||
bodyJSON.Set("message_type", messageType)
|
||||
bodyJSON.Set("entity_id", evalContext.Rule.Name)
|
||||
bodyJSON.Set("timestamp", time.Now().Unix())
|
||||
bodyJSON.Set("state_start_time", evalContext.StartTime.Unix())
|
||||
bodyJSON.Set("state_message", evalContext.Rule.Message)
|
||||
bodyJSON.Set("monitoring_tool", "Grafana v"+setting.BuildVersion)
|
||||
bodyJSON.Set("alert_url", ruleUrl)
|
||||
|
||||
if evalContext.ImagePublicUrl != "" {
|
||||
bodyJSON.Set("image_url", evalContext.ImagePublicUrl)
|
||||
}
|
||||
|
||||
data, _ := bodyJSON.MarshalJSON()
|
||||
cmd := &models.SendWebhookSync{Url: this.URL, Body: string(data)}
|
||||
|
||||
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
|
||||
this.log.Error("Failed to send victorops notification", "error", err, "webhook", this.Name)
|
||||
this.log.Error("Failed to send Victorops notification", "error", err, "webhook", this.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user