From ae0b036ae467c5e52420260500f11e1150e6bd45 Mon Sep 17 00:00:00 2001 From: Istil <66511737+Keyun-Istil@users.noreply.github.com> Date: Fri, 27 Aug 2021 18:21:36 +0800 Subject: [PATCH] feat: support to mute by resource classpath_prefix (#785) --- alert/mute.go | 20 +++++++++++++++----- cache/alert_mute.go | 5 +++-- http/router_mute.go | 28 +++++++++++++++------------- models/mute.go | 24 ++++++++++++------------ sql/n9e.sql | 1 + timer/alert_mute.go | 5 +++-- 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/alert/mute.go b/alert/mute.go index 912640fa..bcc929c3 100644 --- a/alert/mute.go +++ b/alert/mute.go @@ -1,6 +1,8 @@ package alert import ( + "strings" + "github.com/didi/nightingale/v5/cache" "github.com/didi/nightingale/v5/models" "github.com/toolkits/pkg/logger" @@ -14,13 +16,13 @@ func isEventMute(event *models.AlertEvent) bool { } // 先去匹配一下metric为空的mute - if matchMute("", event.ResIdent, event.TagMap) { + if matchMute("", event.ResIdent, event.TagMap, event.ResClasspaths) { return true } // 如果是与条件,就会有多个metric,任一个匹配了屏蔽规则都算被屏蔽 for i := 0; i < len(historyPoints); i++ { - if matchMute(historyPoints[i].Metric, event.ResIdent, event.TagMap) { + if matchMute(historyPoints[i].Metric, event.ResIdent, event.TagMap, event.ResClasspaths) { return true } } @@ -35,7 +37,7 @@ func isEventMute(event *models.AlertEvent) bool { return false } -func matchMute(metric, ident string, tags map[string]string) bool { +func matchMute(metric, ident string, tags map[string]string, classpaths string) bool { filters, exists := cache.AlertMute.GetByKey(metric) if !exists { // 没有屏蔽规则跟这个事件相关 @@ -44,7 +46,7 @@ func matchMute(metric, ident string, tags map[string]string) bool { // 只要有一个屏蔽规则命中,那这个事件就是被屏蔽了 for _, filter := range filters { - if matchMuteOnce(filter, ident, tags) { + if matchMuteOnce(filter, ident, tags, classpaths) { return true } } @@ -52,7 +54,15 @@ func matchMute(metric, ident string, tags map[string]string) bool { return false } -func matchMuteOnce(filter cache.Filter, ident string, tags map[string]string) bool { +func matchMuteOnce(filter cache.Filter, ident string, tags map[string]string, classpaths string) bool { + if len(filter.ClasspathPrefix) != 0 && !strings.HasPrefix(classpaths, filter.ClasspathPrefix) && !strings.Contains(classpaths, " "+filter.ClasspathPrefix) { + //没配置分组屏蔽就不做后续比较 + //比如事件的资源calsspath为“n9e.mon n9e.rdb ccp.web”,配置屏蔽为n9e.rdb + //只要字符串前缀为n9e.rdb或者字符串包含“ n9e.rdb”即可判断所有alsspath中是否有前缀为n9e.rdb的 + //只要有任一点不满足,那这个屏蔽规则也没有继续验证下去的必要 + return false + } + if filter.ResReg != nil && !filter.ResReg.MatchString(ident) { // 比如屏蔽规则配置的是:c3-ceph.* // 当前事件的资源标识是:c4-ceph01.bj diff --git a/cache/alert_mute.go b/cache/alert_mute.go index 3f5d891e..cfbfe0ad 100644 --- a/cache/alert_mute.go +++ b/cache/alert_mute.go @@ -10,8 +10,9 @@ type AlertMuteMap struct { Data map[string][]Filter } type Filter struct { - ResReg *regexp.Regexp - TagsMap map[string]string + ClasspathPrefix string + ResReg *regexp.Regexp + TagsMap map[string]string } var AlertMute = &AlertMuteMap{Data: make(map[string][]Filter)} diff --git a/http/router_mute.go b/http/router_mute.go index d1ed13e0..63934c58 100644 --- a/http/router_mute.go +++ b/http/router_mute.go @@ -23,12 +23,13 @@ func muteGets(c *gin.Context) { } type muteForm struct { - Metric string `json:"metric"` - ResFilters string `json:"res_filters"` - TagFilters string `json:"tags_filters"` - Cause string `json:"cause"` - Btime int64 `json:"btime"` - Etime int64 `json:"etime"` + ClasspathPrefix string `json:"classpath_prefix "` + Metric string `json:"metric"` + ResFilters string `json:"res_filters"` + TagFilters string `json:"tags_filters"` + Cause string `json:"cause"` + Btime int64 `json:"btime"` + Etime int64 `json:"etime"` } func muteAdd(c *gin.Context) { @@ -38,13 +39,14 @@ func muteAdd(c *gin.Context) { me := loginUser(c).MustPerm("mute_create") mt := models.Mute{ - Metric: f.Metric, - ResFilters: f.ResFilters, - TagFilters: f.TagFilters, - Cause: f.Cause, - Btime: f.Btime, - Etime: f.Etime, - CreateBy: me.Username, + ClasspathPrefix: f.ClasspathPrefix, + Metric: f.Metric, + ResFilters: f.ResFilters, + TagFilters: f.TagFilters, + Cause: f.Cause, + Btime: f.Btime, + Etime: f.Etime, + CreateBy: me.Username, } renderMessage(c, mt.Add()) diff --git a/models/mute.go b/models/mute.go index 4b847361..483cb8ef 100644 --- a/models/mute.go +++ b/models/mute.go @@ -10,18 +10,18 @@ import ( ) type Mute struct { - Id int64 `json:"id"` - Metric string `json:"metric"` - ResFilters string `json:"res_filters"` - TagFilters string `json:"tags_filters"` - Cause string `json:"cause"` - Btime int64 `json:"btime"` - Etime int64 `json:"etime"` - CreateBy string `json:"create_by"` - CreateAt int64 `json:"create_at"` - - ResRegexp *regexp.Regexp `xorm:"-" json:"-"` - TagsMap map[string]string `xorm:"-" json:"-"` + Id int64 `json:"id"` + ClasspathPrefix string `json:"classpath_prefix"` + Metric string `json:"metric"` + ResFilters string `json:"res_filters"` + TagFilters string `json:"tags_filters"` + Cause string `json:"cause"` + Btime int64 `json:"btime"` + Etime int64 `json:"etime"` + CreateBy string `json:"create_by"` + CreateAt int64 `json:"create_at"` + ResRegexp *regexp.Regexp `xorm:"-" json:"-"` + TagsMap map[string]string `xorm:"-" json:"-"` } func (m *Mute) TableName() string { diff --git a/sql/n9e.sql b/sql/n9e.sql index 67a09d4b..0d47d92b 100644 --- a/sql/n9e.sql +++ b/sql/n9e.sql @@ -160,6 +160,7 @@ CREATE TABLE `classpath_favorite` ( CREATE TABLE `mute` ( `id` bigint unsigned not null auto_increment, + `classpath_prefix` varchar(255) not null default '' comment 'classpath prefix', `metric` varchar(255) not null comment 'required', `res_filters` varchar(4096) not null default 'resource filters', `tag_filters` varchar(8192) not null default '', diff --git a/timer/alert_mute.go b/timer/alert_mute.go index 48277ce6..9098e956 100644 --- a/timer/alert_mute.go +++ b/timer/alert_mute.go @@ -58,8 +58,9 @@ func syncAlertMutes() error { } filter := cache.Filter{ - ResReg: mutes[i].ResRegexp, - TagsMap: mutes[i].TagsMap, + ResReg: mutes[i].ResRegexp, + TagsMap: mutes[i].TagsMap, + ClasspathPrefix: mutes[i].ClasspathPrefix, } muteMap[mutes[i].Metric] = append(muteMap[mutes[i].Metric], filter)