nezha/service/dao/alertsentinel.go
2021-05-27 20:48:12 +08:00

114 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dao
import (
"fmt"
"log"
"sync"
"time"
"github.com/naiba/nezha/model"
"github.com/naiba/nezha/pkg/utils"
)
// 报警规则
var alertsLock sync.RWMutex
var alerts []model.AlertRule
var alertsStore map[uint64]map[uint64][][]interface{}
type NotificationHistory struct {
Duration time.Duration
Until time.Time
}
func AlertSentinelStart() {
alertsStore = make(map[uint64]map[uint64][][]interface{})
notificationsLock.Lock()
if err := DB.Find(&notifications).Error; err != nil {
panic(err)
}
notificationsLock.Unlock()
alertsLock.Lock()
if err := DB.Find(&alerts).Error; err != nil {
panic(err)
}
for i := 0; i < len(alerts); i++ {
alertsStore[alerts[i].ID] = make(map[uint64][][]interface{})
}
alertsLock.Unlock()
time.Sleep(time.Second * 10)
var lastPrint time.Time
var checkCount uint64
for {
startedAt := time.Now()
checkStatus()
checkCount++
if lastPrint.Before(startedAt.Add(-1 * time.Hour)) {
if Conf.Debug {
log.Println("报警规则检测每小时", checkCount, "次", startedAt, time.Now())
}
checkCount = 0
lastPrint = startedAt
}
time.Sleep(time.Until(startedAt.Add(time.Second * SnapshotDelay)))
}
}
func OnRefreshOrAddAlert(alert model.AlertRule) {
alertsLock.Lock()
defer alertsLock.Unlock()
delete(alertsStore, alert.ID)
var isEdit bool
for i := 0; i < len(alerts); i++ {
if alerts[i].ID == alert.ID {
alerts[i] = alert
isEdit = true
}
}
if !isEdit {
alerts = append(alerts, alert)
}
alertsStore[alert.ID] = make(map[uint64][][]interface{})
}
func OnDeleteAlert(id uint64) {
alertsLock.Lock()
defer alertsLock.Unlock()
delete(alertsStore, id)
for i := 0; i < len(alerts); i++ {
if alerts[i].ID == id {
alerts = append(alerts[:i], alerts[i+1:]...)
i--
}
}
}
func checkStatus() {
alertsLock.RLock()
defer alertsLock.RUnlock()
ServerLock.RLock()
defer ServerLock.RUnlock()
for _, alert := range alerts {
// 跳过未启用
if alert.Enable == nil || !*alert.Enable {
continue
}
for _, server := range ServerList {
// 监测点
alertsStore[alert.ID][server.ID] = append(alertsStore[alert.
ID][server.ID], alert.Snapshot(server))
// 发送通知
max, desc := alert.Check(alertsStore[alert.ID][server.ID])
if desc != "" {
message := fmt.Sprintf("报警规则:%s服务器%s(%s),逮到咯,快去看看!", alert.Name, server.Name, utils.IPDesensitize(server.Host.IP))
go SendNotification(message, true)
}
// 清理旧数据
if max > 0 && max < len(alertsStore[alert.ID][server.ID]) {
alertsStore[alert.ID][server.ID] = alertsStore[alert.ID][server.ID][len(alertsStore[alert.ID][server.ID])-max:]
}
}
}
}