mirror of
https://github.com/grafana/grafana.git
synced 2025-09-28 17:13:55 +08:00
feat(alerting): worked on improving slack alerts
This commit is contained in:
63
pkg/services/alerting/eval_context.go
Normal file
63
pkg/services/alerting/eval_context.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package alerting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EvalContext struct {
|
||||||
|
Firing bool
|
||||||
|
IsTestRun bool
|
||||||
|
Events []*Event
|
||||||
|
Logs []*ResultLogEntry
|
||||||
|
Error error
|
||||||
|
Description string
|
||||||
|
StartTime time.Time
|
||||||
|
EndTime time.Time
|
||||||
|
Rule *Rule
|
||||||
|
DoneChan chan bool
|
||||||
|
CancelChan chan bool
|
||||||
|
log log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *EvalContext) GetDurationMs() float64 {
|
||||||
|
return float64(a.EndTime.Nanosecond()-a.StartTime.Nanosecond()) / float64(1000000)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EvalContext) GetColor() string {
|
||||||
|
if !c.Firing {
|
||||||
|
return "#36a64f"
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Rule.Severity == m.AlertSeverityWarning {
|
||||||
|
return "#fd821b"
|
||||||
|
} else {
|
||||||
|
return "#D63232"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EvalContext) GetStateText() string {
|
||||||
|
if !c.Firing {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Rule.Severity == m.AlertSeverityWarning {
|
||||||
|
return "WARNING"
|
||||||
|
} else {
|
||||||
|
return "CRITICAL"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEvalContext(rule *Rule) *EvalContext {
|
||||||
|
return &EvalContext{
|
||||||
|
StartTime: time.Now(),
|
||||||
|
Rule: rule,
|
||||||
|
Logs: make([]*ResultLogEntry, 0),
|
||||||
|
Events: make([]*Event, 0),
|
||||||
|
DoneChan: make(chan bool, 1),
|
||||||
|
CancelChan: make(chan bool, 1),
|
||||||
|
log: log.New("alerting.engine"),
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ type DefaultEvalHandler struct {
|
|||||||
|
|
||||||
func NewEvalHandler() *DefaultEvalHandler {
|
func NewEvalHandler() *DefaultEvalHandler {
|
||||||
return &DefaultEvalHandler{
|
return &DefaultEvalHandler{
|
||||||
log: log.New("alerting.handler"),
|
log: log.New("alerting.evalHandler"),
|
||||||
alertJobTimeout: time.Second * 5,
|
alertJobTimeout: time.Second * 5,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
package alerting
|
package alerting
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
Offset int64
|
Offset int64
|
||||||
Delay bool
|
Delay bool
|
||||||
@ -13,37 +7,6 @@ type Job struct {
|
|||||||
Rule *Rule
|
Rule *Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
type EvalContext struct {
|
|
||||||
Firing bool
|
|
||||||
IsTestRun bool
|
|
||||||
Events []*Event
|
|
||||||
Logs []*ResultLogEntry
|
|
||||||
Error error
|
|
||||||
Description string
|
|
||||||
StartTime time.Time
|
|
||||||
EndTime time.Time
|
|
||||||
Rule *Rule
|
|
||||||
DoneChan chan bool
|
|
||||||
CancelChan chan bool
|
|
||||||
log log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *EvalContext) GetDurationMs() float64 {
|
|
||||||
return float64(a.EndTime.Nanosecond()-a.StartTime.Nanosecond()) / float64(1000000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEvalContext(rule *Rule) *EvalContext {
|
|
||||||
return &EvalContext{
|
|
||||||
StartTime: time.Now(),
|
|
||||||
Rule: rule,
|
|
||||||
Logs: make([]*ResultLogEntry, 0),
|
|
||||||
Events: make([]*Event, 0),
|
|
||||||
DoneChan: make(chan bool, 1),
|
|
||||||
CancelChan: make(chan bool, 1),
|
|
||||||
log: log.New("alerting.engine"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResultLogEntry struct {
|
type ResultLogEntry struct {
|
||||||
Message string
|
Message string
|
||||||
Data interface{}
|
Data interface{}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package notifiers
|
package notifiers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
@ -47,17 +47,36 @@ func (this *SlackNotifier) Notify(context *alerting.EvalContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
stateText := string(rule.Severity)
|
fields := make([]map[string]interface{}, 0)
|
||||||
if !context.Firing {
|
for _, evt := range context.Events {
|
||||||
stateText = "ok"
|
fields = append(fields, map[string]interface{}{
|
||||||
|
"title": evt.Metric,
|
||||||
|
"value": evt.Value,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
text := fmt.Sprintf("[%s]: <%s|%s>", stateText, ruleLink, rule.Name)
|
body := map[string]interface{}{
|
||||||
|
"attachments": []map[string]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"color": context.GetColor(),
|
||||||
|
//"pretext": "Optional text that appears above the attachment block",
|
||||||
|
// "author_name": "Bobby Tables",
|
||||||
|
// "author_link": "http://flickr.com/bobby/",
|
||||||
|
// "author_icon": "http://flickr.com/icons/bobby.jpg",
|
||||||
|
"title": "[" + context.GetStateText() + "] " + rule.Name,
|
||||||
|
"title_link": ruleLink,
|
||||||
|
// "text": "Optional text that appears within the attachment",
|
||||||
|
"fields": fields,
|
||||||
|
"image_url": "http://my-website.com/path/to/image.jpg",
|
||||||
|
"thumb_url": "http://example.com/path/to/thumb.png",
|
||||||
|
"footer": "Grafana v4.0.0",
|
||||||
|
"footer_icon": "http://grafana.org/assets/img/fav32.png",
|
||||||
|
"ts": time.Now().Unix(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
body := simplejson.New()
|
data, _ := json.Marshal(&body)
|
||||||
body.Set("text", text)
|
|
||||||
|
|
||||||
data, _ := body.MarshalJSON()
|
|
||||||
cmd := &m.SendWebhook{Url: this.Url, Body: string(data)}
|
cmd := &m.SendWebhook{Url: this.Url, Body: string(data)}
|
||||||
|
|
||||||
if err := bus.Dispatch(cmd); err != nil {
|
if err := bus.Dispatch(cmd); err != nil {
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
<h3 class="page-heading">Slack settings</h3>
|
<h3 class="page-heading">Slack settings</h3>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-6">Url</span>
|
<span class="gf-form-label width-6">Url</span>
|
||||||
<input type="text" class="gf-form-input max-width-26" ng-model="ctrl.model.settings.url" placeholder="Slack incoming webhook url"></input>
|
<input type="text" class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="Slack incoming webhook url"></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user