This commit is contained in:
robin
2026-03-13 14:25:13 +08:00
parent a25a474d6a
commit afbaaa869c
95 changed files with 4591 additions and 2578 deletions

View File

@@ -15,18 +15,28 @@ import (
teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const"
"github.com/TeaOSLab/EdgeHttpDNS/internal/rpc"
"github.com/TeaOSLab/EdgeHttpDNS/internal/utils"
"github.com/iwind/TeaGo/maps"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/mem"
)
type StatusManager struct {
quitCh <-chan struct{}
ticker *time.Ticker
isFirstTime bool
cpuUpdatedTime time.Time
cpuLogicalCount int
cpuPhysicalCount int
}
func NewStatusManager(quitCh <-chan struct{}) *StatusManager {
return &StatusManager{
quitCh: quitCh,
ticker: time.NewTicker(30 * time.Second),
quitCh: quitCh,
ticker: time.NewTicker(30 * time.Second),
isFirstTime: true,
cpuUpdatedTime: time.Now(),
cpuLogicalCount: runtime.NumCPU(),
}
}
@@ -72,10 +82,12 @@ func (m *StatusManager) update() {
IsActive: true,
StatusJSON: statusJSON,
})
if err != nil {
log.Println("[HTTPDNS_NODE][status]update status failed:", err.Error())
}
m.reportNodeValues(rpcClient, status)
m.isFirstTime = false
}
func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
@@ -87,8 +99,8 @@ func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
ConfigVersion: 0,
OS: runtime.GOOS,
Arch: runtime.GOARCH,
CPULogicalCount: runtime.NumCPU(),
CPUPhysicalCount: runtime.NumCPU(),
CPULogicalCount: m.cpuLogicalCount,
CPUPhysicalCount: m.cpuPhysicalCount,
IsActive: true,
ConnectionCount: 0,
UpdatedAt: now,
@@ -104,26 +116,104 @@ func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
}
}
hostname, _ := os.Hostname()
status.Hostname = hostname
exePath, _ := os.Executable()
status.ExePath = exePath
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
status.MemoryTotal = memStats.Sys
if status.MemoryTotal > 0 {
status.MemoryUsage = float64(memStats.Alloc) / float64(status.MemoryTotal)
m.updateCPU(status)
m.updateMemory(status)
m.updateLoad(status)
return status
}
func (m *StatusManager) updateCPU(status *nodeconfigs.NodeStatus) {
duration := time.Duration(0)
if m.isFirstTime {
duration = 100 * time.Millisecond
}
percents, err := cpu.Percent(duration, false)
if err == nil && len(percents) > 0 {
status.CPUUsage = percents[0] / 100
}
if time.Since(m.cpuUpdatedTime) >= 5*time.Minute || m.cpuLogicalCount <= 0 {
m.cpuUpdatedTime = time.Now()
if logicalCount, countErr := cpu.Counts(true); countErr == nil && logicalCount > 0 {
m.cpuLogicalCount = logicalCount
}
if physicalCount, countErr := cpu.Counts(false); countErr == nil && physicalCount > 0 {
m.cpuPhysicalCount = physicalCount
}
}
status.CPULogicalCount = m.cpuLogicalCount
if m.cpuPhysicalCount > 0 {
status.CPUPhysicalCount = m.cpuPhysicalCount
}
}
func (m *StatusManager) updateMemory(status *nodeconfigs.NodeStatus) {
stat, err := mem.VirtualMemory()
if err != nil || stat == nil || stat.Total == 0 {
return
}
usedBytes := stat.Used
if stat.Total > stat.Free+stat.Buffers+stat.Cached {
usedBytes = stat.Total - stat.Free - stat.Buffers - stat.Cached
}
status.MemoryTotal = stat.Total
status.MemoryUsage = float64(usedBytes) / float64(stat.Total)
}
func (m *StatusManager) updateLoad(status *nodeconfigs.NodeStatus) {
load1m, load5m, load15m := readLoadAvg()
status.Load1m = load1m
status.Load5m = load5m
status.Load15m = load15m
}
return status
func (m *StatusManager) reportNodeValues(rpcClient *rpc.RPCClient, status *nodeconfigs.NodeStatus) {
if rpcClient == nil || status == nil {
return
}
m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemCPU, maps.Map{
"usage": status.CPUUsage,
"cores": status.CPULogicalCount,
})
m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemMemory, maps.Map{
"usage": status.MemoryUsage,
"total": status.MemoryTotal,
})
m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemLoad, maps.Map{
"load1m": status.Load1m,
"load5m": status.Load5m,
"load15m": status.Load15m,
})
}
func (m *StatusManager) createNodeValue(rpcClient *rpc.RPCClient, item string, value maps.Map) {
valueJSON, err := json.Marshal(value)
if err != nil {
log.Println("[HTTPDNS_NODE][status]marshal node value failed:", err.Error())
return
}
_, err = rpcClient.NodeValueRPC.CreateNodeValue(rpcClient.Context(), &pb.CreateNodeValueRequest{
Item: item,
ValueJSON: valueJSON,
CreatedAt: time.Now().Unix(),
})
if err != nil {
log.Println("[HTTPDNS_NODE][status]create node value failed:", item, err.Error())
}
}
func readLoadAvg() (float64, float64, float64) {