v0.6.1 优化CSS、服务报警、服务状态展示
This commit is contained in:
parent
114f47cb0f
commit
d3c3e55c88
@ -1,7 +1,7 @@
|
|||||||
<div align="center" style="background-color: white">
|
<div align="center" style="background-color: white">
|
||||||
<img width="500" style="max-width:100%" src="https://raw.githubusercontent.com/naiba/nezha/master/resource/static/brand.png" title="哪吒监控">
|
<img width="500" style="max-width:100%" src="https://raw.githubusercontent.com/naiba/nezha/master/resource/static/brand.png" title="哪吒监控">
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.5.1&logo=github&style=for-the-badge"> <img src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/workflow/status/naiba/nezha/Agent%20release?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.4.10-brightgreen?style=for-the-badge&logo=linux">
|
<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.6.1&logo=github&style=for-the-badge"> <img src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/workflow/status/naiba/nezha/Agent%20release?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.4.10-brightgreen?style=for-the-badge&logo=linux">
|
||||||
<br>
|
<br>
|
||||||
<p>:trollface: 哪吒监控 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,命令批量执行和计划任务。</p>
|
<p>:trollface: 哪吒监控 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,命令批量执行和计划任务。</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +54,7 @@ func ServeWeb(port uint) {
|
|||||||
}
|
}
|
||||||
if a == 0 {
|
if a == 0 {
|
||||||
// 这是从未在线的情况
|
// 这是从未在线的情况
|
||||||
return 1 / float32(b) * 100
|
return 0.00001 / float32(b) * 100
|
||||||
}
|
}
|
||||||
return float32(a) / float32(b) * 100
|
return float32(a) / float32(b) * 100
|
||||||
},
|
},
|
||||||
@ -67,7 +67,7 @@ func ServeWeb(port uint) {
|
|||||||
}
|
}
|
||||||
if a == 0 {
|
if a == 0 {
|
||||||
// 这是从未在线的情况
|
// 这是从未在线的情况
|
||||||
return 1 / float32(b) * 100
|
return 0.00001 / float32(b) * 100
|
||||||
}
|
}
|
||||||
return float32(a) / float32(b) * 100
|
return float32(a) / float32(b) * 100
|
||||||
},
|
},
|
||||||
|
@ -110,6 +110,6 @@ func loadCrons() {
|
|||||||
func main() {
|
func main() {
|
||||||
go controller.ServeWeb(dao.Conf.HTTPPort)
|
go controller.ServeWeb(dao.Conf.HTTPPort)
|
||||||
go rpc.ServeRPC(dao.Conf.GRPCPort)
|
go rpc.ServeRPC(dao.Conf.GRPCPort)
|
||||||
go rpc.DispatchTask(time.Minute * 3)
|
go rpc.DispatchTask(time.Second * 30)
|
||||||
dao.AlertSentinelStart()
|
dao.AlertSentinelStart()
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/genkiroid/cert"
|
||||||
"github.com/go-ping/ping"
|
"github.com/go-ping/ping"
|
||||||
"github.com/naiba/nezha/pkg/utils"
|
"github.com/naiba/nezha/pkg/utils"
|
||||||
"github.com/shirou/gopsutil/v3/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
@ -20,8 +21,8 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
// icmp()
|
// icmp()
|
||||||
// tcpping()
|
// tcpping()
|
||||||
// httpWithSSLInfo()
|
httpWithSSLInfo()
|
||||||
sysinfo()
|
// sysinfo()
|
||||||
// cmdExec()
|
// cmdExec()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +73,12 @@ func httpWithSSLInfo() {
|
|||||||
httpClient := &http.Client{Transport: transCfg, CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
httpClient := &http.Client{Transport: transCfg, CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||||
return http.ErrUseLastResponse
|
return http.ErrUseLastResponse
|
||||||
}}
|
}}
|
||||||
resp, err := httpClient.Get("http://mail.nai.ba")
|
url := "https://ops.naibahq.com"
|
||||||
fmt.Println(err, resp.StatusCode)
|
resp, err := httpClient.Get(url)
|
||||||
|
fmt.Println(err, resp)
|
||||||
// SSL 证书信息获取
|
// SSL 证书信息获取
|
||||||
// c := cert.NewCert("expired-ecc-dv.ssl.com")
|
c := cert.NewCert(url[8:])
|
||||||
// fmt.Println(c.Error)
|
fmt.Println(c.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func icmp() {
|
func icmp() {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
.nb-container {
|
.nb-container {
|
||||||
padding-top: 75px;
|
padding-top: 75px;
|
||||||
min-height: 100%;
|
min-height: 100vh;
|
||||||
padding-bottom: 55px;
|
padding-bottom: 55px;
|
||||||
margin-bottom: -47px;
|
margin-bottom: -47px;
|
||||||
}
|
}
|
||||||
|
2
resource/template/common/header.html
vendored
2
resource/template/common/header.html
vendored
@ -9,7 +9,7 @@
|
|||||||
<title>{{.Title}}</title>
|
<title>{{.Title}}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/semantic-ui-alerts.min.css">
|
<link rel="stylesheet" type="text/css" href="/static/semantic-ui-alerts.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/main.css?v202102051040">
|
<link rel="stylesheet" type="text/css" href="/static/main.css?v202104192145">
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/logo.png?v20210320" />
|
<link rel="shortcut icon" type="image/png" href="/static/logo.png?v20210320" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
2
resource/template/common/menu.html
vendored
2
resource/template/common/menu.html
vendored
@ -14,7 +14,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a class='item{{if eq .MatchedPath "/"}} active{{end}}' href="/"><i class="home icon"></i>首页</a>
|
<a class='item{{if eq .MatchedPath "/"}} active{{end}}' href="/"><i class="home icon"></i>首页</a>
|
||||||
<a class='item{{if eq .MatchedPath "/service"}} active{{end}}' href="/service"><i class="rss icon"></i>服务状态</a>
|
<a class='item{{if eq .MatchedPath "/service"}} active{{end}}' href="/service"><i class="rss icon"></i>服务</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="right menu">
|
<div class="right menu">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
pb "github.com/naiba/nezha/proto"
|
pb "github.com/naiba/nezha/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "v0.5.1" // !!记得修改 README 重的 badge 版本!!
|
var Version = "v0.6.1" // !!记得修改 README 重的 badge 版本!!
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SnapshotDelay = 3
|
SnapshotDelay = 3
|
||||||
|
@ -15,15 +15,22 @@ var ServiceSentinelShared *ServiceSentinel
|
|||||||
|
|
||||||
func NewServiceSentinel() {
|
func NewServiceSentinel() {
|
||||||
ServiceSentinelShared = &ServiceSentinel{
|
ServiceSentinelShared = &ServiceSentinel{
|
||||||
serviceResponseChannel: make(chan *pb.TaskResult, 200),
|
serviceResponseChannel: make(chan *pb.TaskResult, 200),
|
||||||
serviceResponseDataStoreToday: make(map[uint64][]model.MonitorHistory),
|
serviceResponseDataStoreTodaySavedIndex: make(map[uint64]int),
|
||||||
lastStatus: make(map[uint64]string),
|
serviceCurrentStatusIndex: make(map[uint64]int),
|
||||||
serviceResponseDataStoreCurrentUp: make(map[uint64]uint64),
|
serviceCurrentStatusData: make(map[uint64][]model.MonitorHistory),
|
||||||
serviceResponseDataStoreCurrentDown: make(map[uint64]uint64),
|
serviceResponseDataStoreTodayLastSave: make(map[uint64]time.Time),
|
||||||
monitors: make(map[uint64]model.Monitor),
|
latestDate: make(map[uint64]string),
|
||||||
latestDate: time.Now().Format("02-Jan-06"),
|
lastStatus: make(map[uint64]string),
|
||||||
|
serviceResponseDataStoreCurrentUp: make(map[uint64]uint64),
|
||||||
|
serviceResponseDataStoreCurrentDown: make(map[uint64]uint64),
|
||||||
|
monitors: make(map[uint64]model.Monitor),
|
||||||
|
serviceResponseDataStoreToday: make(map[uint64][]model.MonitorHistory),
|
||||||
}
|
}
|
||||||
ServiceSentinelShared.OnMonitorUpdate()
|
ServiceSentinelShared.OnMonitorUpdate()
|
||||||
|
for k := range ServiceSentinelShared.monitors {
|
||||||
|
ServiceSentinelShared.latestDate[k] = time.Now().Format("02-Jan-06")
|
||||||
|
}
|
||||||
go ServiceSentinelShared.worker()
|
go ServiceSentinelShared.worker()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,17 +39,19 @@ func NewServiceSentinel() {
|
|||||||
需要记录上一次的状态信息
|
需要记录上一次的状态信息
|
||||||
*/
|
*/
|
||||||
type ServiceSentinel struct {
|
type ServiceSentinel struct {
|
||||||
latestDate string
|
|
||||||
serviceResponseDataStoreTodaySavedIndex int
|
|
||||||
serviceResponseDataStoreTodayLastSave time.Time
|
|
||||||
serviceResponseDataStoreLock sync.RWMutex
|
serviceResponseDataStoreLock sync.RWMutex
|
||||||
monitorsLock sync.RWMutex
|
monitorsLock sync.RWMutex
|
||||||
serviceResponseChannel chan *pb.TaskResult
|
serviceResponseChannel chan *pb.TaskResult
|
||||||
|
serviceResponseDataStoreTodaySavedIndex map[uint64]int
|
||||||
|
serviceCurrentStatusIndex map[uint64]int
|
||||||
|
serviceCurrentStatusData map[uint64][]model.MonitorHistory
|
||||||
|
serviceResponseDataStoreTodayLastSave map[uint64]time.Time
|
||||||
|
latestDate map[uint64]string
|
||||||
lastStatus map[uint64]string
|
lastStatus map[uint64]string
|
||||||
monitors map[uint64]model.Monitor
|
|
||||||
serviceResponseDataStoreToday map[uint64][]model.MonitorHistory
|
|
||||||
serviceResponseDataStoreCurrentUp map[uint64]uint64
|
serviceResponseDataStoreCurrentUp map[uint64]uint64
|
||||||
serviceResponseDataStoreCurrentDown map[uint64]uint64
|
serviceResponseDataStoreCurrentDown map[uint64]uint64
|
||||||
|
monitors map[uint64]model.Monitor
|
||||||
|
serviceResponseDataStoreToday map[uint64][]model.MonitorHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *ServiceSentinel) Dispatch(r *pb.TaskResult) {
|
func (ss *ServiceSentinel) Dispatch(r *pb.TaskResult) {
|
||||||
@ -67,19 +76,28 @@ func (ss *ServiceSentinel) OnMonitorUpdate() {
|
|||||||
ss.monitors = make(map[uint64]model.Monitor)
|
ss.monitors = make(map[uint64]model.Monitor)
|
||||||
for i := 0; i < len(monitors); i++ {
|
for i := 0; i < len(monitors); i++ {
|
||||||
ss.monitors[monitors[i].ID] = monitors[i]
|
ss.monitors[monitors[i].ID] = monitors[i]
|
||||||
|
if len(ss.serviceCurrentStatusData[monitors[i].ID]) == 0 {
|
||||||
|
ss.serviceCurrentStatusData[monitors[i].ID] = make([]model.MonitorHistory, 20)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *ServiceSentinel) OnMonitorDelete(id uint64) {
|
func (ss *ServiceSentinel) OnMonitorDelete(id uint64) {
|
||||||
ss.serviceResponseDataStoreLock.Lock()
|
ss.serviceResponseDataStoreLock.Lock()
|
||||||
defer ss.serviceResponseDataStoreLock.Unlock()
|
defer ss.serviceResponseDataStoreLock.Unlock()
|
||||||
delete(ss.serviceResponseDataStoreCurrentDown, id)
|
delete(ss.serviceResponseDataStoreTodaySavedIndex, id)
|
||||||
delete(ss.serviceResponseDataStoreCurrentUp, id)
|
delete(ss.serviceCurrentStatusIndex, id)
|
||||||
delete(ss.serviceResponseDataStoreToday, id)
|
delete(ss.serviceCurrentStatusData, id)
|
||||||
|
delete(ss.serviceResponseDataStoreTodayLastSave, id)
|
||||||
|
delete(ss.latestDate, id)
|
||||||
delete(ss.lastStatus, id)
|
delete(ss.lastStatus, id)
|
||||||
|
delete(ss.serviceResponseDataStoreCurrentUp, id)
|
||||||
|
delete(ss.serviceResponseDataStoreCurrentDown, id)
|
||||||
|
delete(ss.serviceResponseDataStoreToday, id)
|
||||||
ss.monitorsLock.Lock()
|
ss.monitorsLock.Lock()
|
||||||
defer ss.monitorsLock.Unlock()
|
defer ss.monitorsLock.Unlock()
|
||||||
delete(ss.monitors, id)
|
delete(ss.monitors, id)
|
||||||
|
Cache.Delete(model.CacheKeyServicePage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceItemResponse {
|
func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceItemResponse {
|
||||||
@ -124,11 +142,16 @@ func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceItemResponse {
|
|||||||
// 最新一天的数据
|
// 最新一天的数据
|
||||||
ss.serviceResponseDataStoreLock.RLock()
|
ss.serviceResponseDataStoreLock.RLock()
|
||||||
defer ss.serviceResponseDataStoreLock.RUnlock()
|
defer ss.serviceResponseDataStoreLock.RUnlock()
|
||||||
for k, v := range ss.serviceResponseDataStoreToday {
|
for k := range ss.monitors {
|
||||||
if msm[k] == nil {
|
if msm[k] == nil {
|
||||||
msm[k] = &model.ServiceItemResponse{}
|
msm[k] = &model.ServiceItemResponse{
|
||||||
|
Up: new([30]int),
|
||||||
|
Down: new([30]int),
|
||||||
|
Delay: new([30]float32),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msm[k].Monitor = ss.monitors[k]
|
msm[k].Monitor = ss.monitors[k]
|
||||||
|
v := ss.serviceResponseDataStoreToday[k]
|
||||||
for i := 0; i < len(v); i++ {
|
for i := 0; i < len(v); i++ {
|
||||||
if v[i].Successful {
|
if v[i].Successful {
|
||||||
msm[k].Up[29]++
|
msm[k].Up[29]++
|
||||||
@ -163,44 +186,60 @@ func getStateStr(percent uint64) string {
|
|||||||
|
|
||||||
func (ss *ServiceSentinel) worker() {
|
func (ss *ServiceSentinel) worker() {
|
||||||
for r := range ss.serviceResponseChannel {
|
for r := range ss.serviceResponseChannel {
|
||||||
|
if ss.monitors[r.GetId()].ID == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
mh := model.PB2MonitorHistory(r)
|
mh := model.PB2MonitorHistory(r)
|
||||||
ss.serviceResponseDataStoreLock.Lock()
|
ss.serviceResponseDataStoreLock.Lock()
|
||||||
// 先查看是否到下一天
|
// 先查看是否到下一天
|
||||||
nowDate := time.Now().Format("02-Jan-06")
|
nowDate := time.Now().Format("02-Jan-06")
|
||||||
if nowDate != ss.latestDate {
|
if nowDate != ss.latestDate[mh.MonitorID] {
|
||||||
ss.latestDate = nowDate
|
ss.latestDate[mh.MonitorID] = nowDate
|
||||||
dataToSave := ss.serviceResponseDataStoreToday[mh.MonitorID][ss.serviceResponseDataStoreTodaySavedIndex:]
|
dataToSave := ss.serviceResponseDataStoreToday[mh.MonitorID][ss.serviceResponseDataStoreTodaySavedIndex[mh.MonitorID]:]
|
||||||
if err := DB.Create(&dataToSave).Error; err != nil {
|
if err := DB.Create(&dataToSave).Error; err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
ss.serviceResponseDataStoreTodaySavedIndex = 0
|
ss.serviceResponseDataStoreTodaySavedIndex[mh.MonitorID] = 0
|
||||||
ss.serviceResponseDataStoreToday[mh.MonitorID] = []model.MonitorHistory{}
|
ss.serviceResponseDataStoreToday[mh.MonitorID] = []model.MonitorHistory{}
|
||||||
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] = 0
|
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] = 0
|
||||||
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] = 0
|
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] = 0
|
||||||
ss.serviceResponseDataStoreTodayLastSave = time.Now()
|
ss.serviceResponseDataStoreTodayLastSave[mh.MonitorID] = time.Now()
|
||||||
}
|
}
|
||||||
// 储存至当日数据
|
// 储存至当日数据
|
||||||
ss.serviceResponseDataStoreToday[mh.MonitorID] = append(ss.serviceResponseDataStoreToday[mh.MonitorID], mh)
|
ss.serviceResponseDataStoreToday[mh.MonitorID] = append(ss.serviceResponseDataStoreToday[mh.MonitorID], mh)
|
||||||
// 每20分钟入库一次
|
// 每20分钟入库一次
|
||||||
if time.Now().After(ss.serviceResponseDataStoreTodayLastSave.Add(time.Minute * 20)) {
|
if time.Now().After(ss.serviceResponseDataStoreTodayLastSave[mh.MonitorID].Add(time.Minute * 20)) {
|
||||||
ss.serviceResponseDataStoreTodayLastSave = time.Now()
|
ss.serviceResponseDataStoreTodayLastSave[mh.MonitorID] = time.Now()
|
||||||
dataToSave := ss.serviceResponseDataStoreToday[mh.MonitorID][ss.serviceResponseDataStoreTodaySavedIndex:]
|
dataToSave := ss.serviceResponseDataStoreToday[mh.MonitorID][ss.serviceResponseDataStoreTodaySavedIndex[mh.MonitorID]:]
|
||||||
if err := DB.Create(&dataToSave).Error; err != nil {
|
if err := DB.Create(&dataToSave).Error; err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
ss.serviceResponseDataStoreTodaySavedIndex = len(ss.serviceResponseDataStoreToday[mh.MonitorID])
|
ss.serviceResponseDataStoreTodaySavedIndex[mh.MonitorID] = len(ss.serviceResponseDataStoreToday[mh.MonitorID])
|
||||||
|
}
|
||||||
|
// 写入当前数据
|
||||||
|
ss.serviceCurrentStatusData[mh.MonitorID][ss.serviceCurrentStatusIndex[mh.MonitorID]] = mh
|
||||||
|
ss.serviceCurrentStatusIndex[mh.MonitorID]++
|
||||||
|
if ss.serviceCurrentStatusIndex[mh.MonitorID] == 20 {
|
||||||
|
ss.serviceCurrentStatusIndex[mh.MonitorID] = 0
|
||||||
}
|
}
|
||||||
// 更新当前状态
|
// 更新当前状态
|
||||||
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] = 0
|
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] = 0
|
||||||
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] = 0
|
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] = 0
|
||||||
for i := len(ss.serviceResponseDataStoreToday[mh.MonitorID]) - 1; i >= 0 && i >= len(ss.serviceResponseDataStoreToday[mh.MonitorID])-20; i-- {
|
for i := 0; i < len(ss.serviceCurrentStatusData[mh.MonitorID]); i++ {
|
||||||
if ss.serviceResponseDataStoreToday[mh.MonitorID][i].Successful {
|
if ss.serviceCurrentStatusData[mh.MonitorID][i].MonitorID > 0 {
|
||||||
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID]++
|
if ss.serviceCurrentStatusData[mh.MonitorID][i].Successful {
|
||||||
} else {
|
ss.serviceResponseDataStoreCurrentUp[mh.MonitorID]++
|
||||||
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID]++
|
} else {
|
||||||
|
ss.serviceResponseDataStoreCurrentDown[mh.MonitorID]++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stateStr := getStateStr(ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] * 100 / (ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] + ss.serviceResponseDataStoreCurrentUp[mh.MonitorID]))
|
var upPercent uint64 = 0
|
||||||
|
if ss.serviceResponseDataStoreCurrentDown[mh.MonitorID]+ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] > 0 {
|
||||||
|
upPercent = ss.serviceResponseDataStoreCurrentUp[mh.MonitorID] * 100 / (ss.serviceResponseDataStoreCurrentDown[mh.MonitorID] + ss.serviceResponseDataStoreCurrentUp[mh.MonitorID])
|
||||||
|
}
|
||||||
|
stateStr := getStateStr(upPercent)
|
||||||
|
log.Println(ss.monitors[mh.MonitorID].Target, stateStr)
|
||||||
if stateStr == "故障" || stateStr != ss.lastStatus[mh.MonitorID] {
|
if stateStr == "故障" || stateStr != ss.lastStatus[mh.MonitorID] {
|
||||||
ss.monitorsLock.RLock()
|
ss.monitorsLock.RLock()
|
||||||
isSendNotification := (ss.lastStatus[mh.MonitorID] != "" || stateStr == "故障") && ss.monitors[mh.MonitorID].Notify
|
isSendNotification := (ss.lastStatus[mh.MonitorID] != "" || stateStr == "故障") && ss.monitors[mh.MonitorID].Notify
|
||||||
|
Loading…
Reference in New Issue
Block a user