💥 v2.0 必须更新面板,新增服务监控

This commit is contained in:
naiba
2021-01-16 00:45:49 +08:00
parent 0ce8017875
commit a41c792577
38 changed files with 1015 additions and 453 deletions

View File

@@ -20,9 +20,64 @@ func (cp *commonPage) serve() {
cr := cp.r.Group("")
cr.Use(mygin.Authorize(mygin.AuthorizeOption{}))
cr.GET("/", cp.home)
cr.GET("/service", cp.service)
cr.GET("/ws", cp.ws)
}
type ServiceItem struct {
Monitor model.Monitor
TotalUp uint64
TotalDown uint64
Delay *[30]float32
Up *[30]int
Down *[30]int
}
func (p *commonPage) service(c *gin.Context) {
var ms []model.Monitor
dao.DB.Find(&ms)
year, month, day := time.Now().Date()
today := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
var mhs []model.MonitorHistory
dao.DB.Where("created_at >= ?", today.AddDate(0, 0, -29)).Find(&mhs)
msm := make(map[uint64]*ServiceItem)
for i := 0; i < len(ms); i++ {
msm[ms[i].ID] = &ServiceItem{
Monitor: ms[i],
Delay: &[30]float32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Up: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Down: &[30]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
}
}
// 整合数据
for i := 0; i < len(mhs); i++ {
dayIndex := 29
if mhs[i].CreatedAt.Before(today) {
dayIndex = 28 - (int(today.Sub(mhs[i].CreatedAt).Hours()) / 24)
}
if mhs[i].Successful {
msm[mhs[i].MonitorID].TotalUp++
msm[mhs[i].MonitorID].Delay[dayIndex] = (msm[mhs[i].MonitorID].Delay[dayIndex]*float32(msm[mhs[i].MonitorID].Up[dayIndex]) + mhs[i].Delay) / float32(msm[mhs[i].MonitorID].Up[dayIndex]+1)
msm[mhs[i].MonitorID].Up[dayIndex]++
} else {
msm[mhs[i].MonitorID].TotalDown++
msm[mhs[i].MonitorID].Down[dayIndex]++
}
}
u, ok := c.Get(model.CtxKeyAuthorizedUser)
data := mygin.CommonEnvironment(c, gin.H{
"Title": "服务状态",
"Services": msm,
})
if ok {
data["Admin"] = u
}
c.HTML(http.StatusOK, "theme-"+dao.Conf.Site.Theme+"/service", data)
}
func (cp *commonPage) home(c *gin.Context) {
dao.ServerLock.RLock()
defer dao.ServerLock.RUnlock()

View File

@@ -13,7 +13,6 @@ import (
"github.com/naiba/nezha/service/dao"
)
// ServeWeb ..
func ServeWeb(port uint) {
gin.SetMode(gin.ReleaseMode)
if dao.Conf.Debug {
@@ -43,6 +42,35 @@ func ServeWeb(port uint) {
"ts": func(s string) string {
return strings.TrimSpace(s)
},
"divU64": func(a, b uint64) float32 {
if b == 0 {
if a > 0 {
return 100
}
return 0
}
return float32(a) / float32(b) * 100
},
"div": func(a, b int) float32 {
if b == 0 {
if a > 0 {
return 100
}
return 0
}
return float32(a) / float32(b) * 100
},
"addU64": func(a, b uint64) uint64 {
return a + b
},
"add": func(a, b int) int {
return a + b
},
"dayBefore": func(i int) string {
year, month, day := time.Now().Date()
today := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
return today.AddDate(0, 0, i-29).Format("1月2号")
},
})
r.Static("/static", "resource/static")
r.LoadHTMLGlob("resource/template/**/*")

View File

@@ -33,6 +33,7 @@ func (ma *memberAPI) serve() {
mr.POST("/logout", ma.logout)
mr.POST("/server", ma.addOrEditServer)
mr.POST("/monitor", ma.addOrEditMonitor)
mr.POST("/notification", ma.addOrEditNotification)
mr.POST("/alert-rule", ma.addOrEditAlertRule)
mr.POST("/setting", ma.updateSetting)
@@ -64,6 +65,8 @@ func (ma *memberAPI) delete(c *gin.Context) {
if err == nil {
alertmanager.OnDeleteNotification(id)
}
case "monitor":
err = dao.DB.Delete(&model.Monitor{}, "id = ?", id).Error
case "alert-rule":
err = dao.DB.Delete(&model.AlertRule{}, "id = ?", id).Error
if err == nil {
@@ -125,7 +128,7 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) {
s.State = dao.ServerList[s.ID].State
} else {
s.Host = &model.Host{}
s.State = &model.State{}
s.State = &model.HostState{}
}
dao.ServerList[s.ID] = &s
dao.ReSortServer()
@@ -134,6 +137,42 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) {
})
}
type monitorForm struct {
ID uint64
Name string
Target string
Type uint8
}
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 = mf.Target
m.Type = mf.Type
m.ID = mf.ID
}
if err == nil {
if m.ID == 0 {
err = dao.DB.Create(&m).Error
} else {
err = dao.DB.Save(&m).Error
}
}
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 notificationForm struct {
ID uint64
Name string

View File

@@ -23,6 +23,7 @@ func (mp *memberPage) serve() {
Redirect: "/login",
}))
mr.GET("/server", mp.server)
mr.GET("/monitor", mp.monitor)
mr.GET("/notification", mp.notification)
mr.GET("/setting", mp.setting)
}
@@ -36,6 +37,15 @@ func (mp *memberPage) server(c *gin.Context) {
}))
}
func (mp *memberPage) monitor(c *gin.Context) {
var monitors []model.Monitor
dao.DB.Find(&monitors)
c.HTML(http.StatusOK, "dashboard/monitor", mygin.CommonEnvironment(c, gin.H{
"Title": "服务监控",
"Monitors": monitors,
}))
}
func (mp *memberPage) notification(c *gin.Context) {
var nf []model.Notification
dao.DB.Find(&nf)