judge.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package judge
  2. import (
  3. "fmt"
  4. "log"
  5. "github.com/710leo/urlooker/dataobj"
  6. "github.com/710leo/urlooker/modules/alarm/backend"
  7. "github.com/710leo/urlooker/modules/alarm/cache"
  8. "github.com/710leo/urlooker/modules/alarm/sender"
  9. )
  10. func Judge(L *SafeLinkedList, item *dataobj.ItemStatus, now int64) {
  11. strategy, exists := cache.StrategyMap.Get(item.Sid)
  12. if !exists {
  13. return
  14. }
  15. event := &dataobj.Event{
  16. EventId: fmt.Sprintf("e_%d_%s", item.Id, item.PK()),
  17. Url: strategy.Url,
  18. StrategyId: item.Sid,
  19. Ip: item.Ip,
  20. EventTime: item.PushTime,
  21. RespCode: item.RespCode,
  22. RespTime: item.RespTime,
  23. Result: item.Result,
  24. }
  25. historyData, isTriggered := compute(L, item, strategy)
  26. sendEventIfNeed(historyData, isTriggered, now, event, strategy.MaxStep)
  27. }
  28. func compute(L *SafeLinkedList, item *dataobj.ItemStatus, strategy dataobj.Strategy) (historyData []*HistoryData, isTriggered bool) {
  29. historyData, isEnough := L.HistoryData(strategy.Times)
  30. if !isEnough {
  31. return
  32. }
  33. num := 0 //策略触发次数
  34. for i := 0; i < strategy.Times; i++ {
  35. if historyData[i].Value != 0 {
  36. num++
  37. }
  38. }
  39. if num < strategy.Times {
  40. return
  41. }
  42. isTriggered = true
  43. return
  44. }
  45. func sendEventIfNeed(historyData []*HistoryData, isTriggered bool, now int64, event *dataobj.Event, maxStep int) {
  46. lastEvent, exists := cache.LastEvents.Get(event.EventId)
  47. if isTriggered {
  48. event.Status = "PROBLEM"
  49. if !exists || lastEvent.Status[0] == 'O' {
  50. // 本次触发了阈值,之前又没报过警,得产生一个报警Event
  51. event.CurrentStep = 1
  52. // 但是有些用户把最大报警次数配置成了0,相当于屏蔽了,要检查一下
  53. if maxStep == 0 {
  54. return
  55. }
  56. sendEvent(event)
  57. return
  58. }
  59. // 逻辑走到这里,说明之前Event是PROBLEM状态
  60. if lastEvent.CurrentStep >= maxStep {
  61. // 报警次数已经足够多,到达了最多报警次数了,不再报警
  62. return
  63. }
  64. if historyData[len(historyData)-1].Timestamp <= lastEvent.EventTime {
  65. // 产生过报警的点,就不能再使用来判断了,否则容易出现一分钟报一次的情况
  66. return
  67. }
  68. event.CurrentStep = lastEvent.CurrentStep + 1
  69. sendEvent(event)
  70. } else {
  71. // 如果LastEvent是Problem,报OK,否则啥都不做
  72. if exists && lastEvent.Status[0] == 'P' {
  73. event.Status = "OK"
  74. event.CurrentStep = 1
  75. sendEvent(event)
  76. }
  77. }
  78. }
  79. func sendEvent(event *dataobj.Event) {
  80. cache.LastEvents.Set(event.EventId, event)
  81. saveEvent(event)
  82. sender.SendEvent(event)
  83. }
  84. func saveEvent(event *dataobj.Event) {
  85. var reply string
  86. err := backend.CallRpc("Web.SaveEvent", event, &reply)
  87. if err != nil {
  88. log.Println("[ERROR] Web.SaveEvent:", err)
  89. return
  90. }
  91. if reply != "" {
  92. log.Println("reply:", reply)
  93. }
  94. }