🚀 monitor api
This commit is contained in:
		
							parent
							
								
									61e755d2b9
								
							
						
					
					
						commit
						6b650169df
					
				@ -62,6 +62,11 @@ func routers(r *gin.Engine) {
 | 
			
		||||
	auth.POST("/user", commonHandler(createUser))
 | 
			
		||||
	auth.POST("/batch-delete/user", commonHandler(batchDeleteUser))
 | 
			
		||||
 | 
			
		||||
	auth.GET("/monitor", commonHandler(listMonitor))
 | 
			
		||||
	auth.POST("/monitor", commonHandler(createMonitor))
 | 
			
		||||
	auth.PATCH("/monitor/:id", commonHandler(updateMonitor))
 | 
			
		||||
	auth.POST("/batch-delete/monitor", commonHandler(batchDeleteMonitor))
 | 
			
		||||
 | 
			
		||||
	auth.POST("/server-group", commonHandler(createServerGroup))
 | 
			
		||||
	auth.PATCH("/server-group/:id", commonHandler(updateServerGroup))
 | 
			
		||||
	auth.POST("/batch-delete/server-group", commonHandler(batchDeleteServerGroup))
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,6 @@ func (ma *memberAPI) serve() {
 | 
			
		||||
	// 	Btn:        "点此登录",
 | 
			
		||||
	// 	Redirect:   "/login",
 | 
			
		||||
	// }))
 | 
			
		||||
	mr.POST("/monitor", ma.addOrEditMonitor)
 | 
			
		||||
	mr.POST("/cron", ma.addOrEditCron)
 | 
			
		||||
	mr.GET("/cron/:id/manual", ma.manualTrigger)
 | 
			
		||||
	mr.POST("/force-update", ma.forceUpdate)
 | 
			
		||||
@ -179,12 +178,7 @@ func (ma *memberAPI) delete(c *gin.Context) {
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			singleton.OnNATUpdate()
 | 
			
		||||
		}
 | 
			
		||||
	case "monitor":
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.Monitor{}, "id = ?", id).Error
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			singleton.ServiceSentinelShared.OnMonitorDelete(id)
 | 
			
		||||
			err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ?", id).Error
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	case "cron":
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.Cron{}, "id = ?", id).Error
 | 
			
		||||
		if err == nil {
 | 
			
		||||
@ -214,87 +208,6 @@ func (ma *memberAPI) delete(c *gin.Context) {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type monitorForm struct {
 | 
			
		||||
	ID     uint64
 | 
			
		||||
	Name   string
 | 
			
		||||
	Target string
 | 
			
		||||
	Type   uint8
 | 
			
		||||
	Cover  uint8
 | 
			
		||||
	Notify string
 | 
			
		||||
	//NotificationTag        string
 | 
			
		||||
	SkipServersRaw         string
 | 
			
		||||
	Duration               uint64
 | 
			
		||||
	MinLatency             float32
 | 
			
		||||
	MaxLatency             float32
 | 
			
		||||
	LatencyNotify          string
 | 
			
		||||
	EnableTriggerTask      string
 | 
			
		||||
	EnableShowInService    string
 | 
			
		||||
	FailTriggerTasksRaw    string
 | 
			
		||||
	RecoverTriggerTasksRaw string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ma *memberAPI) addOrEditMonitor(c *gin.Context) {
 | 
			
		||||
	var mf monitorForm
 | 
			
		||||
	var m model.Monitor
 | 
			
		||||
	err := c.ShouldBindJSON(&mf)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		m.Name = mf.Name
 | 
			
		||||
		m.Target = strings.TrimSpace(mf.Target)
 | 
			
		||||
		m.Type = mf.Type
 | 
			
		||||
		m.ID = mf.ID
 | 
			
		||||
		m.SkipServersRaw = mf.SkipServersRaw
 | 
			
		||||
		m.Cover = mf.Cover
 | 
			
		||||
		m.Notify = mf.Notify == "on"
 | 
			
		||||
		//m.NotificationTag = mf.NotificationTag
 | 
			
		||||
		m.Duration = mf.Duration
 | 
			
		||||
		m.LatencyNotify = mf.LatencyNotify == "on"
 | 
			
		||||
		m.MinLatency = mf.MinLatency
 | 
			
		||||
		m.MaxLatency = mf.MaxLatency
 | 
			
		||||
		m.EnableShowInService = mf.EnableShowInService == "on"
 | 
			
		||||
		m.EnableTriggerTask = mf.EnableTriggerTask == "on"
 | 
			
		||||
		m.RecoverTriggerTasksRaw = mf.RecoverTriggerTasksRaw
 | 
			
		||||
		m.FailTriggerTasksRaw = mf.FailTriggerTasksRaw
 | 
			
		||||
		err = m.InitSkipServers()
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		// 保证NotificationTag不为空
 | 
			
		||||
		//if m.NotificationTag == "" {
 | 
			
		||||
		//	m.NotificationTag = "default"
 | 
			
		||||
		//}
 | 
			
		||||
		err = utils.Json.Unmarshal([]byte(mf.FailTriggerTasksRaw), &m.FailTriggerTasks)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		err = utils.Json.Unmarshal([]byte(mf.RecoverTriggerTasksRaw), &m.RecoverTriggerTasks)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		if m.ID == 0 {
 | 
			
		||||
			err = singleton.DB.Create(&m).Error
 | 
			
		||||
		} else {
 | 
			
		||||
			err = singleton.DB.Save(&m).Error
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		if m.Cover == 0 {
 | 
			
		||||
			err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
 | 
			
		||||
		} else {
 | 
			
		||||
			err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id not in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		err = singleton.ServiceSentinelShared.OnMonitorUpdate(m)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		c.JSON(http.StatusOK, model.Response{
 | 
			
		||||
			Code:    http.StatusBadRequest,
 | 
			
		||||
			Message: fmt.Sprintf("请求错误:%s", err),
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	c.JSON(http.StatusOK, model.Response{
 | 
			
		||||
		Code: http.StatusOK,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type cronForm struct {
 | 
			
		||||
	ID              uint64
 | 
			
		||||
	TaskType        uint8 // 0:计划任务 1:触发任务
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,6 @@ func (mp *memberPage) serve() {
 | 
			
		||||
	// 	// Btn:        singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
 | 
			
		||||
	// 	Redirect: "/login",
 | 
			
		||||
	// }))
 | 
			
		||||
	mr.GET("/server", mp.server)
 | 
			
		||||
	mr.GET("/monitor", mp.monitor)
 | 
			
		||||
	mr.GET("/cron", mp.cron)
 | 
			
		||||
	mr.GET("/notification", mp.notification)
 | 
			
		||||
	mr.GET("/ddns", mp.ddns)
 | 
			
		||||
@ -40,22 +38,6 @@ func (mp *memberPage) api(c *gin.Context) {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mp *memberPage) server(c *gin.Context) {
 | 
			
		||||
	singleton.SortedServerLock.RLock()
 | 
			
		||||
	defer singleton.SortedServerLock.RUnlock()
 | 
			
		||||
	c.HTML(http.StatusOK, "dashboard-", gin.H{
 | 
			
		||||
		// "Title":   singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}),
 | 
			
		||||
		"Servers": singleton.SortedServerList,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mp *memberPage) monitor(c *gin.Context) {
 | 
			
		||||
	c.HTML(http.StatusOK, "dashboard-", gin.H{
 | 
			
		||||
		// "Title":    singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}),
 | 
			
		||||
		"Monitors": singleton.ServiceSentinelShared.Monitors(),
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mp *memberPage) cron(c *gin.Context) {
 | 
			
		||||
	var crons []model.Cron
 | 
			
		||||
	singleton.DB.Find(&crons)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										173
									
								
								cmd/dashboard/controller/monitor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								cmd/dashboard/controller/monitor.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,173 @@
 | 
			
		||||
package controller
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/naiba/nezha/model"
 | 
			
		||||
	"github.com/naiba/nezha/service/singleton"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// List monitor
 | 
			
		||||
// @Summary List monitor
 | 
			
		||||
// @Security BearerAuth
 | 
			
		||||
// @Schemes
 | 
			
		||||
// @Description List monitor
 | 
			
		||||
// @Tags auth required
 | 
			
		||||
// @Produce json
 | 
			
		||||
// @Success 200 {object} model.CommonResponse[[]model.Monitor]
 | 
			
		||||
// @Router /monitor [get]
 | 
			
		||||
func listMonitor(c *gin.Context) ([]*model.Monitor, error) {
 | 
			
		||||
	return singleton.ServiceSentinelShared.Monitors(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create monitor
 | 
			
		||||
// @Summary Create monitor
 | 
			
		||||
// @Security BearerAuth
 | 
			
		||||
// @Schemes
 | 
			
		||||
// @Description Create monitor
 | 
			
		||||
// @Tags auth required
 | 
			
		||||
// @Accept json
 | 
			
		||||
// @param request body model.MonitorForm true "Monitor Request"
 | 
			
		||||
// @Produce json
 | 
			
		||||
// @Success 200 {object} model.CommonResponse[uint64]
 | 
			
		||||
// @Router /monitor [post]
 | 
			
		||||
func createMonitor(c *gin.Context) (uint64, error) {
 | 
			
		||||
	var mf model.MonitorForm
 | 
			
		||||
	if err := c.ShouldBindJSON(&mf); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var m model.Monitor
 | 
			
		||||
	m.Name = mf.Name
 | 
			
		||||
	m.Target = strings.TrimSpace(mf.Target)
 | 
			
		||||
	m.Type = mf.Type
 | 
			
		||||
	m.SkipServers = mf.SkipServers
 | 
			
		||||
	m.Cover = mf.Cover
 | 
			
		||||
	m.Notify = mf.Notify
 | 
			
		||||
	m.NotificationGroupID = mf.NotificationGroupID
 | 
			
		||||
	m.Duration = mf.Duration
 | 
			
		||||
	m.LatencyNotify = mf.LatencyNotify
 | 
			
		||||
	m.MinLatency = mf.MinLatency
 | 
			
		||||
	m.MaxLatency = mf.MaxLatency
 | 
			
		||||
	m.EnableShowInService = mf.EnableShowInService
 | 
			
		||||
	m.EnableTriggerTask = mf.EnableTriggerTask
 | 
			
		||||
	m.RecoverTriggerTasks = mf.RecoverTriggerTasks
 | 
			
		||||
	m.FailTriggerTasks = mf.FailTriggerTasks
 | 
			
		||||
 | 
			
		||||
	if err := singleton.DB.Create(&m).Error; err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var skipServers []uint64
 | 
			
		||||
	for k := range m.SkipServers {
 | 
			
		||||
		skipServers = append(skipServers, k)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	if m.Cover == 0 {
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id in (?)", m.ID, skipServers).Error
 | 
			
		||||
	} else {
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id not in (?)", m.ID, skipServers).Error
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return m.ID, singleton.ServiceSentinelShared.OnMonitorUpdate(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update monitor
 | 
			
		||||
// @Summary Update monitor
 | 
			
		||||
// @Security BearerAuth
 | 
			
		||||
// @Schemes
 | 
			
		||||
// @Description Update monitor
 | 
			
		||||
// @Tags auth required
 | 
			
		||||
// @Accept json
 | 
			
		||||
// @param id path uint true "Monitor ID"
 | 
			
		||||
// @param request body model.MonitorForm true "Monitor Request"
 | 
			
		||||
// @Produce json
 | 
			
		||||
// @Success 200 {object} model.CommonResponse[any]
 | 
			
		||||
// @Router /monitor/{id} [patch]
 | 
			
		||||
func updateMonitor(c *gin.Context) (any, error) {
 | 
			
		||||
	strID := c.Param("id")
 | 
			
		||||
	id, err := strconv.ParseUint(strID, 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var mf model.MonitorForm
 | 
			
		||||
	if err := c.ShouldBindJSON(&mf); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var m model.Monitor
 | 
			
		||||
	if err := singleton.DB.First(&m, id).Error; err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("monitor id %d does not exist", id)
 | 
			
		||||
	}
 | 
			
		||||
	m.Name = mf.Name
 | 
			
		||||
	m.Target = strings.TrimSpace(mf.Target)
 | 
			
		||||
	m.Type = mf.Type
 | 
			
		||||
	m.SkipServers = mf.SkipServers
 | 
			
		||||
	m.Cover = mf.Cover
 | 
			
		||||
	m.Notify = mf.Notify
 | 
			
		||||
	m.NotificationGroupID = mf.NotificationGroupID
 | 
			
		||||
	m.Duration = mf.Duration
 | 
			
		||||
	m.LatencyNotify = mf.LatencyNotify
 | 
			
		||||
	m.MinLatency = mf.MinLatency
 | 
			
		||||
	m.MaxLatency = mf.MaxLatency
 | 
			
		||||
	m.EnableShowInService = mf.EnableShowInService
 | 
			
		||||
	m.EnableTriggerTask = mf.EnableTriggerTask
 | 
			
		||||
	m.RecoverTriggerTasks = mf.RecoverTriggerTasks
 | 
			
		||||
	m.FailTriggerTasks = mf.FailTriggerTasks
 | 
			
		||||
 | 
			
		||||
	if err := singleton.DB.Save(&m).Error; err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var skipServers []uint64
 | 
			
		||||
	for k := range m.SkipServers {
 | 
			
		||||
		skipServers = append(skipServers, k)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if m.Cover == 0 {
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id in (?)", m.ID, skipServers).Error
 | 
			
		||||
	} else {
 | 
			
		||||
		err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id not in (?)", m.ID, skipServers).Error
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil, singleton.ServiceSentinelShared.OnMonitorUpdate(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Batch delete monitor
 | 
			
		||||
// @Summary Batch delete monitor
 | 
			
		||||
// @Security BearerAuth
 | 
			
		||||
// @Schemes
 | 
			
		||||
// @Description Batch delete monitor
 | 
			
		||||
// @Tags auth required
 | 
			
		||||
// @Accept json
 | 
			
		||||
// @param request body []uint true "id list"
 | 
			
		||||
// @Produce json
 | 
			
		||||
// @Success 200 {object} model.CommonResponse[any]
 | 
			
		||||
// @Router /batch-delete/monitor [post]
 | 
			
		||||
func batchDeleteMonitor(c *gin.Context) (any, error) {
 | 
			
		||||
	var ids []uint64
 | 
			
		||||
	if err := c.ShouldBindJSON(&ids); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	err := singleton.DB.Transaction(func(tx *gorm.DB) error {
 | 
			
		||||
		if err := tx.Unscoped().Delete(&model.Monitor{}, "id in (?)", ids).Error; err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return tx.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id in (?)", ids).Error
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	singleton.ServiceSentinelShared.OnMonitorDelete(ids)
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
@ -20,12 +20,10 @@ import (
 | 
			
		||||
// @Produce json
 | 
			
		||||
// @Success 200 {object} model.CommonResponse[any]
 | 
			
		||||
// @Router /server [get]
 | 
			
		||||
func listServer(c *gin.Context) ([]model.Server, error) {
 | 
			
		||||
	var servers []model.Server
 | 
			
		||||
	if err := singleton.DB.Find(&servers).Error; err != nil {
 | 
			
		||||
		return nil, newGormError("%v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return servers, nil
 | 
			
		||||
func listServer(c *gin.Context) ([]*model.Server, error) {
 | 
			
		||||
	singleton.SortedServerLock.RLock()
 | 
			
		||||
	defer singleton.SortedServerLock.RUnlock()
 | 
			
		||||
	return singleton.SortedServerList, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Edit server
 | 
			
		||||
 | 
			
		||||
@ -46,27 +46,28 @@ const (
 | 
			
		||||
 | 
			
		||||
type Monitor struct {
 | 
			
		||||
	Common
 | 
			
		||||
	Name                string
 | 
			
		||||
	Type                uint8
 | 
			
		||||
	Target              string
 | 
			
		||||
	SkipServersRaw      string
 | 
			
		||||
	Duration            uint64
 | 
			
		||||
	Notify              bool
 | 
			
		||||
	NotificationGroupID uint64 // 当前服务监控所属的通知组 ID
 | 
			
		||||
	Cover               uint8
 | 
			
		||||
	Name                string `json:"name,omitempty"`
 | 
			
		||||
	Type                uint8  `json:"type,omitempty"`
 | 
			
		||||
	Target              string `json:"target,omitempty"`
 | 
			
		||||
	SkipServersRaw      string `json:"-"`
 | 
			
		||||
	Duration            uint64 `json:"duration,omitempty"`
 | 
			
		||||
	Notify              bool   `json:"notify,omitempty"`
 | 
			
		||||
	NotificationGroupID uint64 `json:"notification_group_id,omitempty"` // 当前服务监控所属的通知组 ID
 | 
			
		||||
	Cover               uint8  `json:"cover,omitempty"`
 | 
			
		||||
 | 
			
		||||
	EnableTriggerTask      bool     `gorm:"default: false"`
 | 
			
		||||
	EnableShowInService    bool     `gorm:"default: false"`
 | 
			
		||||
	FailTriggerTasksRaw    string   `gorm:"default:'[]'"`
 | 
			
		||||
	RecoverTriggerTasksRaw string   `gorm:"default:'[]'"`
 | 
			
		||||
	FailTriggerTasks       []uint64 `gorm:"-" json:"-"` // 失败时执行的触发任务id
 | 
			
		||||
	RecoverTriggerTasks    []uint64 `gorm:"-" json:"-"` // 恢复时执行的触发任务id
 | 
			
		||||
	EnableTriggerTask      bool   `gorm:"default: false" json:"enable_trigger_task,omitempty"`
 | 
			
		||||
	EnableShowInService    bool   `gorm:"default: false" json:"enable_show_in_service,omitempty"`
 | 
			
		||||
	FailTriggerTasksRaw    string `gorm:"default:'[]'" json:"-"`
 | 
			
		||||
	RecoverTriggerTasksRaw string `gorm:"default:'[]'" json:"-"`
 | 
			
		||||
 | 
			
		||||
	MinLatency    float32
 | 
			
		||||
	MaxLatency    float32
 | 
			
		||||
	LatencyNotify bool
 | 
			
		||||
	FailTriggerTasks    []uint64 `gorm:"-" json:"fail_trigger_tasks"`    // 失败时执行的触发任务id
 | 
			
		||||
	RecoverTriggerTasks []uint64 `gorm:"-" json:"recover_trigger_tasks"` // 恢复时执行的触发任务id
 | 
			
		||||
 | 
			
		||||
	SkipServers map[uint64]bool `gorm:"-" json:"-"`
 | 
			
		||||
	MinLatency    float32 `json:"min_latency,omitempty"`
 | 
			
		||||
	MaxLatency    float32 `json:"max_latency,omitempty"`
 | 
			
		||||
	LatencyNotify bool    `json:"latency_notify,omitempty"`
 | 
			
		||||
 | 
			
		||||
	SkipServers map[uint64]bool `gorm:"-" json:"skip_servers"`
 | 
			
		||||
	CronJobID   cron.EntryID    `gorm:"-" json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -88,7 +89,11 @@ func (m *Monitor) CronSpec() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Monitor) BeforeSave(tx *gorm.DB) error {
 | 
			
		||||
 | 
			
		||||
	if data, err := utils.Json.Marshal(m.SkipServers); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	} else {
 | 
			
		||||
		m.SkipServersRaw = string(data)
 | 
			
		||||
	}
 | 
			
		||||
	if data, err := utils.Json.Marshal(m.FailTriggerTasks); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	} else {
 | 
			
		||||
@ -104,14 +109,10 @@ func (m *Monitor) BeforeSave(tx *gorm.DB) error {
 | 
			
		||||
 | 
			
		||||
func (m *Monitor) AfterFind(tx *gorm.DB) error {
 | 
			
		||||
	m.SkipServers = make(map[uint64]bool)
 | 
			
		||||
	var skipServers []uint64
 | 
			
		||||
	if err := utils.Json.Unmarshal([]byte(m.SkipServersRaw), &skipServers); err != nil {
 | 
			
		||||
	if err := utils.Json.Unmarshal([]byte(m.SkipServersRaw), &m.SkipServers); err != nil {
 | 
			
		||||
		log.Println("NEZHA>> Monitor.AfterFind:", err)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < len(skipServers); i++ {
 | 
			
		||||
		m.SkipServers[skipServers[i]] = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 加载触发任务列表
 | 
			
		||||
	if err := utils.Json.Unmarshal([]byte(m.FailTriggerTasksRaw), &m.FailTriggerTasks); err != nil {
 | 
			
		||||
@ -128,15 +129,3 @@ func (m *Monitor) AfterFind(tx *gorm.DB) error {
 | 
			
		||||
func IsServiceSentinelNeeded(t uint64) bool {
 | 
			
		||||
	return t != TaskTypeCommand && t != TaskTypeTerminalGRPC && t != TaskTypeUpgrade
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Monitor) InitSkipServers() error {
 | 
			
		||||
	var skipServers []uint64
 | 
			
		||||
	if err := utils.Json.Unmarshal([]byte(m.SkipServersRaw), &skipServers); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	m.SkipServers = make(map[uint64]bool)
 | 
			
		||||
	for i := 0; i < len(skipServers); i++ {
 | 
			
		||||
		m.SkipServers[skipServers[i]] = true
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								model/monitor_api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								model/monitor_api.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
type MonitorForm struct {
 | 
			
		||||
	Name                string          `json:"name,omitempty"`
 | 
			
		||||
	Target              string          `json:"target,omitempty"`
 | 
			
		||||
	Type                uint8           `json:"type,omitempty"`
 | 
			
		||||
	Cover               uint8           `json:"cover,omitempty"`
 | 
			
		||||
	Notify              bool            `json:"notify,omitempty"`
 | 
			
		||||
	Duration            uint64          `json:"duration,omitempty"`
 | 
			
		||||
	MinLatency          float32         `json:"min_latency,omitempty"`
 | 
			
		||||
	MaxLatency          float32         `json:"max_latency,omitempty"`
 | 
			
		||||
	LatencyNotify       bool            `json:"latency_notify,omitempty"`
 | 
			
		||||
	EnableTriggerTask   bool            `json:"enable_trigger_task,omitempty"`
 | 
			
		||||
	EnableShowInService bool            `json:"enable_show_in_service,omitempty"`
 | 
			
		||||
	FailTriggerTasks    []uint64        `json:"fail_trigger_tasks,omitempty"`
 | 
			
		||||
	RecoverTriggerTasks []uint64        `json:"recover_trigger_tasks,omitempty"`
 | 
			
		||||
	SkipServers         map[uint64]bool `json:"skip_servers,omitempty"`
 | 
			
		||||
	NotificationGroupID uint64          `json:"notification_group_id,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
@ -264,7 +264,7 @@ func (ss *ServiceSentinel) OnMonitorUpdate(m model.Monitor) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss *ServiceSentinel) OnMonitorDelete(id uint64) {
 | 
			
		||||
func (ss *ServiceSentinel) OnMonitorDelete(ids []uint64) {
 | 
			
		||||
	ss.serviceResponseDataStoreLock.Lock()
 | 
			
		||||
	defer ss.serviceResponseDataStoreLock.Unlock()
 | 
			
		||||
	ss.monthlyStatusLock.Lock()
 | 
			
		||||
@ -272,20 +272,22 @@ func (ss *ServiceSentinel) OnMonitorDelete(id uint64) {
 | 
			
		||||
	ss.monitorsLock.Lock()
 | 
			
		||||
	defer ss.monitorsLock.Unlock()
 | 
			
		||||
 | 
			
		||||
	delete(ss.serviceCurrentStatusIndex, id)
 | 
			
		||||
	delete(ss.serviceCurrentStatusData, id)
 | 
			
		||||
	delete(ss.lastStatus, id)
 | 
			
		||||
	delete(ss.serviceResponseDataStoreCurrentUp, id)
 | 
			
		||||
	delete(ss.serviceResponseDataStoreCurrentDown, id)
 | 
			
		||||
	delete(ss.serviceResponseDataStoreCurrentAvgDelay, id)
 | 
			
		||||
	delete(ss.sslCertCache, id)
 | 
			
		||||
	delete(ss.serviceStatusToday, id)
 | 
			
		||||
	for _, id := range ids {
 | 
			
		||||
		delete(ss.serviceCurrentStatusIndex, id)
 | 
			
		||||
		delete(ss.serviceCurrentStatusData, id)
 | 
			
		||||
		delete(ss.lastStatus, id)
 | 
			
		||||
		delete(ss.serviceResponseDataStoreCurrentUp, id)
 | 
			
		||||
		delete(ss.serviceResponseDataStoreCurrentDown, id)
 | 
			
		||||
		delete(ss.serviceResponseDataStoreCurrentAvgDelay, id)
 | 
			
		||||
		delete(ss.sslCertCache, id)
 | 
			
		||||
		delete(ss.serviceStatusToday, id)
 | 
			
		||||
 | 
			
		||||
	// 停掉定时任务
 | 
			
		||||
	Cron.Remove(ss.monitors[id].CronJobID)
 | 
			
		||||
	delete(ss.monitors, id)
 | 
			
		||||
		// 停掉定时任务
 | 
			
		||||
		Cron.Remove(ss.monitors[id].CronJobID)
 | 
			
		||||
		delete(ss.monitors, id)
 | 
			
		||||
 | 
			
		||||
	delete(ss.monthlyStatus, id)
 | 
			
		||||
		delete(ss.monthlyStatus, id)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceItemResponse {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user