未验证 提交 af6003da 编写于 作者: S shardingHe 提交者: GitHub

feat: Add BusiGroupFilter for alert_subscribe (#1660)

* add BusiGroupFilter for alert_subscribe ,copy from TagFiler

* refactor BusiGroupFilter

* refactor BusiGroupFilter

---------
Co-authored-by: NshardingHe <wangzihe@flashcat.cloud>
上级 76ac2cd0
...@@ -22,6 +22,14 @@ func MatchTags(eventTagsMap map[string]string, itags []models.TagFilter) bool { ...@@ -22,6 +22,14 @@ func MatchTags(eventTagsMap map[string]string, itags []models.TagFilter) bool {
} }
return true return true
} }
func MatchGroupsName(groupName string, groupFilter []models.TagFilter) bool {
for _, filter := range groupFilter {
if !matchTag(groupName, filter) {
return false
}
}
return true
}
func matchTag(value string, filter models.TagFilter) bool { func matchTag(value string, filter models.TagFilter) bool {
switch filter.Func { switch filter.Func {
......
...@@ -95,8 +95,8 @@ func (e *Dispatch) relaodTpls() error { ...@@ -95,8 +95,8 @@ func (e *Dispatch) relaodTpls() error {
} }
e.RwLock.RLock() e.RwLock.RLock()
for channel, sender := range e.ExtraSenders { for channelName, extraSender := range e.ExtraSenders {
senders[channel] = sender senders[channelName] = extraSender
} }
e.RwLock.RUnlock() e.RwLock.RUnlock()
...@@ -185,6 +185,10 @@ func (e *Dispatch) handleSub(sub *models.AlertSubscribe, event models.AlertCurEv ...@@ -185,6 +185,10 @@ func (e *Dispatch) handleSub(sub *models.AlertSubscribe, event models.AlertCurEv
if !common.MatchTags(event.TagsMap, sub.ITags) { if !common.MatchTags(event.TagsMap, sub.ITags) {
return return
} }
// event BusiGroups filter
if !common.MatchGroupsName(event.GroupName, sub.IBusiGroups) {
return
}
if sub.ForDuration > (event.TriggerTime - event.FirstTriggerTime) { if sub.ForDuration > (event.TriggerTime - event.FirstTriggerTime) {
return return
} }
...@@ -213,7 +217,7 @@ func (e *Dispatch) Send(rule *models.AlertRule, event *models.AlertCurEvent, not ...@@ -213,7 +217,7 @@ func (e *Dispatch) Send(rule *models.AlertRule, event *models.AlertCurEvent, not
needSend := e.BeforeSenderHook(event) needSend := e.BeforeSenderHook(event)
if needSend { if needSend {
for channel, uids := range notifyTarget.ToChannelUserMap() { for channel, uids := range notifyTarget.ToChannelUserMap() {
ctx := sender.BuildMessageContext(rule, []*models.AlertCurEvent{event}, uids, e.userCache) msgCtx := sender.BuildMessageContext(rule, []*models.AlertCurEvent{event}, uids, e.userCache)
e.RwLock.RLock() e.RwLock.RLock()
s := e.Senders[channel] s := e.Senders[channel]
e.RwLock.RUnlock() e.RwLock.RUnlock()
...@@ -221,7 +225,7 @@ func (e *Dispatch) Send(rule *models.AlertRule, event *models.AlertCurEvent, not ...@@ -221,7 +225,7 @@ func (e *Dispatch) Send(rule *models.AlertRule, event *models.AlertCurEvent, not
logger.Debugf("no sender for channel: %s", channel) logger.Debugf("no sender for channel: %s", channel)
continue continue
} }
s.Send(ctx) s.Send(msgCtx)
} }
} }
......
...@@ -101,6 +101,7 @@ func (rt *Router) alertSubscribePut(c *gin.Context) { ...@@ -101,6 +101,7 @@ func (rt *Router) alertSubscribePut(c *gin.Context) {
"redefine_webhooks", "redefine_webhooks",
"severities", "severities",
"extra_config", "extra_config",
"busi_groups",
)) ))
} }
......
...@@ -23,6 +23,30 @@ type TagFilter struct { ...@@ -23,6 +23,30 @@ type TagFilter struct {
Vset map[string]struct{} // parse value to regexp if func = 'in' or 'not in' Vset map[string]struct{} // parse value to regexp if func = 'in' or 'not in'
} }
func GetTagFilters(jsonArr ormx.JSONArr) ([]TagFilter, error) {
bFilters := make([]TagFilter, 0)
err := json.Unmarshal(jsonArr, &bFilters)
if err != nil {
return nil, err
}
for i := 0; i < len(bFilters); i++ {
if bFilters[i].Func == "=~" || bFilters[i].Func == "!~" {
bFilters[i].Regexp, err = regexp.Compile(bFilters[i].Value)
if err != nil {
return nil, err
}
} else if bFilters[i].Func == "in" || bFilters[i].Func == "not in" {
arr := strings.Fields(bFilters[i].Value)
bFilters[i].Vset = make(map[string]struct{})
for j := 0; j < len(arr); j++ {
bFilters[i].Vset[arr[j]] = struct{}{}
}
}
}
return bFilters, nil
}
const TimeRange int = 0 const TimeRange int = 0
const Periodic int = 1 const Periodic int = 1
...@@ -139,26 +163,12 @@ func (m *AlertMute) Verify() error { ...@@ -139,26 +163,12 @@ func (m *AlertMute) Verify() error {
} }
func (m *AlertMute) Parse() error { func (m *AlertMute) Parse() error {
err := json.Unmarshal(m.Tags, &m.ITags) var err error
m.ITags, err = GetTagFilters(m.Tags)
if err != nil { if err != nil {
return err return err
} }
for i := 0; i < len(m.ITags); i++ {
if m.ITags[i].Func == "=~" || m.ITags[i].Func == "!~" {
m.ITags[i].Regexp, err = regexp.Compile(m.ITags[i].Value)
if err != nil {
return err
}
} else if m.ITags[i].Func == "in" || m.ITags[i].Func == "not in" {
arr := strings.Fields(m.ITags[i].Value)
m.ITags[i].Vset = make(map[string]struct{})
for j := 0; j < len(arr); j++ {
m.ITags[i].Vset[arr[j]] = struct{}{}
}
}
}
return nil return nil
} }
...@@ -222,8 +232,11 @@ func (m *AlertMute) FE2DB() error { ...@@ -222,8 +232,11 @@ func (m *AlertMute) FE2DB() error {
} }
func (m *AlertMute) DB2FE() error { func (m *AlertMute) DB2FE() error {
json.Unmarshal([]byte(m.DatasourceIds), &m.DatasourceIdsJson) err := json.Unmarshal([]byte(m.DatasourceIds), &m.DatasourceIdsJson)
err := json.Unmarshal([]byte(m.PeriodicMutes), &m.PeriodicMutesJson) if err != nil {
return err
}
err = json.Unmarshal([]byte(m.PeriodicMutes), &m.PeriodicMutesJson)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -2,7 +2,6 @@ package models ...@@ -2,7 +2,6 @@ package models
import ( import (
"encoding/json" "encoding/json"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
...@@ -46,6 +45,8 @@ type AlertSubscribe struct { ...@@ -46,6 +45,8 @@ type AlertSubscribe struct {
UpdateBy string `json:"update_by"` UpdateBy string `json:"update_by"`
UpdateAt int64 `json:"update_at"` UpdateAt int64 `json:"update_at"`
ITags []TagFilter `json:"-" gorm:"-"` // inner tags ITags []TagFilter `json:"-" gorm:"-"` // inner tags
BusiGroups ormx.JSONArr `json:"busi_groups"`
IBusiGroups []TagFilter `json:"-" gorm:"-"` // inner busiGroups
} }
func (s *AlertSubscribe) TableName() string { func (s *AlertSubscribe) TableName() string {
...@@ -162,26 +163,12 @@ func (s *AlertSubscribe) DB2FE() error { ...@@ -162,26 +163,12 @@ func (s *AlertSubscribe) DB2FE() error {
} }
func (s *AlertSubscribe) Parse() error { func (s *AlertSubscribe) Parse() error {
err := json.Unmarshal(s.Tags, &s.ITags) var err error
s.ITags, err = GetTagFilters(s.Tags)
if err != nil { if err != nil {
return err return err
} }
s.IBusiGroups, err = GetTagFilters(s.BusiGroups)
for i := 0; i < len(s.ITags); i++ {
if s.ITags[i].Func == "=~" || s.ITags[i].Func == "!~" {
s.ITags[i].Regexp, err = regexp.Compile(s.ITags[i].Value)
if err != nil {
return err
}
} else if s.ITags[i].Func == "in" || s.ITags[i].Func == "not in" {
arr := strings.Fields(s.ITags[i].Value)
s.ITags[i].Vset = make(map[string]struct{})
for j := 0; j < len(arr); j++ {
s.ITags[i].Vset[arr[j]] = struct{}{}
}
}
}
return err return err
} }
...@@ -246,7 +233,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG ...@@ -246,7 +233,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG
} }
exists := make([]string, 0, count) exists := make([]string, 0, count)
delete := false isDelete := false
for i := range ugids { for i := range ugids {
id, _ := strconv.ParseInt(ugids[i], 10, 64) id, _ := strconv.ParseInt(ugids[i], 10, 64)
...@@ -263,7 +250,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG ...@@ -263,7 +250,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG
} }
if ug == nil { if ug == nil {
delete = true isDelete = true
} else { } else {
exists = append(exists, ugids[i]) exists = append(exists, ugids[i])
s.UserGroups = append(s.UserGroups, *ug) s.UserGroups = append(s.UserGroups, *ug)
...@@ -271,7 +258,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG ...@@ -271,7 +258,7 @@ func (s *AlertSubscribe) FillUserGroups(ctx *ctx.Context, cache map[int64]*UserG
} }
} }
if delete { if isDelete {
// some user-group already deleted // some user-group already deleted
DB(ctx).Model(s).Update("user_group_ids", strings.Join(exists, " ")) DB(ctx).Model(s).Update("user_group_ids", strings.Join(exists, " "))
s.UserGroupIds = strings.Join(exists, " ") s.UserGroupIds = strings.Join(exists, " ")
......
package migrate package migrate
import ( import (
"github.com/ccfos/nightingale/v6/pkg/ormx"
"github.com/toolkits/pkg/logger" "github.com/toolkits/pkg/logger"
"gorm.io/gorm" "gorm.io/gorm"
) )
...@@ -46,8 +47,9 @@ type AlertRule struct { ...@@ -46,8 +47,9 @@ type AlertRule struct {
} }
type AlertSubscribe struct { type AlertSubscribe struct {
ExtraConfig string `gorm:"type:text;not null;column:extra_config"` // extra config ExtraConfig string `gorm:"type:text;not null;column:extra_config"` // extra config
Severities string `gorm:"column:severities;type:varchar(32);not null;default:''"` Severities string `gorm:"column:severities;type:varchar(32);not null;default:''"`
BusiGroups ormx.JSONArr `gorm:"column:busi_groups;type:varchar(4096);not null;default:'[]'"`
} }
type AlertMute struct { type AlertMute struct {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册