mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Parse App URL only once (#39855)
This commit is contained in:
parent
a696fc8b2b
commit
2b4e51f478
@ -2,6 +2,7 @@ package ngalert
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
@ -125,11 +126,17 @@ func (ng *AlertNG) init() error {
|
|||||||
DisabledOrgs: ng.Cfg.UnifiedAlerting.DisabledOrgs,
|
DisabledOrgs: ng.Cfg.UnifiedAlerting.DisabledOrgs,
|
||||||
MinRuleInterval: ng.getRuleMinInterval(),
|
MinRuleInterval: ng.getRuleMinInterval(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appUrl, err := url.Parse(ng.Cfg.AppURL)
|
||||||
|
if err != nil {
|
||||||
|
ng.Log.Error("Failed to parse application URL. Continue without it.", "error", err)
|
||||||
|
appUrl = nil
|
||||||
|
}
|
||||||
stateManager := state.NewManager(ng.Log, ng.Metrics.GetStateMetrics(), store, store)
|
stateManager := state.NewManager(ng.Log, ng.Metrics.GetStateMetrics(), store, store)
|
||||||
schedule := schedule.NewScheduler(schedCfg, ng.DataService, ng.Cfg.AppURL, stateManager)
|
scheduler := schedule.NewScheduler(schedCfg, ng.DataService, appUrl, stateManager)
|
||||||
|
|
||||||
ng.stateManager = stateManager
|
ng.stateManager = stateManager
|
||||||
ng.schedule = schedule
|
ng.schedule = scheduler
|
||||||
|
|
||||||
api := api.API{
|
api := api.API{
|
||||||
Cfg: ng.Cfg,
|
Cfg: ng.Cfg,
|
||||||
|
@ -11,22 +11,15 @@ import (
|
|||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/prometheus/alertmanager/api/v2/models"
|
"github.com/prometheus/alertmanager/api/v2/models"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FromAlertStateToPostableAlerts(logger log.Logger, firingStates []*state.State, stateManager *state.Manager, appURL string) apimodels.PostableAlerts {
|
func FromAlertStateToPostableAlerts(firingStates []*state.State, stateManager *state.Manager, appURL *url.URL) apimodels.PostableAlerts {
|
||||||
alerts := apimodels.PostableAlerts{PostableAlerts: make([]models.PostableAlert, 0, len(firingStates))}
|
alerts := apimodels.PostableAlerts{PostableAlerts: make([]models.PostableAlert, 0, len(firingStates))}
|
||||||
var sentAlerts []*state.State
|
var sentAlerts []*state.State
|
||||||
ts := time.Now()
|
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 {
|
for _, alertState := range firingStates {
|
||||||
if !alertState.NeedsSending(stateManager.ResendDelay) {
|
if !alertState.NeedsSending(stateManager.ResendDelay) {
|
||||||
continue
|
continue
|
||||||
@ -38,12 +31,15 @@ func FromAlertStateToPostableAlerts(logger log.Logger, firingStates []*state.Sta
|
|||||||
nA["__value_string__"] = alertState.Results[0].EvaluationString
|
nA["__value_string__"] = alertState.Results[0].EvaluationString
|
||||||
}
|
}
|
||||||
|
|
||||||
genURL := appURL
|
var urlStr string
|
||||||
if uid := nL[ngModels.RuleUIDLabel]; len(uid) > 0 && u != nil {
|
if uid := nL[ngModels.RuleUIDLabel]; len(uid) > 0 && appURL != nil {
|
||||||
oldPath := u.Path
|
u := *appURL
|
||||||
u.Path = path.Join(u.Path, fmt.Sprintf("/alerting/%s/edit", uid))
|
u.Path = path.Join(u.Path, fmt.Sprintf("/alerting/%s/edit", uid))
|
||||||
genURL = u.String()
|
urlStr = u.String()
|
||||||
u.Path = oldPath
|
} else if appURL != nil {
|
||||||
|
urlStr = appURL.String()
|
||||||
|
} else {
|
||||||
|
urlStr = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
alerts.PostableAlerts = append(alerts.PostableAlerts, models.PostableAlert{
|
alerts.PostableAlerts = append(alerts.PostableAlerts, models.PostableAlert{
|
||||||
@ -52,7 +48,7 @@ func FromAlertStateToPostableAlerts(logger log.Logger, firingStates []*state.Sta
|
|||||||
EndsAt: strfmt.DateTime(alertState.EndsAt),
|
EndsAt: strfmt.DateTime(alertState.EndsAt),
|
||||||
Alert: models.Alert{
|
Alert: models.Alert{
|
||||||
Labels: models.LabelSet(nL),
|
Labels: models.LabelSet(nL),
|
||||||
GeneratorURL: strfmt.URI(genURL),
|
GeneratorURL: strfmt.URI(urlStr),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
alertState.LastSentAt = ts
|
alertState.LastSentAt = ts
|
||||||
|
@ -74,7 +74,7 @@ type schedule struct {
|
|||||||
|
|
||||||
stateManager *state.Manager
|
stateManager *state.Manager
|
||||||
|
|
||||||
appURL string
|
appURL *url.URL
|
||||||
|
|
||||||
multiOrgNotifier *notifier.MultiOrgAlertmanager
|
multiOrgNotifier *notifier.MultiOrgAlertmanager
|
||||||
metrics *metrics.Scheduler
|
metrics *metrics.Scheduler
|
||||||
@ -109,8 +109,9 @@ type SchedulerCfg struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewScheduler returns a new schedule.
|
// NewScheduler returns a new schedule.
|
||||||
func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service, appURL string, stateManager *state.Manager) *schedule {
|
func NewScheduler(cfg SchedulerCfg, dataService *tsdb.Service, appURL *url.URL, stateManager *state.Manager) *schedule {
|
||||||
ticker := alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds()))
|
ticker := alerting.NewTicker(cfg.C.Now(), time.Second*0, cfg.C, int64(cfg.BaseInterval.Seconds()))
|
||||||
|
|
||||||
sch := schedule{
|
sch := schedule{
|
||||||
|
|
||||||
registry: alertRuleRegistry{alertRuleInfo: make(map[models.AlertRuleKey]alertRuleInfo)},
|
registry: alertRuleRegistry{alertRuleInfo: make(map[models.AlertRuleKey]alertRuleInfo)},
|
||||||
@ -475,7 +476,7 @@ func (sch *schedule) ruleRoutine(grafanaCtx context.Context, key models.AlertRul
|
|||||||
|
|
||||||
processedStates := sch.stateManager.ProcessEvalResults(alertRule, results)
|
processedStates := sch.stateManager.ProcessEvalResults(alertRule, results)
|
||||||
sch.saveAlertStates(processedStates)
|
sch.saveAlertStates(processedStates)
|
||||||
alerts := FromAlertStateToPostableAlerts(sch.log, processedStates, sch.stateManager, sch.appURL)
|
alerts := FromAlertStateToPostableAlerts(processedStates, sch.stateManager, sch.appURL)
|
||||||
|
|
||||||
sch.log.Debug("sending alerts to notifier", "count", len(alerts.PostableAlerts), "alerts", alerts.PostableAlerts, "org", alertRule.OrgID)
|
sch.log.Debug("sending alerts to notifier", "count", len(alerts.PostableAlerts), "alerts", alerts.PostableAlerts, "org", alertRule.OrgID)
|
||||||
n, err := sch.multiOrgNotifier.AlertmanagerFor(alertRule.OrgID)
|
n, err := sch.multiOrgNotifier.AlertmanagerFor(alertRule.OrgID)
|
||||||
|
@ -3,6 +3,7 @@ package schedule_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -155,7 +156,11 @@ func TestAlertingTicker(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
st := state.NewManager(schedCfg.Logger, testMetrics.GetStateMetrics(), dbstore, dbstore)
|
st := state.NewManager(schedCfg.Logger, testMetrics.GetStateMetrics(), dbstore, dbstore)
|
||||||
sched := schedule.NewScheduler(schedCfg, nil, "http://localhost", st)
|
appUrl := &url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: "localhost",
|
||||||
|
}
|
||||||
|
sched := schedule.NewScheduler(schedCfg, nil, appUrl, st)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -247,7 +248,11 @@ func setupScheduler(t *testing.T, rs store.RuleStore, is store.InstanceStore, ac
|
|||||||
AdminConfigPollInterval: 10 * time.Minute, // do not poll in unit tests.
|
AdminConfigPollInterval: 10 * time.Minute, // do not poll in unit tests.
|
||||||
}
|
}
|
||||||
st := state.NewManager(schedCfg.Logger, m.GetStateMetrics(), rs, is)
|
st := state.NewManager(schedCfg.Logger, m.GetStateMetrics(), rs, is)
|
||||||
return NewScheduler(schedCfg, nil, "http://localhost", st), mockedClock
|
appUrl := &url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: "localhost",
|
||||||
|
}
|
||||||
|
return NewScheduler(schedCfg, nil, appUrl, st), mockedClock
|
||||||
}
|
}
|
||||||
|
|
||||||
// createTestAlertRule creates a dummy alert definition to be used by the tests.
|
// createTestAlertRule creates a dummy alert definition to be used by the tests.
|
||||||
|
Loading…
Reference in New Issue
Block a user