Files
WddSuperAgent/agent-wdd/config/CPU.go
2025-03-27 16:09:20 +08:00

178 lines
3.9 KiB
Go

package config
import (
"agent-wdd/log"
"bufio"
"bytes"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
)
// Gather 获取CPU相关的信息
func (cpu *CPU) Gather() {
log.Info("Gathering INFO => CPU !")
cpu.getBasicInfo()
cpu.getVirtualizationInfo()
}
func (cpu *CPU) Save() {
log.Info("Saving INFO => CPU !")
ConfigCache.Agent.CPU = *cpu
SaveConfig()
}
func (cpu *CPU) getBasicInfo() {
switch runtime.GOOS {
case "linux":
cpu.getLinuxCPUInfo()
case "windows":
cpu.getWindowsCPUInfo()
case "darwin":
cpu.getDarwinCPUInfo()
default:
// 其他平台处理
}
}
func (cpu *CPU) getLinuxCPUInfo() {
data, err := os.ReadFile("/proc/cpuinfo")
if err != nil {
return
}
contents := string(data)
cpu.Cores = strings.Count(contents, "processor\t:")
// 创建带缓冲的扫描器
scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, "model name") {
cpu.Brand = strings.TrimSpace(strings.SplitN(line, ":", 2)[1])
}
if strings.Contains(line, "cpu MHz") {
cpu.Mhz = strings.TrimSpace(strings.Split(line, ":")[1])
}
}
cpu.Arch = runtime.GOARCH
}
func (cpu *CPU) getWindowsCPUInfo() {
cmd := exec.Command("wmic", "cpu", "get", "Name,NumberOfCores,CurrentClockSpeed", "/VALUE")
output, err := cmd.Output()
if err != nil {
return
}
info := string(output)
lines := strings.Split(info, "\n")
for _, line := range lines {
if strings.HasPrefix(line, "Name=") {
cpu.Brand = strings.TrimSpace(strings.SplitN(line, "=", 2)[1])
}
if strings.HasPrefix(line, "NumberOfCores=") {
cores, _ := strconv.Atoi(strings.SplitN(line, "=", 2)[1])
cpu.Cores = cores
}
if strings.HasPrefix(line, "CurrentClockSpeed=") {
cpu.Mhz = strings.SplitN(line, "=", 2)[1]
}
}
// 架构处理
switch runtime.GOARCH {
case "amd64":
cpu.Arch = "x86_64"
default:
cpu.Arch = runtime.GOARCH
}
}
func (cpu *CPU) getVirtualizationInfo() {
switch runtime.GOOS {
case "linux":
cpu.getLinuxVirtualization()
case "windows":
cpu.getWindowsVirtualization()
}
}
func (cpu *CPU) getLinuxVirtualization() {
// 检查CPU虚拟化支持
data, err := ioutil.ReadFile("/proc/cpuinfo")
if err == nil {
if strings.Contains(string(data), "vmx") || strings.Contains(string(data), "svm") {
cpu.Virt = "supported"
}
}
// 检测是否在虚拟机中
if _, err := os.Stat("/sys/hypervisor/uid"); !os.IsNotExist(err) {
cpu.Virt = "virtualized"
if data, err := ioutil.ReadFile("/sys/hypervisor/type"); err == nil {
cpu.Hypervisor = strings.TrimSpace(string(data))
}
return
}
// 使用systemd-detect-virt
cmd := exec.Command("systemd-detect-virt")
if output, err := cmd.Output(); err == nil {
result := strings.TrimSpace(string(output))
if result != "none" {
cpu.Virt = "virtualized"
cpu.Hypervisor = result
}
}
}
func (cpu *CPU) getWindowsVirtualization() {
cmd := exec.Command("wmic", "computersystem", "get", "model", "/VALUE")
output, err := cmd.Output()
if err != nil {
return
}
model := strings.ToLower(string(output))
switch {
case strings.Contains(model, "virtualbox"):
cpu.Hypervisor = "VirtualBox"
case strings.Contains(model, "vmware"):
cpu.Hypervisor = "VMware"
case strings.Contains(model, "kvm"):
cpu.Hypervisor = "KVM"
case strings.Contains(model, "hyper-v"):
cpu.Hypervisor = "Hyper-V"
case strings.Contains(model, "xen"):
cpu.Hypervisor = "Xen"
}
if cpu.Hypervisor != "" {
cpu.Virt = "virtualized"
}
}
func (cpu *CPU) getDarwinCPUInfo() {
// macOS实现
cmd := exec.Command("sysctl", "-n", "machdep.cpu.brand_string")
if output, err := cmd.Output(); err == nil {
cpu.Brand = strings.TrimSpace(string(output))
}
cmd = exec.Command("sysctl", "-n", "hw.ncpu")
if output, err := cmd.Output(); err == nil {
if cores, err := strconv.Atoi(strings.TrimSpace(string(output))); err == nil {
cpu.Cores = cores
}
}
cpu.Arch = runtime.GOARCH
}