From 0b95c5aaa609e9c79376c51b11c04f447cbec2cd Mon Sep 17 00:00:00 2001 From: Akizon77 Date: Sat, 21 Jun 2025 16:40:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96CPU=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- monitoring/unit/cpu.go | 108 +++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/monitoring/unit/cpu.go b/monitoring/unit/cpu.go index e86fa6e..30a49d9 100644 --- a/monitoring/unit/cpu.go +++ b/monitoring/unit/cpu.go @@ -1,6 +1,9 @@ package monitoring import ( + "bufio" + "os" + "os/exec" "runtime" "strings" "time" @@ -16,49 +19,90 @@ type CpuInfo struct { } func Cpu() CpuInfo { - cpuinfo := CpuInfo{} - info, err := cpu.Info() - if err != nil { - cpuinfo.CPUName = "Unknown" + cpuinfo := CpuInfo{ + CPUName: "Unknown", + CPUArchitecture: runtime.GOARCH, + CPUCores: 1, + CPUUsage: 0.0, } - /* - // multiple CPU - // 多个 CPU - if len(info) > 1 { - cpuCountMap := make(map[string]int) - for _, cpu := range info { - cpuCountMap[cpu.ModelName]++ - } - for modelName, count := range cpuCountMap { - if count > 1 { - cpuinfo.CPUName += modelName + " x " + strconv.Itoa(count) + ", " - } else { - cpuinfo.CPUName += modelName + ", " + + // 优先使用 lscpu 获取 CPU 信息 + name, err := readCPUNameFromLscpu() + if err == nil && name != "" { + cpuinfo.CPUName = strings.TrimSpace(name) + } else { + // 如果 lscpu 无法获取 CPU 名称,尝试使用 gopsutil + info, err := cpu.Info() + if err == nil && len(info) > 0 { + cpuinfo.CPUName = strings.TrimSpace(info[0].ModelName) + if cpuinfo.CPUName == "" { + if info[0].VendorID != "" || info[0].Family != "" { + cpuinfo.CPUName = strings.TrimSpace(info[0].VendorID + " " + info[0].Family) } } - cpuinfo.CPUName = cpuinfo.CPUName[:len(cpuinfo.CPUName)-2] // Remove trailing comma and space - } else if len(info) == 1 { - cpuinfo.CPUName = info[0].ModelName } - */ - cpuinfo.CPUName = info[0].ModelName + } - cpuinfo.CPUName = strings.TrimSpace(cpuinfo.CPUName) - - cpuinfo.CPUArchitecture = runtime.GOARCH + if cpuinfo.CPUName == "Unknown" { + name, err := readCPUNameFromProc() + if err == nil && name != "" { + cpuinfo.CPUName = strings.TrimSpace(name) + } + } cores, err := cpu.Counts(true) - if err != nil { - cpuinfo.CPUCores = 1 // Error case + if err == nil { + cpuinfo.CPUCores = cores } - cpuinfo.CPUCores = cores - // Get CPU Usage percentages, err := cpu.Percent(1*time.Second, false) - if err != nil { - cpuinfo.CPUUsage = 0.0 // Error case - } else { + if err == nil && len(percentages) > 0 { cpuinfo.CPUUsage = percentages[0] } + return cpuinfo } + +// readCPUNameFromLscpu 从 lscpu 命令读取 CPU 名称 +func readCPUNameFromLscpu() (string, error) { + cmd := exec.Command("lscpu") + output, err := cmd.Output() + if err != nil { + return "", err + } + + scanner := bufio.NewScanner(strings.NewReader(string(output))) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "Model name:") { + parts := strings.SplitN(line, ":", 2) + if len(parts) == 2 { + return strings.TrimSpace(parts[1]), nil + } + } + } + + return "", scanner.Err() +} + +// readCPUNameFromProc 从 /proc/cpuinfo 读取 CPU 名称 +func readCPUNameFromProc() (string, error) { + file, err := os.Open("/proc/cpuinfo") + if err != nil { + return "", err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "Model\t") || strings.HasPrefix(line, "Hardware\t") || strings.HasPrefix(line, "Processor\t") { + parts := strings.SplitN(line, ":", 2) + if len(parts) == 2 { + return strings.TrimSpace(parts[1]), nil + } + } + } + + return "", scanner.Err() +}