diff --git a/README.md b/README.md
index c2defc1..7281768 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
LOGO designed by 熊大 .
-
+
:trollface: 哪吒监控 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,计划任务和在线终端。
diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 126f0d1..88b54e4 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -211,14 +211,15 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) { } type monitorForm struct { - ID uint64 - Name string - Target string - Type uint8 - Cover uint8 - Notify string - SkipServersRaw string - Duration uint64 + ID uint64 + Name string + Target string + Type uint8 + Cover uint8 + Notify string + NotificationTag string + SkipServersRaw string + Duration uint64 } func (ma *memberAPI) addOrEditMonitor(c *gin.Context) { @@ -233,10 +234,15 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) { m.SkipServersRaw = mf.SkipServersRaw m.Cover = mf.Cover m.Notify = mf.Notify == "on" + m.NotificationTag = mf.NotificationTag m.Duration = mf.Duration err = m.InitSkipServers() } if err == nil { + // 保证NotificationTag不为空 + if m.NotificationTag == "" { + m.NotificationTag = "default" + } if m.ID == 0 { err = singleton.DB.Create(&m).Error } else { @@ -259,13 +265,14 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) { } type cronForm struct { - ID uint64 - Name string - Scheduler string - Command string - ServersRaw string - Cover uint8 - PushSuccessful string + ID uint64 + Name string + Scheduler string + Command string + ServersRaw string + Cover uint8 + PushSuccessful string + NotificationTag string } func (ma *memberAPI) addOrEditCron(c *gin.Context) { @@ -278,12 +285,17 @@ func (ma *memberAPI) addOrEditCron(c *gin.Context) { cr.Command = cf.Command cr.ServersRaw = cf.ServersRaw cr.PushSuccessful = cf.PushSuccessful == "on" + cr.NotificationTag = cf.NotificationTag cr.ID = cf.ID cr.Cover = cf.Cover err = utils.Json.Unmarshal([]byte(cf.ServersRaw), &cr.Servers) } tx := singleton.DB.Begin() if err == nil { + // 保证NotificationTag不为空 + if cr.NotificationTag == "" { + cr.NotificationTag = "default" + } if cf.ID == 0 { err = tx.Create(&cr).Error } else { @@ -376,6 +388,7 @@ func (ma *memberAPI) forceUpdate(c *gin.Context) { type notificationForm struct { ID uint64 Name string + Tag string // 分组名 URL string RequestMethod int RequestType int @@ -390,6 +403,7 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) { err := c.ShouldBindJSON(&nf) if err == nil { n.Name = nf.Name + n.Tag = nf.Tag n.RequestMethod = nf.RequestMethod n.RequestType = nf.RequestType n.RequestHeader = nf.RequestHeader @@ -401,6 +415,10 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) { err = n.Send("这是测试消息") } if err == nil { + // 保证Tag不为空 + if n.Tag == "" { + n.Tag = "default" + } if n.ID == 0 { err = singleton.DB.Create(&n).Error } else { @@ -414,17 +432,18 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) { }) return } - singleton.OnRefreshOrAddNotification(n) + singleton.OnRefreshOrAddNotification(&n) c.JSON(http.StatusOK, model.Response{ Code: http.StatusOK, }) } type alertRuleForm struct { - ID uint64 - Name string - RulesRaw string - Enable string + ID uint64 + Name string + RulesRaw string + NotificationTag string + Enable string } func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) { @@ -464,9 +483,14 @@ func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) { if err == nil { r.Name = arf.Name r.RulesRaw = arf.RulesRaw + r.NotificationTag = arf.NotificationTag enable := arf.Enable == "on" r.Enable = &enable r.ID = arf.ID + //保证NotificationTag不为空 + if r.NotificationTag == "" { + r.NotificationTag = "default" + } if r.ID == 0 { err = singleton.DB.Create(&r).Error } else { @@ -517,14 +541,15 @@ func (ma *memberAPI) logout(c *gin.Context) { } type settingForm struct { - Title string - Admin string - Theme string - CustomCode string - ViewPassword string - IgnoredIPNotification string - GRPCHost string - Cover uint8 + Title string + Admin string + Theme string + CustomCode string + ViewPassword string + IgnoredIPNotification string + IPChangeNotificationTag string // IP变更提醒的通知组 + GRPCHost string + Cover uint8 EnableIPChangeNotification string EnablePlainIPInNotification string @@ -544,11 +569,16 @@ func (ma *memberAPI) updateSetting(c *gin.Context) { singleton.Conf.Cover = sf.Cover singleton.Conf.GRPCHost = sf.GRPCHost singleton.Conf.IgnoredIPNotification = sf.IgnoredIPNotification + singleton.Conf.IPChangeNotificationTag = sf.IPChangeNotificationTag singleton.Conf.Site.Brand = sf.Title singleton.Conf.Site.Theme = sf.Theme singleton.Conf.Site.CustomCode = sf.CustomCode singleton.Conf.Site.ViewPassword = sf.ViewPassword singleton.Conf.Oauth2.Admin = sf.Admin + // 保证NotificationTag不为空 + if singleton.Conf.IPChangeNotificationTag == "" { + singleton.Conf.IPChangeNotificationTag = "default" + } if err := singleton.Conf.Save(); err != nil { c.JSON(http.StatusOK, model.Response{ Code: http.StatusBadRequest, diff --git a/model/alertrule.go b/model/alertrule.go index 321480d..032e616 100644 --- a/model/alertrule.go +++ b/model/alertrule.go @@ -20,10 +20,11 @@ type CycleTransferStats struct { type AlertRule struct { Common - Name string - RulesRaw string - Enable *bool - Rules []Rule `gorm:"-" json:"-"` + Name string + RulesRaw string + Enable *bool + NotificationTag string // 该报警规则所在的通知组 + Rules []Rule `gorm:"-" json:"-"` } func (r *AlertRule) BeforeSave(tx *gorm.DB) error { diff --git a/model/config.go b/model/config.go index e7cf6b7..e509104 100644 --- a/model/config.go +++ b/model/config.go @@ -71,12 +71,13 @@ type Config struct { ProxyGRPCPort uint TLS bool - EnableIPChangeNotification bool - EnablePlainIPInNotification bool + EnablePlainIPInNotification bool // 通知信息IP不打码 // IP变更提醒 - Cover uint8 // 覆盖范围(0:提醒未被 IgnoredIPNotification 包含的所有服务器; 1:仅提醒被 IgnoredIPNotification 包含的服务器;) - IgnoredIPNotification string // 特定服务器IP(多个服务器用逗号分隔) + EnableIPChangeNotification bool + IPChangeNotificationTag string + Cover uint8 // 覆盖范围(0:提醒未被 IgnoredIPNotification 包含的所有服务器; 1:仅提醒被 IgnoredIPNotification 包含的服务器;) + IgnoredIPNotification string // 特定服务器IP(多个服务器用逗号分隔) v *viper.Viper IgnoredIPNotificationServerIDs map[uint64]bool // [ServerID] -> bool(值为true代表当前ServerID在特定服务器列表内) @@ -102,6 +103,9 @@ func (c *Config) Read(path string) error { if c.GRPCPort == 0 { c.GRPCPort = 5555 } + if c.EnableIPChangeNotification && c.IPChangeNotificationTag == "" { + c.IPChangeNotificationTag = "default" + } c.updateIgnoredIPNotificationID() return nil diff --git a/model/cron.go b/model/cron.go index fbdf75a..a8e756c 100644 --- a/model/cron.go +++ b/model/cron.go @@ -15,14 +15,15 @@ const ( type Cron struct { Common - Name string - Scheduler string //分钟 小时 天 月 星期 - Command string - Servers []uint64 `gorm:"-"` - PushSuccessful bool // 推送成功的通知 - LastExecutedAt time.Time // 最后一次执行时间 - LastResult bool // 最后一次执行结果 - Cover uint8 // 计划任务覆盖范围 (0:仅覆盖特定服务器 1:仅忽略特定服务器) + Name string + Scheduler string //分钟 小时 天 月 星期 + Command string + Servers []uint64 `gorm:"-"` + PushSuccessful bool // 推送成功的通知 + NotificationTag string // 指定通知方式的分组 + LastExecutedAt time.Time // 最后一次执行时间 + LastResult bool // 最后一次执行结果 + Cover uint8 // 计划任务覆盖范围 (0:仅覆盖特定服务器 1:仅忽略特定服务器) CronJobID cron.EntryID `gorm:"-"` ServersRaw string diff --git a/model/monitor.go b/model/monitor.go index 309de37..0230eeb 100644 --- a/model/monitor.go +++ b/model/monitor.go @@ -38,13 +38,14 @@ const ( type Monitor struct { Common - Name string - Type uint8 - Target string - SkipServersRaw string - Duration uint64 - Notify bool - Cover uint8 + Name string + Type uint8 + Target string + SkipServersRaw string + Duration uint64 + Notify bool + NotificationTag string // 当前服务监控所属的通知组 + Cover uint8 SkipServers map[uint64]bool `gorm:"-" json:"-"` CronJobID cron.EntryID `gorm:"-" json:"-"` diff --git a/model/notification.go b/model/notification.go index 3ea2a9e..fcbfb56 100644 --- a/model/notification.go +++ b/model/notification.go @@ -28,6 +28,7 @@ const ( type Notification struct { Common Name string + Tag string // 分组名 URL string RequestMethod int RequestType int diff --git a/resource/static/main.js b/resource/static/main.js index c185373..55be2a3 100644 --- a/resource/static/main.js +++ b/resource/static/main.js @@ -114,6 +114,7 @@ function addOrEditAlertRule(rule) { modal.find("input[name=ID]").val(rule ? rule.ID : null); modal.find("input[name=Name]").val(rule ? rule.Name : null); modal.find("textarea[name=RulesRaw]").val(rule ? rule.RulesRaw : null); + modal.find("input[name=NotificationTag]").val(rule ? rule.NotificationTag : null); if (rule && rule.Enable) { modal.find(".ui.rule-enable.checkbox").checkbox("set checked"); } else { @@ -134,6 +135,7 @@ function addOrEditNotification(notification) { ); modal.find("input[name=ID]").val(notification ? notification.ID : null); modal.find("input[name=Name]").val(notification ? notification.Name : null); + modal.find("input[name=Tag]").val(notification ? notification.Tag : null); modal.find("input[name=URL]").val(notification ? notification.URL : null); modal .find("textarea[name=RequestHeader]") @@ -225,6 +227,7 @@ function addOrEditMonitor(monitor) { modal.find("input[name=Duration]").val(monitor && monitor.Duration ? monitor.Duration : 30); modal.find("select[name=Type]").val(monitor ? monitor.Type : 1); modal.find("select[name=Cover]").val(monitor ? monitor.Cover : 0); + modal.find("input[name=NotificationTag]").val(monitor ? monitor.NotificationTag : null); if (monitor && monitor.Notify) { modal.find(".ui.nb-notify.checkbox").checkbox("set checked"); } else { @@ -261,6 +264,7 @@ function addOrEditCron(cron) { ); modal.find("input[name=ID]").val(cron ? cron.ID : null); modal.find("input[name=Name]").val(cron ? cron.Name : null); + modal.find("input[name=NotificationTag]").val(cron ? cron.NotificationTag : null); modal.find("input[name=Scheduler]").val(cron ? cron.Scheduler : null); modal.find("a.ui.label.visible").each((i, el) => { el.remove(); diff --git a/resource/template/component/cron.html b/resource/template/component/cron.html index 3ee3da8..0b71952 100644 --- a/resource/template/component/cron.html +++ b/resource/template/component/cron.html @@ -32,6 +32,10 @@ +