diff --git a/cfg.example.json b/cfg.example.json index ac6aa4e..fc3c8fb 100644 --- a/cfg.example.json +++ b/cfg.example.json @@ -26,6 +26,7 @@ "userSmsQueue": "/queue/user/sms", "userMailQueue": "/queue/user/mail" }, + "savefile":"/tmp/alarm.cache.file", "api": { "portal": "http://falcon.example.com", "uic": "http://uic.example.com", diff --git a/g/cfg.go b/g/cfg.go index aa15b70..8c74b7b 100644 --- a/g/cfg.go +++ b/g/cfg.go @@ -39,6 +39,7 @@ type GlobalConfig struct { Queue *QueueConfig `json:"queue"` Redis *RedisConfig `json:"redis"` Api *ApiConfig `json:"api"` + SaveFile string `json:"savefile"` } var ( diff --git a/g/eventdto.go b/g/eventdto.go index 75cbd30..aae8f9a 100644 --- a/g/eventdto.go +++ b/g/eventdto.go @@ -30,6 +30,7 @@ type EventDto struct { ExpressionId int `json:"expressionId"` StrategyId int `json:"strategyId"` TemplateId int `json:"templateId"` + ActionId int `json:"actionId"` Link string `json:"link"` } @@ -53,6 +54,12 @@ func (this OrderedEvents) Less(i, j int) bool { var Events = &SafeEvents{M: make(map[string]*EventDto)} +func (this *SafeEvents) Init(m map[string]*EventDto) { + this.Lock() + defer this.Unlock() + this.M = m +} + func (this *SafeEvents) Delete(id string) { this.Lock() defer this.Unlock() @@ -102,6 +109,7 @@ func (this *SafeEvents) Put(event *model.Event) { dto.ExpressionId = event.ExpressionId() dto.StrategyId = event.StrategyId() dto.TemplateId = event.TplId() + dto.ActionId = event.ActionId() dto.Link = Link(event) diff --git a/g/savetofile.go b/g/savetofile.go new file mode 100644 index 0000000..eeeb520 --- /dev/null +++ b/g/savetofile.go @@ -0,0 +1,51 @@ +package g + +import( + "os" + "io/ioutil" + "encoding/json" + "log" +) + + +func SaveCacheToFile() { + event := Events.Clone() + body, err := json.Marshal(event) + if err != nil { + log.Println("SaveCacheToFile Fail:",err) + return + } + + if config.SaveFile == "" { + log.Println("config savefile is empty") + return + } + err2 := ioutil.WriteFile(config.SaveFile, body, 0666) + if err2 != nil { + log.Println("SaveCacheToFile save event list to file Fail!",err2) + } +} + +func ReadCacheFromFile() { + fi,err := os.Open( config.SaveFile ) + if err != nil { + log.Println("ReadCacheFromFile , cache file open fail:",err) + return + } + + defer fi.Close() + + var events map[string]*EventDto + fd,err := ioutil.ReadAll(fi) + jerr := json.Unmarshal(fd,&events) + if err != nil || jerr != nil { + log.Println("ReadCacheFromFile, json decode cache file content error: ", err,jerr) + return + } + + if config.Debug { + log.Println("read event from cache file is:",string(fd)) + } + + Events.Init(events) +} diff --git a/http/controller.go b/http/controller.go index da58eea..9bf008c 100644 --- a/http/controller.go +++ b/http/controller.go @@ -23,6 +23,11 @@ func (this *MainController) Health() { this.Ctx.WriteString("ok") } +func (this *MainController) EventList() { + events := g.Events.Clone() + this.Ctx.Output.JSON(events,false,false) +} + func (this *MainController) Workdir() { this.Ctx.WriteString(fmt.Sprintf("%s", file.SelfDir())) } diff --git a/http/http.go b/http/http.go index 7ad5a92..d6d80e0 100644 --- a/http/http.go +++ b/http/http.go @@ -2,11 +2,10 @@ package http import ( "fmt" - "log" - _ "net/http/pprof" - "github.com/astaxie/beego" "github.com/open-falcon/alarm/g" + "log" + _ "net/http/pprof" ) func configRoutes() { @@ -15,6 +14,7 @@ func configRoutes() { beego.Router("/health", &MainController{}, "get:Health") beego.Router("/workdir", &MainController{}, "get:Workdir") beego.Router("/config/reload", &MainController{}, "get:ConfigReload") + beego.Router("/eventlist", &MainController{}, "get:EventList") beego.Router("/event/solve", &MainController{}, "post:Solve") } diff --git a/main.go b/main.go index 5becef4..53b1104 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,8 @@ func main() { g.ParseConfig(*cfg) g.InitRedisConnPool() + //初始化,从cache文件中获取event list + g.ReadCacheFromFile() go http.Start() @@ -38,10 +40,12 @@ func main() { go cron.CombineMail() sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL) go func() { <-sigs fmt.Println() + //将当前的未恢复报警落地到文件 + g.SaveCacheToFile() g.RedisConnPool.Close() os.Exit(0) }()