[feature] support multiple cluster config with mute&subscribe (#1046)
* [feature] support multiple cluster config with mute&subscribe * [feature] support multiple cluster config with mute&subscribe
This commit is contained in:
parent
299270f74e
commit
538880b0e0
|
@ -22,8 +22,8 @@ type TagFilter struct {
|
||||||
type AlertMute struct {
|
type AlertMute struct {
|
||||||
Id int64 `json:"id" gorm:"primaryKey"`
|
Id int64 `json:"id" gorm:"primaryKey"`
|
||||||
GroupId int64 `json:"group_id"`
|
GroupId int64 `json:"group_id"`
|
||||||
Prod string `json:"prod"` // product empty means n9e
|
Prod string `json:"prod"` // product empty means n9e
|
||||||
Cluster string `json:"cluster"`
|
Cluster string `json:"cluster"` // take effect by clusters, seperated by space
|
||||||
Tags ormx.JSONArr `json:"tags"`
|
Tags ormx.JSONArr `json:"tags"`
|
||||||
Cause string `json:"cause"`
|
Cause string `json:"cause"`
|
||||||
Btime int64 `json:"btime"`
|
Btime int64 `json:"btime"`
|
||||||
|
@ -44,7 +44,7 @@ func AlertMuteGets(prods []string, bgid int64, query string) (lst []AlertMute, e
|
||||||
arr := strings.Fields(query)
|
arr := strings.Fields(query)
|
||||||
for i := 0; i < len(arr); i++ {
|
for i := 0; i < len(arr); i++ {
|
||||||
qarg := "%" + arr[i] + "%"
|
qarg := "%" + arr[i] + "%"
|
||||||
session = session.Where("cause like ?", qarg, qarg)
|
session = session.Where("cause like ?", qarg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,10 @@ func (m *AlertMute) Verify() error {
|
||||||
return errors.New("cluster invalid")
|
return errors.New("cluster invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if IsClusterAll(m.Cluster) {
|
||||||
|
m.Cluster = ClusterAll
|
||||||
|
}
|
||||||
|
|
||||||
if m.Etime <= m.Btime {
|
if m.Etime <= m.Btime {
|
||||||
return fmt.Errorf("Oops... etime(%d) <= btime(%d)", m.Etime, m.Btime)
|
return fmt.Errorf("Oops... etime(%d) <= btime(%d)", m.Etime, m.Btime)
|
||||||
}
|
}
|
||||||
|
@ -123,7 +127,7 @@ func AlertMuteDel(ids []int64) error {
|
||||||
func AlertMuteStatistics(cluster string) (*Statistics, error) {
|
func AlertMuteStatistics(cluster string) (*Statistics, error) {
|
||||||
session := DB().Model(&AlertMute{}).Select("count(*) as total", "max(create_at) as last_updated")
|
session := DB().Model(&AlertMute{}).Select("count(*) as total", "max(create_at) as last_updated")
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("cluster = ?", cluster)
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var stats []*Statistics
|
var stats []*Statistics
|
||||||
|
@ -146,10 +150,19 @@ func AlertMuteGetsByCluster(cluster string) ([]*AlertMute, error) {
|
||||||
// get my cluster's mutes
|
// get my cluster's mutes
|
||||||
session := DB().Model(&AlertMute{})
|
session := DB().Model(&AlertMute{})
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("cluster = ?", cluster)
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lst []*AlertMute
|
var lst []*AlertMute
|
||||||
|
var mlst []*AlertMute
|
||||||
err = session.Find(&lst).Error
|
err = session.Find(&lst).Error
|
||||||
return lst, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, m := range lst {
|
||||||
|
if MatchCluster(m.Cluster, cluster) {
|
||||||
|
mlst = append(mlst, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mlst, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,10 @@ func (ar *AlertRule) Verify() error {
|
||||||
return errors.New("cluster is blank")
|
return errors.New("cluster is blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if IsClusterAll(ar.Cluster) {
|
||||||
|
ar.Cluster = ClusterAll
|
||||||
|
}
|
||||||
|
|
||||||
if str.Dangerous(ar.Name) {
|
if str.Dangerous(ar.Name) {
|
||||||
return errors.New("Name has invalid characters")
|
return errors.New("Name has invalid characters")
|
||||||
}
|
}
|
||||||
|
@ -301,7 +305,7 @@ func AlertRuleGetsByCluster(cluster string) ([]*AlertRule, error) {
|
||||||
session := DB().Where("disabled = ? and prod = ?", 0, "")
|
session := DB().Where("disabled = ? and prod = ?", 0, "")
|
||||||
|
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("(cluster like ? or cluster like ?)", "%"+cluster+"%", "%"+ClusterAll+"%")
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lst []*AlertRule
|
var lst []*AlertRule
|
||||||
|
@ -393,7 +397,7 @@ func AlertRuleStatistics(cluster string) (*Statistics, error) {
|
||||||
|
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
// 简略的判断,当一个clustername是另一个clustername的substring的时候,会出现stats与预期不符,不影响使用
|
// 简略的判断,当一个clustername是另一个clustername的substring的时候,会出现stats与预期不符,不影响使用
|
||||||
session = session.Where("(cluster like ? or cluster like ?)", "%"+cluster+"%", "%"+ClusterAll+"%")
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var stats []*Statistics
|
var stats []*Statistics
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
type AlertSubscribe struct {
|
type AlertSubscribe struct {
|
||||||
Id int64 `json:"id" gorm:"primaryKey"`
|
Id int64 `json:"id" gorm:"primaryKey"`
|
||||||
GroupId int64 `json:"group_id"`
|
GroupId int64 `json:"group_id"`
|
||||||
Cluster string `json:"cluster"`
|
Cluster string `json:"cluster"` // take effect by clusters, seperated by space
|
||||||
RuleId int64 `json:"rule_id"`
|
RuleId int64 `json:"rule_id"`
|
||||||
RuleName string `json:"rule_name" gorm:"-"` // for fe
|
RuleName string `json:"rule_name" gorm:"-"` // for fe
|
||||||
Tags ormx.JSONArr `json:"tags"`
|
Tags ormx.JSONArr `json:"tags"`
|
||||||
|
@ -59,6 +59,10 @@ func (s *AlertSubscribe) Verify() error {
|
||||||
return errors.New("cluster invalid")
|
return errors.New("cluster invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if IsClusterAll(s.Cluster) {
|
||||||
|
s.Cluster = ClusterAll
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.Parse(); err != nil {
|
if err := s.Parse(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -202,7 +206,7 @@ func AlertSubscribeStatistics(cluster string) (*Statistics, error) {
|
||||||
session := DB().Model(&AlertSubscribe{}).Select("count(*) as total", "max(update_at) as last_updated")
|
session := DB().Model(&AlertSubscribe{}).Select("count(*) as total", "max(update_at) as last_updated")
|
||||||
|
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("cluster = ?", cluster)
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var stats []*Statistics
|
var stats []*Statistics
|
||||||
|
@ -218,10 +222,19 @@ func AlertSubscribeGetsByCluster(cluster string) ([]*AlertSubscribe, error) {
|
||||||
// get my cluster's subscribes
|
// get my cluster's subscribes
|
||||||
session := DB().Model(&AlertSubscribe{})
|
session := DB().Model(&AlertSubscribe{})
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("cluster = ?", cluster)
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lst []*AlertSubscribe
|
var lst []*AlertSubscribe
|
||||||
|
var slst []*AlertSubscribe
|
||||||
err := session.Find(&lst).Error
|
err := session.Find(&lst).Error
|
||||||
return lst, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, s := range lst {
|
||||||
|
if MatchCluster(s.Cluster, cluster) {
|
||||||
|
slst = append(slst, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slst, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,3 +60,13 @@ func MatchCluster(ruleCluster, targetCluster string) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsClusterAll(ruleCluster string) bool {
|
||||||
|
clusters := strings.Fields(ruleCluster)
|
||||||
|
for _, c := range clusters {
|
||||||
|
if c == ClusterAll {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,10 @@ func (re *RecordingRule) Verify() error {
|
||||||
return errors.New("cluster is blank")
|
return errors.New("cluster is blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if IsClusterAll(re.Cluster) {
|
||||||
|
re.Cluster = ClusterAll
|
||||||
|
}
|
||||||
|
|
||||||
if !model.MetricNameRE.MatchString(re.Name) {
|
if !model.MetricNameRE.MatchString(re.Name) {
|
||||||
return errors.New("Name has invalid chreacters")
|
return errors.New("Name has invalid chreacters")
|
||||||
}
|
}
|
||||||
|
@ -193,7 +197,7 @@ func RecordingRuleGetsByCluster(cluster string) ([]*RecordingRule, error) {
|
||||||
session := DB().Where("disabled = ? and prod = ?", 0, "")
|
session := DB().Where("disabled = ? and prod = ?", 0, "")
|
||||||
|
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
session = session.Where("(cluster like ? or cluster like ?)", "%"+cluster+"%", "%"+ClusterAll+"%")
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lst []*RecordingRule
|
var lst []*RecordingRule
|
||||||
|
@ -228,7 +232,7 @@ func RecordingRuleStatistics(cluster string) (*Statistics, error) {
|
||||||
session := DB().Model(&RecordingRule{}).Select("count(*) as total", "max(update_at) as last_updated")
|
session := DB().Model(&RecordingRule{}).Select("count(*) as total", "max(update_at) as last_updated")
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
// 简略的判断,当一个clustername是另一个clustername的substring的时候,会出现stats与预期不符,不影响使用
|
// 简略的判断,当一个clustername是另一个clustername的substring的时候,会出现stats与预期不符,不影响使用
|
||||||
session = session.Where("(cluster like ? or cluster like ?)", "%"+cluster+"%", "%"+ClusterAll+"%")
|
session = session.Where("(cluster like ? or cluster = ?)", "%"+cluster+"%", ClusterAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
var stats []*Statistics
|
var stats []*Statistics
|
||||||
|
|
Loading…
Reference in New Issue