- 支持 Windows Agent 构建、安装脚本和统一上报协议 - 增强 RDP 剪贴板、虚拟盘和文件传输能力 - 新增 AIOps 上下文工具、告警 RCA trace 落库和回放接口 - 重构 docs 模块文档并补充终端、堡垒机、监控、AI Agent 设计
78 lines
1.6 KiB
Go
78 lines
1.6 KiB
Go
//go:build windows
|
|
|
|
// Package collector 提供 Windows CPU 指标采集能力。 // Logan.Li
|
|
package collector
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"sync"
|
|
"syscall"
|
|
"unsafe"
|
|
|
|
"ezops/agent/model"
|
|
)
|
|
|
|
type filetime struct {
|
|
LowDateTime uint32
|
|
HighDateTime uint32
|
|
}
|
|
|
|
type cpuSample struct {
|
|
total uint64
|
|
idle uint64
|
|
iowait uint64
|
|
}
|
|
|
|
type CPUCollector struct {
|
|
mu sync.Mutex
|
|
prev *cpuSample
|
|
}
|
|
|
|
func NewCPUCollector() *CPUCollector {
|
|
return &CPUCollector{}
|
|
}
|
|
|
|
func (c *CPUCollector) Collect() (model.CPUStat, error) {
|
|
stat := model.CPUStat{CoreCount: runtime.NumCPU()}
|
|
cur, err := readCPUSample()
|
|
if err != nil {
|
|
return stat, fmt.Errorf("读取 Windows CPU 采样失败: %w", err)
|
|
}
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
if c.prev != nil {
|
|
totalDelta := cur.total - c.prev.total
|
|
idleDelta := cur.idle - c.prev.idle
|
|
if totalDelta > 0 {
|
|
stat.UsagePercent = float64(totalDelta-idleDelta) / float64(totalDelta) * 100.0
|
|
if stat.UsagePercent < 0 {
|
|
stat.UsagePercent = 0
|
|
}
|
|
}
|
|
}
|
|
c.prev = &cur
|
|
return stat, nil
|
|
}
|
|
|
|
func readCPUSample() (cpuSample, error) {
|
|
var idle, kernel, user filetime
|
|
proc := syscall.NewLazyDLL("kernel32.dll").NewProc("GetSystemTimes")
|
|
ret, _, err := proc.Call(
|
|
uintptr(unsafe.Pointer(&idle)),
|
|
uintptr(unsafe.Pointer(&kernel)),
|
|
uintptr(unsafe.Pointer(&user)),
|
|
)
|
|
if ret == 0 {
|
|
return cpuSample{}, err
|
|
}
|
|
idleTicks := filetimeToUint64(idle)
|
|
kernelTicks := filetimeToUint64(kernel)
|
|
userTicks := filetimeToUint64(user)
|
|
return cpuSample{total: kernelTicks + userTicks, idle: idleTicks}, nil
|
|
}
|
|
|
|
func filetimeToUint64(ft filetime) uint64 {
|
|
return uint64(ft.HighDateTime)<<32 | uint64(ft.LowDateTime)
|
|
}
|