package judge import ( "fmt" "log" "github.com/710leo/urlooker/dataobj" "github.com/710leo/urlooker/modules/alarm/backend" "github.com/710leo/urlooker/modules/alarm/cache" "github.com/710leo/urlooker/modules/alarm/sender" ) func Judge(L *SafeLinkedList, item *dataobj.ItemStatus, now int64) { strategy, exists := cache.StrategyMap.Get(item.Sid) if !exists { return } event := &dataobj.Event{ EventId: fmt.Sprintf("e_%d_%s", item.Id, item.PK()), Url: strategy.Url, StrategyId: item.Sid, Ip: item.Ip, EventTime: item.PushTime, RespCode: item.RespCode, RespTime: item.RespTime, Result: item.Result, } historyData, isTriggered := compute(L, item, strategy) sendEventIfNeed(historyData, isTriggered, now, event, strategy.MaxStep) } func compute(L *SafeLinkedList, item *dataobj.ItemStatus, strategy dataobj.Strategy) (historyData []*HistoryData, isTriggered bool) { historyData, isEnough := L.HistoryData(strategy.Times) if !isEnough { return } num := 0 //策略触发次数 for i := 0; i < strategy.Times; i++ { if historyData[i].Value != 0 { num++ } } if num < strategy.Times { return } isTriggered = true return } func sendEventIfNeed(historyData []*HistoryData, isTriggered bool, now int64, event *dataobj.Event, maxStep int) { lastEvent, exists := cache.LastEvents.Get(event.EventId) if isTriggered { event.Status = "PROBLEM" if !exists || lastEvent.Status[0] == 'O' { // 本次触发了阈值,之前又没报过警,得产生一个报警Event event.CurrentStep = 1 // 但是有些用户把最大报警次数配置成了0,相当于屏蔽了,要检查一下 if maxStep == 0 { return } sendEvent(event) return } // 逻辑走到这里,说明之前Event是PROBLEM状态 if lastEvent.CurrentStep >= maxStep { // 报警次数已经足够多,到达了最多报警次数了,不再报警 return } if historyData[len(historyData)-1].Timestamp <= lastEvent.EventTime { // 产生过报警的点,就不能再使用来判断了,否则容易出现一分钟报一次的情况 return } event.CurrentStep = lastEvent.CurrentStep + 1 sendEvent(event) } else { // 如果LastEvent是Problem,报OK,否则啥都不做 if exists && lastEvent.Status[0] == 'P' { event.Status = "OK" event.CurrentStep = 1 sendEvent(event) } } } func sendEvent(event *dataobj.Event) { cache.LastEvents.Set(event.EventId, event) saveEvent(event) sender.SendEvent(event) } func saveEvent(event *dataobj.Event) { var reply string err := backend.CallRpc("Web.SaveEvent", event, &reply) if err != nil { log.Println("[ERROR] Web.SaveEvent:", err) return } if reply != "" { log.Println("reply:", reply) } }