mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 04:30:05 +00:00
WIP: 通知方式分组 支持将不同的报警|监控|计划任务的通知 发送到指定的通知分组
This commit is contained in:
@@ -29,10 +29,10 @@ func (s *NezhaHandler) ReportTask(c context.Context, r *pb.TaskResult) (*pb.Rece
|
||||
singleton.ServerLock.RLock()
|
||||
defer singleton.ServerLock.RUnlock()
|
||||
if cr.PushSuccessful && r.GetSuccessful() {
|
||||
singleton.SendNotification(fmt.Sprintf("[任务成功] %s ,服务器:%s,日志:\n%s", cr.Name, singleton.ServerList[clientID].Name, r.GetData()), false)
|
||||
singleton.SendNotification(cr.NotificationTag, fmt.Sprintf("[任务成功] %s ,服务器:%s,日志:\n%s", cr.Name, singleton.ServerList[clientID].Name, r.GetData()), false)
|
||||
}
|
||||
if !r.GetSuccessful() {
|
||||
singleton.SendNotification(fmt.Sprintf("[任务失败] %s ,服务器:%s,日志:\n%s", cr.Name, singleton.ServerList[clientID].Name, r.GetData()), false)
|
||||
singleton.SendNotification(cr.NotificationTag, fmt.Sprintf("[任务失败] %s ,服务器:%s,日志:\n%s", cr.Name, singleton.ServerList[clientID].Name, r.GetData()), false)
|
||||
}
|
||||
singleton.DB.Model(cr).Updates(model.Cron{
|
||||
LastExecutedAt: time.Now().Add(time.Second * -1 * time.Duration(r.GetDelay())),
|
||||
@@ -103,7 +103,7 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
|
||||
singleton.ServerList[clientID].Host.IP != "" &&
|
||||
host.IP != "" &&
|
||||
singleton.ServerList[clientID].Host.IP != host.IP {
|
||||
singleton.SendNotification(fmt.Sprintf(
|
||||
singleton.SendNotification(singleton.Conf.IPChangeNotificationTag, fmt.Sprintf(
|
||||
"[IP变更] %s ,旧IP:%s,新IP:%s。",
|
||||
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].Host.IP), singleton.IPDesensitize(host.IP)), true)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
var (
|
||||
Cron *cron.Cron
|
||||
Crons map[uint64]*model.Cron
|
||||
Crons map[uint64]*model.Cron // [CrondID] -> *model.Cron
|
||||
CronLock sync.RWMutex
|
||||
)
|
||||
|
||||
@@ -27,9 +27,12 @@ func LoadCronTasks() {
|
||||
DB.Find(&crons)
|
||||
var err error
|
||||
errMsg := new(bytes.Buffer)
|
||||
for i := 0; i < len(crons); i++ {
|
||||
cr := crons[i]
|
||||
|
||||
var notificationTagList []string
|
||||
for _, cr := range crons {
|
||||
// 旧版本计划任务可能不存在通知组 为其添加默认通知组
|
||||
if cr.NotificationTag == "" {
|
||||
AddDefaultCronNotificationTag(&cr)
|
||||
}
|
||||
// 注册计划任务
|
||||
cr.CronJobID, err = Cron.AddFunc(cr.Scheduler, CronTrigger(cr))
|
||||
if err == nil {
|
||||
@@ -39,15 +42,30 @@ func LoadCronTasks() {
|
||||
errMsg.WriteString("调度失败的计划任务:[")
|
||||
}
|
||||
errMsg.WriteString(fmt.Sprintf("%d,", cr.ID))
|
||||
notificationTagList = append(notificationTagList, cr.NotificationTag)
|
||||
}
|
||||
}
|
||||
if errMsg.Len() > 0 {
|
||||
msg := errMsg.String()
|
||||
SendNotification(msg[:len(msg)-1]+"] 这些任务将无法正常执行,请进入后点重新修改保存。", false)
|
||||
msg := errMsg.String() + "] 这些任务将无法正常执行,请进入后点重新修改保存。"
|
||||
for _, tag := range notificationTagList {
|
||||
// 向调度错误的计划任务所包含的所有通知组发送通知
|
||||
SendNotification(tag, msg, false)
|
||||
}
|
||||
}
|
||||
Cron.Start()
|
||||
}
|
||||
|
||||
// AddDefaultCronNotificationTag 添加默认的计划任务通知组
|
||||
func AddDefaultCronNotificationTag(c *model.Cron) {
|
||||
CronLock.Lock()
|
||||
defer CronLock.Unlock()
|
||||
|
||||
if c.NotificationTag == "" {
|
||||
c.NotificationTag = "default"
|
||||
}
|
||||
DB.Save(c)
|
||||
}
|
||||
|
||||
func ManualTrigger(c model.Cron) {
|
||||
CronTrigger(c)()
|
||||
}
|
||||
@@ -74,7 +92,7 @@ func CronTrigger(cr model.Cron) func() {
|
||||
Type: model.TaskTypeCommand,
|
||||
})
|
||||
} else {
|
||||
SendNotification(fmt.Sprintf("[任务失败] %s,服务器 %s 离线,无法执行。", cr.Name, s.Name), false)
|
||||
SendNotification(cr.NotificationTag, fmt.Sprintf("[任务失败] %s,服务器 %s 离线,无法执行。", cr.Name, s.Name), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,46 +13,95 @@ import (
|
||||
const firstNotificationDelay = time.Minute * 15
|
||||
|
||||
// 通知方式
|
||||
var notifications []model.Notification
|
||||
var notificationsLock sync.RWMutex
|
||||
var (
|
||||
NotificationList map[string]map[uint64]*model.Notification // [NotificationMethodTag][NotificationID] -> model.Notification
|
||||
NotificationIDToTag map[uint64]string // [NotificationID] -> NotificationTag
|
||||
notificationsLock sync.RWMutex
|
||||
)
|
||||
|
||||
// LoadNotifications 从 DB 加载通知方式到 singleton.notifications 变量
|
||||
// InitNotification 初始化 Tag <-> ID <-> Notification 的映射
|
||||
func InitNotification() {
|
||||
NotificationList = make(map[string]map[uint64]*model.Notification)
|
||||
NotificationIDToTag = make(map[uint64]string)
|
||||
}
|
||||
|
||||
// LoadNotifications 从 DB 初始化通知方式相关参数
|
||||
func LoadNotifications() {
|
||||
InitNotification()
|
||||
notificationsLock.Lock()
|
||||
defer notificationsLock.Unlock()
|
||||
|
||||
var notifications []model.Notification
|
||||
if err := DB.Find(¬ifications).Error; err != nil {
|
||||
panic(err)
|
||||
}
|
||||
notificationsLock.Unlock()
|
||||
for _, n := range notifications {
|
||||
// 旧版本的Tag可能不存在 自动设置为默认值
|
||||
if n.Tag == "" {
|
||||
SetDefaultNotificationTagInDB(&n)
|
||||
}
|
||||
AddNotificationToList(&n)
|
||||
}
|
||||
}
|
||||
|
||||
func OnRefreshOrAddNotification(n model.Notification) {
|
||||
// SetDefaultNotificationTagInDB 设置默认通知方式的 Tag
|
||||
func SetDefaultNotificationTagInDB(n *model.Notification) {
|
||||
n.Tag = "default"
|
||||
if err := DB.Save(n).Error; err != nil {
|
||||
log.Println("[ERROR]", err)
|
||||
}
|
||||
}
|
||||
|
||||
// OnRefreshOrAddNotification 刷新通知方式相关参数
|
||||
func OnRefreshOrAddNotification(n *model.Notification) {
|
||||
notificationsLock.Lock()
|
||||
defer notificationsLock.Unlock()
|
||||
|
||||
var isEdit bool
|
||||
for i := 0; i < len(notifications); i++ {
|
||||
if notifications[i].ID == n.ID {
|
||||
notifications[i] = n
|
||||
isEdit = true
|
||||
}
|
||||
if _, ok := NotificationList[n.Tag][n.ID]; ok {
|
||||
isEdit = true
|
||||
}
|
||||
if !isEdit {
|
||||
notifications = append(notifications, n)
|
||||
AddNotificationToList(n)
|
||||
} else {
|
||||
UpdateNotificationInList(n)
|
||||
}
|
||||
}
|
||||
|
||||
// AddNotificationToList 添加通知方式到map中
|
||||
func AddNotificationToList(n *model.Notification) {
|
||||
notificationsLock.Lock()
|
||||
defer notificationsLock.Unlock()
|
||||
|
||||
// 当前 Tag 不存在,创建对应该 Tag 的 子 map 后再添加
|
||||
if _, ok := NotificationList[n.Tag]; !ok {
|
||||
NotificationList[n.Tag] = make(map[uint64]*model.Notification)
|
||||
}
|
||||
NotificationList[n.Tag][n.ID] = n
|
||||
NotificationIDToTag[n.ID] = n.Tag
|
||||
|
||||
}
|
||||
|
||||
// UpdateNotificationInList 在 map 中更新通知方式
|
||||
func UpdateNotificationInList(n *model.Notification) {
|
||||
notificationsLock.Lock()
|
||||
defer notificationsLock.Unlock()
|
||||
|
||||
NotificationList[n.Tag][n.ID] = n
|
||||
}
|
||||
|
||||
// OnDeleteNotification 在map中删除通知方式
|
||||
func OnDeleteNotification(id uint64) {
|
||||
notificationsLock.Lock()
|
||||
defer notificationsLock.Unlock()
|
||||
for i := 0; i < len(notifications); i++ {
|
||||
if notifications[i].ID == id {
|
||||
notifications = append(notifications[:i], notifications[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
delete(NotificationList[NotificationIDToTag[id]], id)
|
||||
delete(NotificationIDToTag, id)
|
||||
}
|
||||
|
||||
func SendNotification(desc string, muteable bool) {
|
||||
if muteable {
|
||||
// SendNotification 向指定的通知方式组的所有通知方式发送通知
|
||||
func SendNotification(notificationTag string, desc string, mutable bool) {
|
||||
if mutable {
|
||||
// 通知防骚扰策略
|
||||
nID := hex.EncodeToString(md5.New().Sum([]byte(desc))) // #nosec
|
||||
var flag bool
|
||||
@@ -80,16 +129,17 @@ func SendNotification(desc string, muteable bool) {
|
||||
|
||||
if !flag {
|
||||
if Conf.Debug {
|
||||
log.Println("NEZHA>> 静音的重复通知:", desc, muteable)
|
||||
log.Println("NEZHA>> 静音的重复通知:", desc, mutable)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
// 发出通知
|
||||
// 向该通知方式组的所有通知方式发出通知
|
||||
notificationsLock.RLock()
|
||||
defer notificationsLock.RUnlock()
|
||||
for i := 0; i < len(notifications); i++ {
|
||||
if err := notifications[i].Send(desc); err != nil {
|
||||
|
||||
for _, n := range NotificationList[notificationTag] {
|
||||
if err := n.Send(desc); err != nil {
|
||||
log.Println("NEZHA>> 发送通知失败:", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user