1.5.0
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user