feat: 报警规则支持绑定触发任务
This commit is contained in:
		
							parent
							
								
									ceb1b74834
								
							
						
					
					
						commit
						13d1be59b6
					
				@ -615,6 +615,8 @@ type alertRuleForm struct {
 | 
				
			|||||||
	ID                     uint64
 | 
						ID                     uint64
 | 
				
			||||||
	Name                   string
 | 
						Name                   string
 | 
				
			||||||
	RulesRaw               string
 | 
						RulesRaw               string
 | 
				
			||||||
 | 
						FailTriggerTasksRaw    string // 失败时触发的任务id
 | 
				
			||||||
 | 
						RecoverTriggerTasksRaw string // 恢复时触发的任务id
 | 
				
			||||||
	NotificationTag        string
 | 
						NotificationTag        string
 | 
				
			||||||
	TriggerMode            int
 | 
						TriggerMode            int
 | 
				
			||||||
	Enable                 string
 | 
						Enable                 string
 | 
				
			||||||
@ -657,12 +659,22 @@ func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) {
 | 
				
			|||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		r.Name = arf.Name
 | 
							r.Name = arf.Name
 | 
				
			||||||
		r.RulesRaw = arf.RulesRaw
 | 
							r.RulesRaw = arf.RulesRaw
 | 
				
			||||||
 | 
							r.FailTriggerTasksRaw = arf.FailTriggerTasksRaw
 | 
				
			||||||
 | 
							r.RecoverTriggerTasksRaw = arf.RecoverTriggerTasksRaw
 | 
				
			||||||
		r.NotificationTag = arf.NotificationTag
 | 
							r.NotificationTag = arf.NotificationTag
 | 
				
			||||||
		enable := arf.Enable == "on"
 | 
							enable := arf.Enable == "on"
 | 
				
			||||||
		r.TriggerMode = arf.TriggerMode
 | 
							r.TriggerMode = arf.TriggerMode
 | 
				
			||||||
		r.Enable = &enable
 | 
							r.Enable = &enable
 | 
				
			||||||
		r.ID = arf.ID
 | 
							r.ID = arf.ID
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							err = utils.Json.Unmarshal([]byte(arf.FailTriggerTasksRaw), &r.FailTriggerTasks)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							err = utils.Json.Unmarshal([]byte(arf.RecoverTriggerTasksRaw), &r.RecoverTriggerTasks)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	//保证NotificationTag不为空
 | 
						//保证NotificationTag不为空
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
		if r.NotificationTag == "" {
 | 
							if r.NotificationTag == "" {
 | 
				
			||||||
			r.NotificationTag = "default"
 | 
								r.NotificationTag = "default"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,20 +30,44 @@ type AlertRule struct {
 | 
				
			|||||||
	Enable                 *bool
 | 
						Enable                 *bool
 | 
				
			||||||
	TriggerMode            int    `gorm:"default:0"` // 触发模式: 0-始终触发(默认) 1-单次触发
 | 
						TriggerMode            int    `gorm:"default:0"` // 触发模式: 0-始终触发(默认) 1-单次触发
 | 
				
			||||||
	NotificationTag        string // 该报警规则所在的通知组
 | 
						NotificationTag        string // 该报警规则所在的通知组
 | 
				
			||||||
 | 
						FailTriggerTasksRaw    string
 | 
				
			||||||
 | 
						RecoverTriggerTasksRaw string
 | 
				
			||||||
	Rules                  []Rule   `gorm:"-" json:"-"`
 | 
						Rules                  []Rule   `gorm:"-" json:"-"`
 | 
				
			||||||
 | 
						FailTriggerTasks       []uint64 `gorm:"-" json:"-"` // 失败时执行的触发任务id
 | 
				
			||||||
 | 
						RecoverTriggerTasks    []uint64 `gorm:"-" json:"-"` // 恢复时执行的触发任务id
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *AlertRule) BeforeSave(tx *gorm.DB) error {
 | 
					func (r *AlertRule) BeforeSave(tx *gorm.DB) error {
 | 
				
			||||||
	data, err := utils.Json.Marshal(r.Rules)
 | 
						if data, err := utils.Json.Marshal(r.Rules); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						} else {
 | 
				
			||||||
		r.RulesRaw = string(data)
 | 
							r.RulesRaw = string(data)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if data, err := utils.Json.Marshal(r.FailTriggerTasks); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							r.FailTriggerTasksRaw = string(data)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if data, err := utils.Json.Marshal(r.RecoverTriggerTasks); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							r.RecoverTriggerTasksRaw = string(data)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *AlertRule) AfterFind(tx *gorm.DB) error {
 | 
					func (r *AlertRule) AfterFind(tx *gorm.DB) error {
 | 
				
			||||||
	return utils.Json.Unmarshal([]byte(r.RulesRaw), &r.Rules)
 | 
						var err error
 | 
				
			||||||
 | 
						if err = utils.Json.Unmarshal([]byte(r.RulesRaw), &r.Rules); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err = utils.Json.Unmarshal([]byte(r.FailTriggerTasksRaw), &r.FailTriggerTasks); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err = utils.Json.Unmarshal([]byte(r.RecoverTriggerTasksRaw), &r.RecoverTriggerTasks); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *AlertRule) Enabled() bool {
 | 
					func (r *AlertRule) Enabled() bool {
 | 
				
			||||||
 | 
				
			|||||||
@ -162,6 +162,7 @@ func checkStatus() {
 | 
				
			|||||||
					message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.MustLocalize(&i18n.LocalizeConfig{
 | 
										message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.MustLocalize(&i18n.LocalizeConfig{
 | 
				
			||||||
						MessageID: "Incident",
 | 
											MessageID: "Incident",
 | 
				
			||||||
					}), server.Name, IPDesensitize(server.Host.IP), alert.Name)
 | 
										}), server.Name, IPDesensitize(server.Host.IP), alert.Name)
 | 
				
			||||||
 | 
										go SendTriggerTasks(alert.FailTriggerTasks, curServer.ID)
 | 
				
			||||||
					go SendNotification(alert.NotificationTag, message, true, &curServer)
 | 
										go SendNotification(alert.NotificationTag, message, true, &curServer)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
@ -170,6 +171,7 @@ func checkStatus() {
 | 
				
			|||||||
					message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.MustLocalize(&i18n.LocalizeConfig{
 | 
										message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.MustLocalize(&i18n.LocalizeConfig{
 | 
				
			||||||
						MessageID: "Resolved",
 | 
											MessageID: "Resolved",
 | 
				
			||||||
					}), server.Name, IPDesensitize(server.Host.IP), alert.Name)
 | 
										}), server.Name, IPDesensitize(server.Host.IP), alert.Name)
 | 
				
			||||||
 | 
										go SendTriggerTasks(alert.RecoverTriggerTasks, curServer.ID)
 | 
				
			||||||
					go SendNotification(alert.NotificationTag, message, true, &curServer)
 | 
										go SendNotification(alert.NotificationTag, message, true, &curServer)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				alertsPrevState[alert.ID][server.ID] = _RuleCheckPass
 | 
									alertsPrevState[alert.ID][server.ID] = _RuleCheckPass
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,7 @@ func LoadCronTasks() {
 | 
				
			|||||||
	for i := 0; i < len(crons); i++ {
 | 
						for i := 0; i < len(crons); i++ {
 | 
				
			||||||
		// 触发任务类型无需注册
 | 
							// 触发任务类型无需注册
 | 
				
			||||||
		if crons[i].TaskType == model.CronTypeTriggerTask {
 | 
							if crons[i].TaskType == model.CronTypeTriggerTask {
 | 
				
			||||||
 | 
								Crons[crons[i].ID] = &crons[i]
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// 旧版本计划任务可能不存在通知组 为其添加默认通知组
 | 
							// 旧版本计划任务可能不存在通知组 为其添加默认通知组
 | 
				
			||||||
@ -68,6 +69,22 @@ func ManualTrigger(c model.Cron) {
 | 
				
			|||||||
	CronTrigger(c)()
 | 
						CronTrigger(c)()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SendTriggerTasks(taskIDs []uint64, triggerServer uint64) {
 | 
				
			||||||
 | 
						CronLock.RLock()
 | 
				
			||||||
 | 
						var cronLists []*model.Cron
 | 
				
			||||||
 | 
						for _, taskID := range taskIDs {
 | 
				
			||||||
 | 
							if c, ok := Crons[taskID]; ok {
 | 
				
			||||||
 | 
								cronLists = append(cronLists, c)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						CronLock.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 依次调用CronTrigger发送任务
 | 
				
			||||||
 | 
						for _, c := range cronLists {
 | 
				
			||||||
 | 
							go CronTrigger(*c, triggerServer)()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CronTrigger(cr model.Cron, triggerServer ...uint64) func() {
 | 
					func CronTrigger(cr model.Cron, triggerServer ...uint64) func() {
 | 
				
			||||||
	crIgnoreMap := make(map[uint64]bool)
 | 
						crIgnoreMap := make(map[uint64]bool)
 | 
				
			||||||
	for j := 0; j < len(cr.Servers); j++ {
 | 
						for j := 0; j < len(cr.Servers); j++ {
 | 
				
			||||||
@ -76,7 +93,7 @@ func CronTrigger(cr model.Cron, triggerServer ...uint64) func() {
 | 
				
			|||||||
	return func() {
 | 
						return func() {
 | 
				
			||||||
		if cr.Cover == model.CronCoverSelf {
 | 
							if cr.Cover == model.CronCoverSelf {
 | 
				
			||||||
			if len(triggerServer) == 0 {
 | 
								if len(triggerServer) == 0 {
 | 
				
			||||||
				log.Println("触发任务未指定触发服务器")
 | 
									log.Println("触发任务", cr.Name, "未指定触发服务器")
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ServerLock.RLock()
 | 
								ServerLock.RLock()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user