mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 12:48:14 -05:00
🚀 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…
Reference in New Issue
Block a user