diff --git a/cmd/bosun/conf/rule/loaders.go b/cmd/bosun/conf/rule/loaders.go index 14edf9e3e6..41245765e6 100644 --- a/cmd/bosun/conf/rule/loaders.go +++ b/cmd/bosun/conf/rule/loaders.go @@ -276,24 +276,18 @@ func (c *Conf) loadAlert(s *parse.SectionNode) { c.errorf("Depends and crit/warn must share at least one tag.") } } - warnLength := len(a.WarnNotification.Notifications) + len(a.WarnNotification.Lookups) - critLength := len(a.CritNotification.Notifications) + len(a.CritNotification.Lookups) + allNots := c.getAllPossibleNotifications(&a) if a.Log { - for _, n := range a.CritNotification.Notifications { + for _, n := range allNots { if n.Next != nil { c.errorf("cannot use log with a chained notification") } } - for _, n := range a.WarnNotification.Notifications { - if n.Next != nil { - c.errorf("cannot use log with a chained notification") - } - } - if warnLength+critLength == 0 { + if len(allNots) == 0 { c.errorf("log specified but no notification") } } - if warnLength+critLength > 0 && a.Template == nil { + if len(allNots) > 0 && a.Template == nil { c.errorf("notifications specified but no template") } if a.Template != nil { @@ -334,17 +328,9 @@ func (c *Conf) loadAlert(s *parse.SectionNode) { checkTplKeys(ntk, key, false) } } - uniqNots := map[string]*conf.Notification{} - for n, not := range a.CritNotification.GetAllChained() { - uniqNots[n] = not - } - for n, not := range a.WarnNotification.GetAllChained() { - uniqNots[n] = not - } - for _, not := range uniqNots { + for _, not := range allNots { checkNotification(not) } - } a.ReturnType = ret c.Alerts[name] = &a diff --git a/cmd/bosun/conf/rule/rule.go b/cmd/bosun/conf/rule/rule.go index e7de9ba59a..5118454522 100644 --- a/cmd/bosun/conf/rule/rule.go +++ b/cmd/bosun/conf/rule/rule.go @@ -797,3 +797,32 @@ func (c *Conf) genHash() { func (c *Conf) GetHash() string { return c.Hash } + +// returns any notifications accessible from the alert vis warn/critNotification, including chains and lookups +func (c *Conf) getAllPossibleNotifications(a *conf.Alert) map[string]*conf.Notification { + nots := map[string]*conf.Notification{} + for k, v := range a.WarnNotification.GetAllChained() { + nots[k] = v + } + for k, v := range a.CritNotification.GetAllChained() { + nots[k] = v + } + followLookup := func(l map[string]*conf.Lookup) { + for target, lookup := range l { + for _, entry := range lookup.Entries { + if notNames, ok := entry.Values[target]; ok { + for _, k := range strings.Split(notNames, ",") { + if not, ok := c.Notifications[k]; ok { + nots[k] = not + } else { + c.errorf("Notification %s needed by lookup %s in %s is not defined.", k, lookup.Name, a.Name) + } + } + } + } + } + } + followLookup(a.CritNotification.Lookups) + followLookup(a.WarnNotification.Lookups) + return nots +} diff --git a/cmd/bosun/w.sh b/cmd/bosun/w.sh index e38443b430..365e68b588 100755 --- a/cmd/bosun/w.sh +++ b/cmd/bosun/w.sh @@ -1,5 +1,5 @@ #!/bin/sh while echo "(RE)STARTING BOSUN"; do - go run main.go -w -q || exit + go run main.go -w -q -dev || exit done diff --git a/cmd/bosun/web/static.go b/cmd/bosun/web/static.go index 704c5a8b56..1c8e7087e9 100644 --- a/cmd/bosun/web/static.go +++ b/cmd/bosun/web/static.go @@ -15733,38 +15733,40 @@ ynVAe1gblV/Il1Vj8q9kxl3Nf5rdW5qKUSdkaRqV3v8JAAD//7n7cuC9JgAA "/js/ace/mode-bosun.js": { local: "web/static/js/ace/mode-bosun.js", - size: 4772, + size: 5252, modtime: 0, compressed: ` -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 -CYpNiH8HAAD//zPHBa+kEgAA +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 `, }, diff --git a/cmd/bosun/web/static/js/ace/mode-bosun.js b/cmd/bosun/web/static/js/ace/mode-bosun.js index 1275132e5f..0fd3cc3eb8 100644 --- a/cmd/bosun/web/static/js/ace/mode-bosun.js +++ b/cmd/bosun/web/static/js/ace/mode-bosun.js @@ -11,8 +11,15 @@ var BosunHighlightRules = function() { var inAlertKeywords = "macro|template|crit|warn|depends|squelch|critNotification|" + "warnNotification|unknown|unjoinedOk|ignoreUnknown|log|maxLogFrequency" - var inNotificationKeywords = "email|post|get|print|contentType|next|timeout|body|useBody"; - + var inNotificationKeywords = "email|post|get|print|contentType|next|timeout|bodyTemplate|postTemplate|getTemplate|emailSubjectTemplate|runOnActions|groupActions|unknownMinGroupSize|unknownThreshold"; + for (var action of ["Get","Post","Body","EmailSubject"]){ + inNotificationKeywords += "|action"+action; + inNotificationKeywords += "|unknown"+action; + inNotificationKeywords += "|unknownMulti"+action; + for (var type of ["Ack", "Close", "Forget", "ForceClose", "Purge", "Note", "DelayedClose","CancelClose"]){ + inNotificationKeywords += "|action"+action+type; + } + } var inTemplateKeywords = "subject|body"; var inSectionKeywords = [inAlertKeywords, inNotificationKeywords, inTemplateKeywords].join("|");