版本封存

This commit is contained in:
zeaslity
2025-12-06 11:26:05 +08:00
parent 13949e1ba8
commit c0ae5e30c4
57 changed files with 2443 additions and 1428 deletions

View File

@@ -1,163 +1,205 @@
package services
package host_info
import (
"bufio"
"cmii-uav-watchdog-common/models"
"fmt"
"cmii-uav-watchdog-common/wdd_log"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
)
// NewCPUInfo 创建一个默认的 CPUInfo
func NewCPUInfo() models.CPUInfo {
return models.CPUInfo{
ModelName: "unknown",
Cores: 0,
Architecture: "unknown",
UUID: "unknown",
ModelName: "unknown",
Cores: 0,
Architecture: "amd64",
Flags: []string{},
Hypervisor: "unknown",
Virtualization: "unknown",
}
}
const (
exePath = "/proc/self/exe"
elfMagic = 0x7f
elfMagicString = "ELF"
eMachineOffset = 18
)
// parseLine 解析单行 CPU 信息
func parseLine(line string, cpuInfo *models.CPUInfo) {
if strings.HasPrefix(line, "model name") {
cpuInfo.ModelName = strings.TrimSpace(strings.Split(line, ":")[1])
}
}
// getCPUCores 通过 processor 行获取 CPU 核心数
func getCPUCores() (int, error) {
cores := 0
file, err := os.Open("/proc/cpuinfo")
if err != nil {
return cores, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "processor") {
cores++
}
}
if err := scanner.Err(); err != nil {
return cores, err
}
return cores, nil
}
// getCPUUUID 获取 CPU UUID
func getCPUUUID() (string, error) {
data, err := os.ReadFile("/sys/class/dmi/id/product_uuid")
if err != nil {
return "unknown", err
}
return strings.TrimSpace(string(data)), nil
}
func getCPUArchitecture() string {
cpuarch := "unknown"
// 打开当前进程的执行文件
file, err := os.Open(exePath)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error opening %s: %v\n", exePath, err)
return cpuarch
}
defer file.Close()
// 读取前64个字节以获取 ELF 头部信息
header := make([]byte, 64)
if _, err := file.Read(header); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error reading header: %v\n", err)
return cpuarch
}
// 检查 ELF 文件标识
if header[0] != elfMagic || string(header[1:4]) != elfMagicString {
_, _ = fmt.Fprintln(os.Stderr, "File is not an ELF file")
return cpuarch
}
// 获取架构信息
arch := header[eMachineOffset] // e_machine 字段的偏移量
switch arch {
case 0x02: // EM_386
cpuarch = "x86(32-bit)"
case 0x03: // EM_X86_64
cpuarch = "x86_64(64-bit)"
case 0x28: // EM_ARM
cpuarch = "ARM"
case 0x2A: // EM_ARM64
cpuarch = "ARM64"
case 0x08: // EM_MIPS
cpuarch = "MIPS"
default:
cpuarch = "unknown architecture"
}
return cpuarch
}
// GetCPUInfo 获取 CPU 信息
// GetCPUInfo 获取CPU信息
// 返回CPU信息结构体
func GetCPUInfo() models.CPUInfo {
wdd_log.Debug("开始获取CPU信息")
// 首先尝试从/proc/cpuinfo文件中读取信息
cpuInfo, err := getCPUInfoFromProc()
if err == nil {
wdd_log.Debug("成功从/proc/cpuinfo获取CPU信息")
return cpuInfo
}
// 如果从文件获取失败尝试使用lscpu命令
wdd_log.Warn("从/proc/cpuinfo获取CPU信息失败: %s尝试使用lscpu命令", err.Error())
cpuInfo, err = getCPUInfoFromLscpu()
if err == nil {
wdd_log.Debug("成功从lscpu命令获取CPU信息")
return cpuInfo
}
// 如果都失败使用runtime包获取基本信息
wdd_log.Warn("从lscpu获取CPU信息失败: %s使用runtime包获取基本信息", err.Error())
return getFallbackCPUInfo()
}
// getCPUInfoFromProc 从/proc/cpuinfo文件中读取CPU信息
// 返回CPU信息结构体和可能的错误
func getCPUInfoFromProc() (models.CPUInfo, error) {
wdd_log.Debug("尝试从/proc/cpuinfo读取CPU信息")
// 创建默认的CPU信息结构体
cpuInfo := NewCPUInfo()
// 读取 /proc/cpuinfo
// 打开/proc/cpuinfo文件
file, err := os.Open("/proc/cpuinfo")
if err != nil {
fmt.Println("Error opening /proc/cpuinfo:", err)
return cpuInfo // 返回默认值
return cpuInfo, err
}
defer func() {
if err := file.Close(); err != nil {
fmt.Println("Error closing /proc/cpuinfo:", err)
}
}()
defer file.Close()
// 使用scanner读取文件
scanner := bufio.NewScanner(file)
// 处理的CPU核心数量
coreCount := 1
var flags []string
// 逐行读取并解析
for scanner.Scan() {
parseLine(scanner.Text(), &cpuInfo)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading /proc/cpuinfo:", err)
return cpuInfo // 返回默认值
line := scanner.Text()
parts := strings.Split(line, ":")
if len(parts) < 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
switch key {
case "processor":
// 计数处理器核心数量
coreCount++
case "model name":
// 获取CPU型号名称
cpuInfo.ModelName = value
// 提取频率信息(如果包含)
if strings.Contains(value, "@") {
freqParts := strings.Split(value, "@")
if len(freqParts) > 1 {
cpuInfo.Frequency = strings.TrimSpace(freqParts[1])
}
}
case "flags":
// 获取CPU标志
flags = strings.Fields(value)
case "cpu cores":
// 获取每个物理CPU的核心数
cores, err := strconv.Atoi(value)
if err == nil && cores > 0 {
cpuInfo.Cores = cores
}
}
}
// 获取 CPU 核心
cores, err := getCPUCores()
// 如果没有从cpu cores字段获取到核心数使用处理器计
if cpuInfo.Cores == 0 && coreCount > 0 {
cpuInfo.Cores = coreCount
}
// 设置CPU标志
cpuInfo.Flags = flags
// 检测虚拟化相关信息
for _, flag := range flags {
if flag == "vmx" {
cpuInfo.Virtualization = "vmx"
} else if flag == "svm" {
cpuInfo.Virtualization = "svm"
} else if flag == "hypervisor" {
cpuInfo.Hypervisor = "present"
}
}
// 设置架构
cpuInfo.Architecture = runtime.GOARCH
return cpuInfo, nil
}
// getCPUInfoFromLscpu 使用lscpu命令获取CPU信息
// 返回CPU信息结构体和可能的错误
func getCPUInfoFromLscpu() (models.CPUInfo, error) {
wdd_log.Debug("尝试使用lscpu命令获取CPU信息")
// 创建默认的CPU信息结构体
cpuInfo := NewCPUInfo()
// 执行lscpu命令
cmd := exec.Command("lscpu")
output, err := cmd.Output()
if err != nil {
fmt.Println("Error getting CPU cores:", err)
} else {
cpuInfo.Cores = cores
return cpuInfo, err
}
// 获取 CPU UUID
uuid, err := getCPUUUID()
if err != nil {
fmt.Println("Error getting CPU UUID:", err)
} else {
cpuInfo.UUID = uuid
// 解析输出
lines := strings.Split(string(output), "\n")
for _, line := range lines {
parts := strings.Split(line, ":")
if len(parts) < 2 {
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
switch key {
case "Model name":
cpuInfo.ModelName = value
// 提取频率信息(如果包含)
if strings.Contains(value, "@") {
freqParts := strings.Split(value, "@")
if len(freqParts) > 1 {
cpuInfo.Frequency = strings.TrimSpace(freqParts[1])
}
}
case "Architecture":
cpuInfo.Architecture = value
case "CPU(s)":
cores, err := strconv.Atoi(value)
if err == nil {
cpuInfo.Cores = cores
}
case "Flags":
cpuInfo.Flags = strings.Fields(value)
case "Hypervisor vendor":
cpuInfo.Hypervisor = value
case "Virtualization":
cpuInfo.Virtualization = value
case "CPU MHz":
if cpuInfo.Frequency == "" {
cpuInfo.Frequency = value + " MHz"
}
}
}
cpuInfo.Architecture = getCPUArchitecture()
return cpuInfo, nil
}
// getFallbackCPUInfo 使用runtime包获取基本CPU信息
// 返回CPU信息结构体
func getFallbackCPUInfo() models.CPUInfo {
wdd_log.Debug("使用runtime包获取基本CPU信息")
cpuInfo := NewCPUInfo()
cpuInfo.Cores = runtime.NumCPU()
cpuInfo.Architecture = runtime.GOARCH
return cpuInfo
}
/*
CPU模型名称: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
核心数量: 4
架构信息: x86_64
*/