112 lines
3.0 KiB
Go
112 lines
3.0 KiB
Go
package service
|
|
|
|
import (
|
|
"hy2xs-admin/dao"
|
|
"hy2xs-admin/model/entity"
|
|
"hy2xs-admin/model/vo"
|
|
"hy2xs-admin/util"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type metricsSnapshot struct {
|
|
CollectedAt int64
|
|
System vo.DashboardSystemVo
|
|
Hysteria vo.DashboardHysteriaVo
|
|
OnlinePeers int64
|
|
OnlineDevices int64
|
|
CollectorState vo.DataHealthVo
|
|
HysteriaState vo.DataHealthVo
|
|
}
|
|
|
|
var metricsStore = struct {
|
|
sync.RWMutex
|
|
snapshot metricsSnapshot
|
|
lastSuccessAt int64
|
|
}{}
|
|
|
|
func CollectMetricsSnapshot() {
|
|
nowMs := time.Now().UnixMilli()
|
|
s := metricsSnapshot{
|
|
CollectedAt: nowMs,
|
|
CollectorState: vo.DataHealthVo{Status: "ok", LastSuccessAt: nowMs},
|
|
HysteriaState: vo.DataHealthVo{Status: "ok", LastSuccessAt: nowMs},
|
|
}
|
|
|
|
if cpuPercent, err := util.GetCpuPercent(); err == nil {
|
|
s.System.CpuPercent = cpuPercent
|
|
}
|
|
if memPercent, err := util.GetMemPercent(); err == nil {
|
|
s.System.MemPercent = memPercent
|
|
}
|
|
if memInfo, err := util.GetMemInfo(); err == nil {
|
|
s.System.MemUsedBytes = memInfo.Used
|
|
s.System.MemTotalBytes = memInfo.Total
|
|
}
|
|
if diskPercent, err := util.GetDiskPercent(); err == nil {
|
|
s.System.DiskPercent = diskPercent
|
|
}
|
|
if diskInfo, err := util.GetDiskInfo(); err == nil {
|
|
s.System.DiskUsedBytes = diskInfo.Used
|
|
s.System.DiskTotalBytes = diskInfo.Total
|
|
}
|
|
|
|
s.Hysteria.Running = Hysteria2IsRunning()
|
|
s.Hysteria.Version = "-"
|
|
if content, err := util.Exec(util.GetHysteria2BinPath() + " version"); err == nil {
|
|
s.Hysteria.Version = content
|
|
}
|
|
|
|
if onlineMap, err := Hysteria2Online(); err == nil {
|
|
s.Hysteria.ApiReachable = true
|
|
s.OnlinePeers = int64(len(onlineMap))
|
|
for _, c := range onlineMap {
|
|
s.OnlineDevices += c
|
|
}
|
|
} else {
|
|
s.Hysteria.ApiReachable = false
|
|
s.Hysteria.LastApiError = "dashboard.error.trafficApiUnavailable"
|
|
s.HysteriaState.Status = "error"
|
|
s.HysteriaState.MessageKey = "dashboard.error.trafficApiUnavailable"
|
|
}
|
|
|
|
metricsStore.Lock()
|
|
metricsStore.snapshot = s
|
|
metricsStore.lastSuccessAt = nowMs
|
|
metricsStore.Unlock()
|
|
|
|
running := int64(0)
|
|
if s.Hysteria.Running {
|
|
running = 1
|
|
}
|
|
diskPath := "/"
|
|
metric := entity.MetricSample{
|
|
SampledAt: &nowMs,
|
|
CpuPercent: &s.System.CpuPercent,
|
|
Load1: func() *float64 { v := float64(0); return &v }(),
|
|
MemUsedBytes: func() *int64 { v := int64(s.System.MemUsedBytes); return &v }(),
|
|
MemTotalBytes: func() *int64 { v := int64(s.System.MemTotalBytes); return &v }(),
|
|
MemPercent: &s.System.MemPercent,
|
|
DiskPath: &diskPath,
|
|
DiskUsedBytes: func() *int64 { v := int64(s.System.DiskUsedBytes); return &v }(),
|
|
DiskTotalBytes: func() *int64 { v := int64(s.System.DiskTotalBytes); return &v }(),
|
|
DiskPercent: &s.System.DiskPercent,
|
|
HysteriaRunning: &running,
|
|
OnlinePeers: &s.OnlinePeers,
|
|
OnlineDevices: &s.OnlineDevices,
|
|
}
|
|
_ = dao.SaveMetricSample(metric)
|
|
}
|
|
|
|
func CleanupMetricsRetention() {
|
|
cutoff := time.Now().Add(-72 * time.Hour).UnixMilli()
|
|
_ = dao.CleanupMetricSample(cutoff)
|
|
}
|
|
|
|
func DashboardSnapshot() metricsSnapshot {
|
|
metricsStore.RLock()
|
|
defer metricsStore.RUnlock()
|
|
return metricsStore.snapshot
|
|
}
|
|
|