✨ 展示月流量使用情况
This commit is contained in:
		
							parent
							
								
									611cabf369
								
							
						
					
					
						commit
						561a3c85fb
					
				@ -4,7 +4,7 @@
 | 
				
			|||||||
  <br>
 | 
					  <br>
 | 
				
			||||||
  <small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
 | 
					  <small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
 | 
				
			||||||
  <br><br>
 | 
					  <br><br>
 | 
				
			||||||
<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.11.2&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.7.1-brightgreen?style=for-the-badge&logo=linux">
 | 
					<img src="https://img.shields.io/github/workflow/status/naiba/nezha/Dashboard%20image?label=Dash%20v0.11.3&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.7.1-brightgreen?style=for-the-badge&logo=linux">
 | 
				
			||||||
  <br>
 | 
					  <br>
 | 
				
			||||||
  <br>
 | 
					  <br>
 | 
				
			||||||
  <p>:trollface: <b>哪吒监控</b> 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,计划任务和在线终端。</p>
 | 
					  <p>:trollface: <b>哪吒监控</b> 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,计划任务和在线终端。</p>
 | 
				
			||||||
 | 
				
			|||||||
@ -98,9 +98,12 @@ func (p *commonPage) checkViewPassword(c *gin.Context) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *commonPage) service(c *gin.Context) {
 | 
					func (p *commonPage) service(c *gin.Context) {
 | 
				
			||||||
 | 
						dao.AlertsLock.RLock()
 | 
				
			||||||
 | 
						defer dao.AlertsLock.RUnlock()
 | 
				
			||||||
	c.HTML(http.StatusOK, "theme-"+dao.Conf.Site.Theme+"/service", mygin.CommonEnvironment(c, gin.H{
 | 
						c.HTML(http.StatusOK, "theme-"+dao.Conf.Site.Theme+"/service", mygin.CommonEnvironment(c, gin.H{
 | 
				
			||||||
		"Title":              "服务状态",
 | 
							"Title":              "服务状态",
 | 
				
			||||||
		"Services":           dao.ServiceSentinelShared.LoadStats(),
 | 
							"Services":           dao.ServiceSentinelShared.LoadStats(),
 | 
				
			||||||
 | 
							"CycleTransferStats": dao.AlertsCycleTransferStatsStore,
 | 
				
			||||||
		"CustomCode":         dao.Conf.Site.CustomCode,
 | 
							"CustomCode":         dao.Conf.Site.CustomCode,
 | 
				
			||||||
	}))
 | 
						}))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -108,7 +111,6 @@ func (p *commonPage) service(c *gin.Context) {
 | 
				
			|||||||
func (cp *commonPage) home(c *gin.Context) {
 | 
					func (cp *commonPage) home(c *gin.Context) {
 | 
				
			||||||
	dao.SortedServerLock.RLock()
 | 
						dao.SortedServerLock.RLock()
 | 
				
			||||||
	defer dao.SortedServerLock.RUnlock()
 | 
						defer dao.SortedServerLock.RUnlock()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.HTML(http.StatusOK, "theme-"+dao.Conf.Site.Theme+"/home", mygin.CommonEnvironment(c, gin.H{
 | 
						c.HTML(http.StatusOK, "theme-"+dao.Conf.Site.Theme+"/home", mygin.CommonEnvironment(c, gin.H{
 | 
				
			||||||
		"Servers":    dao.SortedServerList,
 | 
							"Servers":    dao.SortedServerList,
 | 
				
			||||||
		"CustomCode": dao.Conf.Site.CustomCode,
 | 
							"CustomCode": dao.Conf.Site.CustomCode,
 | 
				
			||||||
 | 
				
			|||||||
@ -61,11 +61,24 @@ func (ma *memberAPI) delete(c *gin.Context) {
 | 
				
			|||||||
	case "server":
 | 
						case "server":
 | 
				
			||||||
		err = dao.DB.Unscoped().Delete(&model.Server{}, "id = ?", id).Error
 | 
							err = dao.DB.Unscoped().Delete(&model.Server{}, "id = ?", id).Error
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
 | 
								// 删除服务器
 | 
				
			||||||
			dao.ServerLock.Lock()
 | 
								dao.ServerLock.Lock()
 | 
				
			||||||
			delete(dao.SecretToID, dao.ServerList[id].Secret)
 | 
								delete(dao.SecretToID, dao.ServerList[id].Secret)
 | 
				
			||||||
			delete(dao.ServerList, id)
 | 
								delete(dao.ServerList, id)
 | 
				
			||||||
			dao.ServerLock.Unlock()
 | 
								dao.ServerLock.Unlock()
 | 
				
			||||||
			dao.ReSortServer()
 | 
								dao.ReSortServer()
 | 
				
			||||||
 | 
								// 删除循环流量状态中的此服务器相关的记录
 | 
				
			||||||
 | 
								dao.AlertsLock.Lock()
 | 
				
			||||||
 | 
								for i := 0; i < len(dao.Alerts); i++ {
 | 
				
			||||||
 | 
									if dao.AlertsCycleTransferStatsStore[dao.Alerts[i].ID] != nil {
 | 
				
			||||||
 | 
										delete(dao.AlertsCycleTransferStatsStore[dao.Alerts[i].ID].ServerName, id)
 | 
				
			||||||
 | 
										delete(dao.AlertsCycleTransferStatsStore[dao.Alerts[i].ID].Transfer, id)
 | 
				
			||||||
 | 
										delete(dao.AlertsCycleTransferStatsStore[dao.Alerts[i].ID].NextUpdate, id)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dao.AlertsLock.Unlock()
 | 
				
			||||||
 | 
								// 删除服务器相关循环流量记录
 | 
				
			||||||
 | 
								dao.DB.Unscoped().Delete(&model.Transfer{}, "server_id = ?", id)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case "notification":
 | 
						case "notification":
 | 
				
			||||||
		err = dao.DB.Unscoped().Delete(&model.Notification{}, "id = ?", id).Error
 | 
							err = dao.DB.Unscoped().Delete(&model.Notification{}, "id = ?", id).Error
 | 
				
			||||||
 | 
				
			|||||||
@ -2,10 +2,20 @@ package model
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CycleTransferStats struct {
 | 
				
			||||||
 | 
						Name       string
 | 
				
			||||||
 | 
						From       time.Time
 | 
				
			||||||
 | 
						To         time.Time
 | 
				
			||||||
 | 
						ServerName map[uint64]string
 | 
				
			||||||
 | 
						Transfer   map[uint64]uint64
 | 
				
			||||||
 | 
						NextUpdate map[uint64]time.Time
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AlertRule struct {
 | 
					type AlertRule struct {
 | 
				
			||||||
	Common
 | 
						Common
 | 
				
			||||||
	Name     string
 | 
						Name     string
 | 
				
			||||||
@ -27,10 +37,14 @@ func (r *AlertRule) AfterFind(tx *gorm.DB) error {
 | 
				
			|||||||
	return json.Unmarshal([]byte(r.RulesRaw), &r.Rules)
 | 
						return json.Unmarshal([]byte(r.RulesRaw), &r.Rules)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *AlertRule) Snapshot(server *Server, db *gorm.DB) []interface{} {
 | 
					func (r *AlertRule) Enabled() bool {
 | 
				
			||||||
 | 
						return r.Enable != nil && *r.Enable
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *AlertRule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server, db *gorm.DB) []interface{} {
 | 
				
			||||||
	var point []interface{}
 | 
						var point []interface{}
 | 
				
			||||||
	for i := 0; i < len(r.Rules); i++ {
 | 
						for i := 0; i < len(r.Rules); i++ {
 | 
				
			||||||
		point = append(point, r.Rules[i].Snapshot(server, db))
 | 
							point = append(point, r.Rules[i].Snapshot(cycleTransferStats, server, db))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return point
 | 
						return point
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,7 @@ func percentage(used, total uint64) float64 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Snapshot 未通过规则返回 struct{}{}, 通过返回 nil
 | 
					// Snapshot 未通过规则返回 struct{}{}, 通过返回 nil
 | 
				
			||||||
func (u *Rule) Snapshot(server *Server, db *gorm.DB) interface{} {
 | 
					func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server, db *gorm.DB) interface{} {
 | 
				
			||||||
	// 监控全部但是排除了此服务器
 | 
						// 监控全部但是排除了此服务器
 | 
				
			||||||
	if u.Cover == RuleCoverAll && u.Ignore[server.ID] {
 | 
						if u.Cover == RuleCoverAll && u.Ignore[server.ID] {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
@ -139,6 +139,11 @@ func (u *Rule) Snapshot(server *Server, db *gorm.DB) interface{} {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			u.LastCycleStatus[server.ID] = nil
 | 
								u.LastCycleStatus[server.ID] = nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if cycleTransferStats.ServerName[server.ID] != server.Name {
 | 
				
			||||||
 | 
								cycleTransferStats.ServerName[server.ID] = server.Name
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cycleTransferStats.Transfer[server.ID] = uint64(src)
 | 
				
			||||||
 | 
							cycleTransferStats.NextUpdate[server.ID] = u.NextTransferAt[server.ID]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if u.Type == "offline" && float64(time.Now().Unix())-src > 6 {
 | 
						if u.Type == "offline" && float64(time.Now().Unix())-src > 6 {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								resource/template/theme-default/service.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								resource/template/theme-default/service.html
									
									
									
									
										vendored
									
									
								
							@ -7,7 +7,6 @@
 | 
				
			|||||||
<div class="nb-container">
 | 
					<div class="nb-container">
 | 
				
			||||||
    <div class="ui container">
 | 
					    <div class="ui container">
 | 
				
			||||||
        <div class="service-status">
 | 
					        <div class="service-status">
 | 
				
			||||||
 | 
					 | 
				
			||||||
            <table class="ui celled table">
 | 
					            <table class="ui celled table">
 | 
				
			||||||
                <thead>
 | 
					                <thead>
 | 
				
			||||||
                    <tr>
 | 
					                    <tr>
 | 
				
			||||||
@ -30,12 +29,48 @@
 | 
				
			|||||||
                            </div> {{end}}
 | 
					                            </div> {{end}}
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                        <td class="ui center aligned delay-today">
 | 
					                        <td class="ui center aligned delay-today">
 | 
				
			||||||
                            <i class="delay-today {{className (divU64 $service.CurrentUp (addU64 $service.CurrentUp $service.CurrentDown))}}"></i>
 | 
					                            <i
 | 
				
			||||||
 | 
					                                class="delay-today {{className (divU64 $service.CurrentUp (addU64 $service.CurrentUp $service.CurrentDown))}}"></i>
 | 
				
			||||||
                            {{statusName (divU64 $service.CurrentUp (addU64 $service.CurrentUp $service.CurrentDown))}}
 | 
					                            {{statusName (divU64 $service.CurrentUp (addU64 $service.CurrentUp $service.CurrentDown))}}
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                    </tr> {{end}}
 | 
					                    </tr> {{end}}
 | 
				
			||||||
                </tbody>
 | 
					                </tbody>
 | 
				
			||||||
            </table>
 | 
					            </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {{if .CycleTransferStats}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <h2 style="text-align: center;">循环流量统计</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <table class="ui celled table">
 | 
				
			||||||
 | 
					                <thead>
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">ID</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">规则</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">服务器</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">自</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">至</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">下次刷新</th>
 | 
				
			||||||
 | 
					                        <th class="ui center aligned">流量</th>
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                </thead>
 | 
				
			||||||
 | 
					                <tbody>
 | 
				
			||||||
 | 
					                    {{range $id, $stats := .CycleTransferStats}}
 | 
				
			||||||
 | 
					                    {{range $innerId, $transfer := $stats.Transfer}}
 | 
				
			||||||
 | 
					                        <tr>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{$id}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{$stats.Name}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{index $stats.ServerName $innerId}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{$stats.From|tf}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{$stats.To|tf}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{(index $stats.NextUpdate $innerId)|tf}}</td>
 | 
				
			||||||
 | 
					                            <td class="ui center aligned">{{$transfer|bf}}</td>
 | 
				
			||||||
 | 
					                        </tr>
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                </tbody>
 | 
				
			||||||
 | 
					            </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {{end}}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -16,29 +16,54 @@ const (
 | 
				
			|||||||
	_RuleCheckPass
 | 
						_RuleCheckPass
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 报警规则
 | 
					 | 
				
			||||||
var alertsLock sync.RWMutex
 | 
					 | 
				
			||||||
var alerts []*model.AlertRule
 | 
					 | 
				
			||||||
var alertsStore map[uint64]map[uint64][][]interface{}
 | 
					 | 
				
			||||||
var alertsPrevState map[uint64]map[uint64]uint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type NotificationHistory struct {
 | 
					type NotificationHistory struct {
 | 
				
			||||||
	Duration time.Duration
 | 
						Duration time.Duration
 | 
				
			||||||
	Until    time.Time
 | 
						Until    time.Time
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 报警规则
 | 
				
			||||||
 | 
					var AlertsLock sync.RWMutex
 | 
				
			||||||
 | 
					var Alerts []*model.AlertRule
 | 
				
			||||||
 | 
					var alertsStore map[uint64]map[uint64][][]interface{}
 | 
				
			||||||
 | 
					var alertsPrevState map[uint64]map[uint64]uint
 | 
				
			||||||
 | 
					var AlertsCycleTransferStatsStore map[uint64]*model.CycleTransferStats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addCycleTransferStatsInfo(alert *model.AlertRule) {
 | 
				
			||||||
 | 
						if !alert.Enabled() {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for j := 0; j < len(alert.Rules); j++ {
 | 
				
			||||||
 | 
							if !alert.Rules[j].IsTransferDurationRule() {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if AlertsCycleTransferStatsStore[alert.ID] == nil {
 | 
				
			||||||
 | 
								from := alert.Rules[j].GetTransferDurationStart()
 | 
				
			||||||
 | 
								AlertsCycleTransferStatsStore[alert.ID] = &model.CycleTransferStats{
 | 
				
			||||||
 | 
									Name:       alert.Name,
 | 
				
			||||||
 | 
									From:       from,
 | 
				
			||||||
 | 
									To:         from.Add(time.Hour * time.Duration(alert.Rules[j].CycleInterval)),
 | 
				
			||||||
 | 
									ServerName: make(map[uint64]string),
 | 
				
			||||||
 | 
									Transfer:   make(map[uint64]uint64),
 | 
				
			||||||
 | 
									NextUpdate: make(map[uint64]time.Time),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func AlertSentinelStart() {
 | 
					func AlertSentinelStart() {
 | 
				
			||||||
	alertsStore = make(map[uint64]map[uint64][][]interface{})
 | 
						alertsStore = make(map[uint64]map[uint64][][]interface{})
 | 
				
			||||||
	alertsPrevState = make(map[uint64]map[uint64]uint)
 | 
						alertsPrevState = make(map[uint64]map[uint64]uint)
 | 
				
			||||||
	alertsLock.Lock()
 | 
						AlertsCycleTransferStatsStore = make(map[uint64]*model.CycleTransferStats)
 | 
				
			||||||
	if err := DB.Find(&alerts).Error; err != nil {
 | 
						AlertsLock.Lock()
 | 
				
			||||||
 | 
						if err := DB.Find(&Alerts).Error; err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i := 0; i < len(alerts); i++ {
 | 
						for i := 0; i < len(Alerts); i++ {
 | 
				
			||||||
		alertsStore[alerts[i].ID] = make(map[uint64][][]interface{})
 | 
							alertsStore[Alerts[i].ID] = make(map[uint64][][]interface{})
 | 
				
			||||||
		alertsPrevState[alerts[i].ID] = make(map[uint64]uint)
 | 
							alertsPrevState[Alerts[i].ID] = make(map[uint64]uint)
 | 
				
			||||||
 | 
							addCycleTransferStatsInfo(Alerts[i])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	alertsLock.Unlock()
 | 
						AlertsLock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	time.Sleep(time.Second * 10)
 | 
						time.Sleep(time.Second * 10)
 | 
				
			||||||
	var lastPrint time.Time
 | 
						var lastPrint time.Time
 | 
				
			||||||
@ -59,52 +84,55 @@ func AlertSentinelStart() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func OnRefreshOrAddAlert(alert model.AlertRule) {
 | 
					func OnRefreshOrAddAlert(alert model.AlertRule) {
 | 
				
			||||||
	alertsLock.Lock()
 | 
						AlertsLock.Lock()
 | 
				
			||||||
	defer alertsLock.Unlock()
 | 
						defer AlertsLock.Unlock()
 | 
				
			||||||
	delete(alertsStore, alert.ID)
 | 
						delete(alertsStore, alert.ID)
 | 
				
			||||||
	delete(alertsPrevState, alert.ID)
 | 
						delete(alertsPrevState, alert.ID)
 | 
				
			||||||
	var isEdit bool
 | 
						var isEdit bool
 | 
				
			||||||
	for i := 0; i < len(alerts); i++ {
 | 
						for i := 0; i < len(Alerts); i++ {
 | 
				
			||||||
		if alerts[i].ID == alert.ID {
 | 
							if Alerts[i].ID == alert.ID {
 | 
				
			||||||
			alerts[i] = &alert
 | 
								Alerts[i] = &alert
 | 
				
			||||||
			isEdit = true
 | 
								isEdit = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !isEdit {
 | 
						if !isEdit {
 | 
				
			||||||
		alerts = append(alerts, &alert)
 | 
							Alerts = append(Alerts, &alert)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	alertsStore[alert.ID] = make(map[uint64][][]interface{})
 | 
						alertsStore[alert.ID] = make(map[uint64][][]interface{})
 | 
				
			||||||
	alertsPrevState[alert.ID] = make(map[uint64]uint)
 | 
						alertsPrevState[alert.ID] = make(map[uint64]uint)
 | 
				
			||||||
 | 
						delete(AlertsCycleTransferStatsStore, alert.ID)
 | 
				
			||||||
 | 
						addCycleTransferStatsInfo(&alert)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func OnDeleteAlert(id uint64) {
 | 
					func OnDeleteAlert(id uint64) {
 | 
				
			||||||
	alertsLock.Lock()
 | 
						AlertsLock.Lock()
 | 
				
			||||||
	defer alertsLock.Unlock()
 | 
						defer AlertsLock.Unlock()
 | 
				
			||||||
	delete(alertsStore, id)
 | 
						delete(alertsStore, id)
 | 
				
			||||||
	delete(alertsPrevState, id)
 | 
						delete(alertsPrevState, id)
 | 
				
			||||||
	for i := 0; i < len(alerts); i++ {
 | 
						for i := 0; i < len(Alerts); i++ {
 | 
				
			||||||
		if alerts[i].ID == id {
 | 
							if Alerts[i].ID == id {
 | 
				
			||||||
			alerts = append(alerts[:i], alerts[i+1:]...)
 | 
								Alerts = append(Alerts[:i], Alerts[i+1:]...)
 | 
				
			||||||
			i--
 | 
								i--
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						delete(AlertsCycleTransferStatsStore, id)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func checkStatus() {
 | 
					func checkStatus() {
 | 
				
			||||||
	alertsLock.RLock()
 | 
						AlertsLock.RLock()
 | 
				
			||||||
	defer alertsLock.RUnlock()
 | 
						defer AlertsLock.RUnlock()
 | 
				
			||||||
	ServerLock.RLock()
 | 
						ServerLock.RLock()
 | 
				
			||||||
	defer ServerLock.RUnlock()
 | 
						defer ServerLock.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, alert := range alerts {
 | 
						for _, alert := range Alerts {
 | 
				
			||||||
		// 跳过未启用
 | 
							// 跳过未启用
 | 
				
			||||||
		if alert.Enable == nil || !*alert.Enable {
 | 
							if !alert.Enabled() {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, server := range ServerList {
 | 
							for _, server := range ServerList {
 | 
				
			||||||
			// 监测点
 | 
								// 监测点
 | 
				
			||||||
			alertsStore[alert.ID][server.ID] = append(alertsStore[alert.
 | 
								alertsStore[alert.ID][server.ID] = append(alertsStore[alert.
 | 
				
			||||||
				ID][server.ID], alert.Snapshot(server, DB))
 | 
									ID][server.ID], alert.Snapshot(AlertsCycleTransferStatsStore[alert.ID], server, DB))
 | 
				
			||||||
			// 发送通知,分为触发报警和恢复通知
 | 
								// 发送通知,分为触发报警和恢复通知
 | 
				
			||||||
			max, passed := alert.Check(alertsStore[alert.ID][server.ID])
 | 
								max, passed := alert.Check(alertsStore[alert.ID][server.ID])
 | 
				
			||||||
			if !passed {
 | 
								if !passed {
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ import (
 | 
				
			|||||||
	pb "github.com/naiba/nezha/proto"
 | 
						pb "github.com/naiba/nezha/proto"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Version = "v0.11.2" // !!记得修改 README 中的 badge 版本!!
 | 
					var Version = "v0.11.3" // !!记得修改 README 中的 badge 版本!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	Conf  *model.Config
 | 
						Conf  *model.Config
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user