Alerting: Fill the empty GeneratorURL (#35740)

Signed-off-by: Ganesh Vernekar <ganeshvern@gmail.com>
This commit is contained in:
Ganesh Vernekar 2021-06-16 15:34:12 +05:30 committed by GitHub
parent 16850630bf
commit dcd4bf1615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 27 deletions

View File

@ -44,7 +44,7 @@ const (
)
const (
UIDLabel = "__alert_rule_uid__"
RuleUIDLabel = "__alert_rule_uid__"
NamespaceUIDLabel = "__alert_rule_namespace_uid__"
)

View File

@ -89,7 +89,7 @@ func (ng *AlertNG) Init() error {
Notifier: ng.Alertmanager,
Metrics: ng.Metrics,
}
ng.schedule = schedule.NewScheduler(schedCfg, ng.DataService)
ng.schedule = schedule.NewScheduler(schedCfg, ng.DataService, ng.Cfg.AppURL)
api := api.API{
Cfg: ng.Cfg,

View File

@ -1,31 +1,53 @@
package schedule
import (
"fmt"
"net/url"
"path"
"time"
"github.com/go-openapi/strfmt"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/prometheus/alertmanager/api/v2/models"
"github.com/grafana/grafana/pkg/infra/log"
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/state"
)
func FromAlertStateToPostableAlerts(firingStates []*state.State, stateManager *state.Manager) apimodels.PostableAlerts {
func FromAlertStateToPostableAlerts(logger log.Logger, firingStates []*state.State, stateManager *state.Manager, appURL string) apimodels.PostableAlerts {
alerts := apimodels.PostableAlerts{PostableAlerts: make([]models.PostableAlert, 0, len(firingStates))}
var sentAlerts []*state.State
ts := time.Now()
u, err := url.Parse(appURL)
if err != nil {
logger.Debug("failed to parse URL while joining URL", "url", appURL, "err", err.Error())
u = nil
}
for _, alertState := range firingStates {
if alertState.NeedsSending(stateManager.ResendDelay) {
nL := alertState.Labels.Copy()
if len(alertState.Results) > 0 {
nL["__value__"] = alertState.Results[0].EvaluationString
}
genURL := appURL
if uid := nL[ngModels.RuleUIDLabel]; len(uid) > 0 && u != nil {
oldPath := u.Path
u.Path = path.Join(u.Path, fmt.Sprintf("/alerting/%s/edit", uid))
genURL = u.String()
u.Path = oldPath
}
alerts.PostableAlerts = append(alerts.PostableAlerts, models.PostableAlert{
Annotations: alertState.Annotations,
StartsAt: strfmt.DateTime(alertState.StartsAt),
EndsAt: strfmt.DateTime(alertState.EndsAt),
Alert: models.Alert{
Labels: models.LabelSet(nL),
Labels: models.LabelSet(nL),
GeneratorURL: strfmt.URI(genURL),
},
})
alertState.LastSentAt = ts

View File

@ -88,7 +88,7 @@ func (sch *schedule) ruleRoutine(grafanaCtx context.Context, key models.AlertRul
processedStates := stateManager.ProcessEvalResults(alertRule, results)
sch.saveAlertStates(processedStates)
alerts := FromAlertStateToPostableAlerts(processedStates, stateManager)
alerts := FromAlertStateToPostableAlerts(sch.log, processedStates, stateManager, sch.appURL)
sch.log.Debug("sending alerts to notifier", "count", len(alerts.PostableAlerts), "alerts", alerts.PostableAlerts)
err = sch.sendAlerts(alerts)
if err != nil {
@ -160,6 +160,8 @@ type schedule struct {
dataService *tsdb.Service
appURL string
notifier Notifier
metrics *metrics.Metrics
}
@ -180,7 +182,7 @@ type SchedulerCfg struct {
}
// NewScheduler returns a new schedule.
func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service) *schedule {
func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service, appURL string) *schedule {
ticker := alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds()))
sch := schedule{
registry: alertRuleRegistry{alertRuleInfo: make(map[models.AlertRuleKey]alertRuleInfo)},
@ -197,6 +199,7 @@ func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service) *schedule {
dataService: dataService,
notifier: cfg.Notifier,
metrics: cfg.Metrics,
appURL: appURL,
}
return &sch
}

View File

@ -107,7 +107,7 @@ func TestWarmStateCache(t *testing.T) {
InstanceStore: dbstore,
Metrics: metrics.NewMetrics(prometheus.NewRegistry()),
}
sched := schedule.NewScheduler(schedCfg, nil)
sched := schedule.NewScheduler(schedCfg, nil, "http://localhost")
st := state.NewManager(schedCfg.Logger, nilMetrics)
sched.WarmStateCache(st)
@ -153,7 +153,7 @@ func TestAlertingTicker(t *testing.T) {
Logger: log.New("ngalert schedule test"),
Metrics: metrics.NewMetrics(prometheus.NewRegistry()),
}
sched := schedule.NewScheduler(schedCfg, nil)
sched := schedule.NewScheduler(schedCfg, nil, "http://localhost")
ctx := context.Background()

View File

@ -84,7 +84,7 @@ func (c *cache) getOrCreate(alertRule *ngModels.AlertRule, result eval.Result) *
}
func attachRuleLabels(m map[string]string, alertRule *ngModels.AlertRule) {
m[ngModels.UIDLabel] = alertRule.UID
m[ngModels.RuleUIDLabel] = alertRule.UID
m[ngModels.NamespaceUIDLabel] = alertRule.NamespaceUID
m[prometheusModel.AlertNameLabel] = alertRule.Title
}

View File

@ -1353,7 +1353,7 @@ var expNotifications = map[string][]string{
{
"title": "[FIRING:1] SlackAlert2 ",
"title_link": "http://localhost:3000/alerting/list",
"text": "**Firing**\n\nLabels:\n - alertname = SlackAlert2\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DSlackAlert2\n",
"text": "**Firing**\n\nLabels:\n - alertname = SlackAlert2\nAnnotations:\nSource: http://localhost:3000/alerting/UID_SlackAlert2/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DSlackAlert2\n",
"fallback": "[FIRING:1] SlackAlert2 ",
"footer": "Grafana v",
"footer_icon": "https://grafana.com/assets/img/fav32.png",
@ -1386,7 +1386,7 @@ var expNotifications = map[string][]string{
"component": "Integration Test",
"group": "testgroup",
"custom_details": {
"firing": "\nLabels:\n - alertname = PagerdutyAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DPagerdutyAlert\n",
"firing": "\nLabels:\n - alertname = PagerdutyAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_PagerdutyAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DPagerdutyAlert\n",
"num_firing": "1",
"num_resolved": "0",
"resolved": ""
@ -1406,7 +1406,7 @@ var expNotifications = map[string][]string{
`{
"link": {
"messageUrl": "dingtalk://dingtalkclient/page/link?pc_slide=false&url=http%3A%2F%2Flocalhost%3A3000%2Falerting%2Flist",
"text": "**Firing**\n\nLabels:\n - alertname = DingDingAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DDingDingAlert\n",
"text": "**Firing**\n\nLabels:\n - alertname = DingDingAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_DingDingAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DDingDingAlert\n",
"title": "[FIRING:1] DingDingAlert "
},
"msgtype": "link"
@ -1431,7 +1431,7 @@ var expNotifications = map[string][]string{
],
"sections": [
{
"text": "**Firing**\n\nLabels:\n - alertname = TeamsAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DTeamsAlert\n",
"text": "**Firing**\n\nLabels:\n - alertname = TeamsAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_TeamsAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DTeamsAlert\n",
"title": "Details"
}
],
@ -1453,7 +1453,7 @@ var expNotifications = map[string][]string{
"annotations": {},
"startsAt": "%s",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "",
"generatorURL": "http://localhost:3000/alerting/UID_WebhookAlert/edit",
"fingerprint": "7611eef9e67f6e50",
"silenceURL": "http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DWebhookAlert",
"dashboardURL": "",
@ -1473,12 +1473,12 @@ var expNotifications = map[string][]string{
"truncatedAlerts": 0,
"title": "[FIRING:1] WebhookAlert ",
"state": "alerting",
"message": "**Firing**\n\nLabels:\n - alertname = WebhookAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DWebhookAlert\n"
"message": "**Firing**\n\nLabels:\n - alertname = WebhookAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_WebhookAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DWebhookAlert\n"
}`,
},
"discord_recv/discord_test": {
`{
"content": "**Firing**\n\nLabels:\n - alertname = DiscordAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DDiscordAlert\n",
"content": "**Firing**\n\nLabels:\n - alertname = DiscordAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_DiscordAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DDiscordAlert\n",
"embeds": [
{
"color": 14037554,
@ -1506,7 +1506,7 @@ var expNotifications = map[string][]string{
},
"name": "default"
},
"output": "**Firing**\n\nLabels:\n - alertname = SensuGoAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DSensuGoAlert\n",
"output": "**Firing**\n\nLabels:\n - alertname = SensuGoAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_SensuGoAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DSensuGoAlert\n",
"status": 2
},
"entity": {
@ -1519,10 +1519,10 @@ var expNotifications = map[string][]string{
}`,
},
"pushover_recv/pushover_test": {
"--abcd\r\nContent-Disposition: form-data; name=\"user\"\r\n\r\nmysecretkey\r\n--abcd\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\nmysecrettoken\r\n--abcd\r\nContent-Disposition: form-data; name=\"priority\"\r\n\r\n0\r\n--abcd\r\nContent-Disposition: form-data; name=\"sound\"\r\n\r\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n[FIRING:1] PushoverAlert \r\n--abcd\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nhttp://localhost:3000/alerting/list\r\n--abcd\r\nContent-Disposition: form-data; name=\"url_title\"\r\n\r\nShow alert rule\r\n--abcd\r\nContent-Disposition: form-data; name=\"message\"\r\n\r\n**Firing**\n\nLabels:\n - alertname = PushoverAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DPushoverAlert\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"html\"\r\n\r\n1\r\n--abcd--\r\n",
"--abcd\r\nContent-Disposition: form-data; name=\"user\"\r\n\r\nmysecretkey\r\n--abcd\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\nmysecrettoken\r\n--abcd\r\nContent-Disposition: form-data; name=\"priority\"\r\n\r\n0\r\n--abcd\r\nContent-Disposition: form-data; name=\"sound\"\r\n\r\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n[FIRING:1] PushoverAlert \r\n--abcd\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nhttp://localhost:3000/alerting/list\r\n--abcd\r\nContent-Disposition: form-data; name=\"url_title\"\r\n\r\nShow alert rule\r\n--abcd\r\nContent-Disposition: form-data; name=\"message\"\r\n\r\n**Firing**\n\nLabels:\n - alertname = PushoverAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_PushoverAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DPushoverAlert\n\r\n--abcd\r\nContent-Disposition: form-data; name=\"html\"\r\n\r\n1\r\n--abcd--\r\n",
},
"telegram_recv/bot6sh027hs034h": {
"--abcd\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\ntelegram_chat_id\r\n--abcd\r\nContent-Disposition: form-data; name=\"parse_mode\"\r\n\r\nhtml\r\n--abcd\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n**Firing**\n\nLabels:\n - alertname = TelegramAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DTelegramAlert\n\r\n--abcd--\r\n",
"--abcd\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\ntelegram_chat_id\r\n--abcd\r\nContent-Disposition: form-data; name=\"parse_mode\"\r\n\r\nhtml\r\n--abcd\r\nContent-Disposition: form-data; name=\"text\"\r\n\r\n**Firing**\n\nLabels:\n - alertname = TelegramAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_TelegramAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DTelegramAlert\n\r\n--abcd--\r\n",
},
"googlechat_recv/googlechat_test": {
`{
@ -1538,7 +1538,7 @@ var expNotifications = map[string][]string{
"widgets": [
{
"textParagraph": {
"text": "**Firing**\n\nLabels:\n - alertname = GoogleChatAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DGoogleChatAlert\n"
"text": "**Firing**\n\nLabels:\n - alertname = GoogleChatAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_GoogleChatAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DGoogleChatAlert\n"
}
},
{
@ -1576,7 +1576,7 @@ var expNotifications = map[string][]string{
"client": "Grafana",
"client_url": "http://localhost:3000/alerting/list",
"description": "[FIRING:1] KafkaAlert ",
"details": "**Firing**\n\nLabels:\n - alertname = KafkaAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DKafkaAlert\n",
"details": "**Firing**\n\nLabels:\n - alertname = KafkaAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_KafkaAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DKafkaAlert\n",
"incident_key": "35c0bdb1715f9162a20d7b2a01cb2e3a4c5b1dc663571701e3f67212b696332f"
}
}
@ -1584,10 +1584,10 @@ var expNotifications = map[string][]string{
}`,
},
"line_recv/line_test": {
`message=%5BFIRING%3A1%5D+LineAlert+%0Ahttp%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+LineAlert%0AAnnotations%3A%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253DLineAlert%0A`,
`message=%5BFIRING%3A1%5D+LineAlert+%0Ahttp%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+LineAlert%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2FUID_LineAlert%2Fedit%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253DLineAlert%0A`,
},
"threema_recv/threema_test": {
`from=%2A1234567&secret=myapisecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A1%5D+ThreemaAlert+%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+ThreemaAlert%0AAnnotations%3A%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253DThreemaAlert%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A&to=abcdefgh`,
`from=%2A1234567&secret=myapisecret&text=%E2%9A%A0%EF%B8%8F+%5BFIRING%3A1%5D+ThreemaAlert+%0A%0A%2AMessage%3A%2A%0A%2A%2AFiring%2A%2A%0A%0ALabels%3A%0A+-+alertname+%3D+ThreemaAlert%0AAnnotations%3A%0ASource%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2FUID_ThreemaAlert%2Fedit%0ASilence%3A+http%3A%2F%2Flocalhost%3A3000%2Falerting%2Fsilence%2Fnew%3Falertmanager%3Dgrafana%26matchers%3Dalertname%253DThreemaAlert%0A%0A%2AURL%3A%2A+http%3A%2Flocalhost%3A3000%2Falerting%2Flist%0A&to=abcdefgh`,
},
"victorops_recv/victorops_test": {
`{
@ -1596,14 +1596,14 @@ var expNotifications = map[string][]string{
"entity_id": "633ae988fa7074bcb51f3d1c5fef2ba1c5c4ccb45b3ecbf681f7d507b078b1ae",
"message_type": "CRITICAL",
"monitoring_tool": "Grafana v",
"state_message": "**Firing**\n\nLabels:\n - alertname = VictorOpsAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DVictorOpsAlert\n",
"state_message": "**Firing**\n\nLabels:\n - alertname = VictorOpsAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_VictorOpsAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%%3DVictorOpsAlert\n",
"timestamp": %s
}`,
},
"opsgenie_recv/opsgenie_test": {
`{
"alias": "47e92f0f6ef9fe99f3954e0d6155f8d09c4b9a038d8c3105e82c0cee4c62956e",
"description": "[FIRING:1] OpsGenieAlert \nhttp://localhost:3000/alerting/list\n\n**Firing**\n\nLabels:\n - alertname = OpsGenieAlert\nAnnotations:\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DOpsGenieAlert\n",
"description": "[FIRING:1] OpsGenieAlert \nhttp://localhost:3000/alerting/list\n\n**Firing**\n\nLabels:\n - alertname = OpsGenieAlert\nAnnotations:\nSource: http://localhost:3000/alerting/UID_OpsGenieAlert/edit\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DOpsGenieAlert\n",
"details": {
"url": "http://localhost:3000/alerting/list"
},
@ -1618,13 +1618,13 @@ var expNotifications = map[string][]string{
{
"labels": {
"__alert_rule_uid__": "UID_AlertmanagerAlert",
"__value__": "[ var='A' labels={} value=1 ]",
"__value__": "[ var='A' labels={} value=1 ]",
"alertname": "AlertmanagerAlert"
},
"annotations": {},
"startsAt": "%s",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "",
"generatorURL": "http://localhost:3000/alerting/UID_AlertmanagerAlert/edit",
"UpdatedAt": "%s",
"Timeout": false
}