diff --git a/cmii-uav-watchdog-agent/cmd/watchdog-agent.go b/cmii-uav-watchdog-agent/cmd/watchdog-agent.go index 4ef89e4..7c185b4 100644 --- a/cmii-uav-watchdog-agent/cmd/watchdog-agent.go +++ b/cmii-uav-watchdog-agent/cmd/watchdog-agent.go @@ -1,8 +1,8 @@ package cmd import ( + "cmii-uav-watchdog-agent/host_info" "cmii-uav-watchdog-agent/rpc" - "cmii-uav-watchdog-agent/services" "cmii-uav-watchdog-agent/totp" "cmii-uav-watchdog-common/models" "fmt" diff --git a/cmii-uav-watchdog-agent/host_info/cpu_service.go b/cmii-uav-watchdog-agent/host_info/cpu_service.go index d403419..2ae2348 100644 --- a/cmii-uav-watchdog-agent/host_info/cpu_service.go +++ b/cmii-uav-watchdog-agent/host_info/cpu_service.go @@ -14,26 +14,106 @@ func NewCPUInfo() models.CPUInfo { ModelName: "unknown", Cores: 0, Architecture: "unknown", + UUID: "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]) - } else if strings.HasPrefix(line, "cpu cores") { - if _, err := fmt.Sscanf(line, "cpu cores\t: %d", &cpuInfo.Cores); err != nil { - fmt.Println("Error parsing cpu cores:", err) - } - } else if strings.HasPrefix(line, "Architecture") { - cpuInfo.Architecture = strings.TrimSpace(strings.Split(line, ":")[1]) } } -// getCPUInfo 获取 CPU 信息 +// 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 信息 func GetCPUInfo() models.CPUInfo { cpuInfo := NewCPUInfo() + // 读取 /proc/cpuinfo file, err := os.Open("/proc/cpuinfo") if err != nil { fmt.Println("Error opening /proc/cpuinfo:", err) @@ -54,6 +134,24 @@ func GetCPUInfo() models.CPUInfo { return cpuInfo // 返回默认值 } + // 获取 CPU 核心数 + cores, err := getCPUCores() + if err != nil { + fmt.Println("Error getting CPU cores:", err) + } else { + cpuInfo.Cores = cores + } + + // 获取 CPU UUID + uuid, err := getCPUUUID() + if err != nil { + fmt.Println("Error getting CPU UUID:", err) + } else { + cpuInfo.UUID = uuid + } + + cpuInfo.Architecture = getCPUArchitecture() + return cpuInfo } diff --git a/cmii-uav-watchdog-agent/host_info/host_info.go b/cmii-uav-watchdog-agent/host_info/host_info.go index de7e546..b758318 100644 --- a/cmii-uav-watchdog-agent/host_info/host_info.go +++ b/cmii-uav-watchdog-agent/host_info/host_info.go @@ -3,11 +3,11 @@ package services import "cmii-uav-watchdog-common/models" type Data struct { - CPUInfo models.CPUInfo `json:"cpu_info"` - DiskInfo []models.DiskInfo `json:"disk_info"` - MemoryInfo models.MemoryInfo `json:"memory_info"` - NetInfo []models.NetworkInterfaceInfo `json:"net_info"` - MotherboardInfo models.MotherboardInfo `json:"motherboard_info"` + SystemInfo models.SystemInfo `json:"system_info"` + CPUInfo models.CPUInfo `json:"cpu_info"` + DiskInfo []models.DiskInfo `json:"disk_info"` + MemoryInfo models.MemoryInfo `json:"memory_info"` + NetInfo []models.NetworkInterfaceInfo `json:"net_info"` } /* @@ -16,11 +16,11 @@ type Data struct { func GetAllInfo() Data { data := Data{ - CPUInfo: GetCPUInfo(), - DiskInfo: GetDiskInfo(), - MemoryInfo: GetMemoryInfo(), - NetInfo: GetNetworkInterfaces(), - MotherboardInfo: GetMotherboardInfo(), + SystemInfo: GetSystemInfo(), + CPUInfo: GetCPUInfo(), + DiskInfo: GetDiskInfo(), + MemoryInfo: GetMemoryInfo(), + NetInfo: GetNetworkInterfaces(), } return data diff --git a/cmii-uav-watchdog-agent/host_info/mem_service.go b/cmii-uav-watchdog-agent/host_info/mem_service.go index 2c59821..73bf0f9 100644 --- a/cmii-uav-watchdog-agent/host_info/mem_service.go +++ b/cmii-uav-watchdog-agent/host_info/mem_service.go @@ -14,6 +14,10 @@ func NewMemoryInfo() models.MemoryInfo { Total: 0, Free: 0, Available: 0, + Used: 0, + Buffers: 0, + Cached: 0, + Shared: 0, } } @@ -46,9 +50,18 @@ func GetMemoryInfo() models.MemoryInfo { memInfo.Free = value case "MemAvailable:": memInfo.Available = value + case "Buffers:": + memInfo.Buffers = value // 存储 Buffers 值 + case "Cached:": + memInfo.Cached = value // 存储 Cached 值 + case "Shmem:": + memInfo.Shared = value // 存储 Shared 值 } } + // 计算已用内存 + memInfo.Used = memInfo.Total - memInfo.Free - memInfo.Buffers - memInfo.Cached - memInfo.Shared + return memInfo } diff --git a/cmii-uav-watchdog-agent/host_info/system_service.go b/cmii-uav-watchdog-agent/host_info/system_service.go new file mode 100644 index 0000000..2ac613a --- /dev/null +++ b/cmii-uav-watchdog-agent/host_info/system_service.go @@ -0,0 +1,123 @@ +package services + +import ( + "cmii-uav-watchdog-common/models" + "log" + "os" + "strings" +) + +// NewOSInfo 创建并返回一个 OSInfo 实例,设置默认值 +func NewOSInfo() models.OSInfo { + return models.OSInfo{ + Name: "unknown", + Version: "unknown", + ID: "unknown", + IDLike: "unknown", + VersionID: "unknown", + PrettyName: "unknown", + HomeURL: "unknown", + SupportURL: "unknown", + BugReportURL: "unknown", + PrivacyURL: "unknown", + } +} + +// NewSystemInfo 创建并返回一个 SystemInfo 实例,设置默认值 +func NewSystemInfo() models.SystemInfo { + return models.SystemInfo{ + MachineID: "unknown", + OS: NewOSInfo(), + KernelVersion: "unknown", + } +} + +// GetSystemInfo 获取 Linux 系统信息 +func GetSystemInfo() models.SystemInfo { + sysInfo := NewSystemInfo() // 初始化结构体 + + // 获取机器 ID + machineID := getMachineID() + if machineID != "" { + sysInfo.MachineID = machineID + } + // 获取操作系统版本 + sysInfo.OS = getOSVersion() + + // 获取内核版本 + kernelVersion := getKernelVersion() + if kernelVersion != "" { + sysInfo.KernelVersion = kernelVersion + } + + return sysInfo +} +func getOSVersion() models.OSInfo { + data, err := os.ReadFile("/etc/os-release") + if err != nil { + log.Printf("Error reading /etc/os-release: %v", err) + return NewOSInfo() // 返回默认值 + } + + osInfo := NewOSInfo() // 初始化 OSInfo 结构体 + lines := strings.Split(string(data), "\n") + + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" { + continue + } + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + continue + } + key := strings.Trim(parts[0], `"`) + value := strings.Trim(parts[1], `"`) + + // 解析不同的字段 + switch key { + case "NAME": + osInfo.Name = value + case "VERSION": + osInfo.Version = value + case "ID": + osInfo.ID = value + case "ID_LIKE": + osInfo.IDLike = value + case "VERSION_ID": + osInfo.VersionID = value + case "PRETTY_NAME": + osInfo.PrettyName = value + case "HOME_URL": + osInfo.HomeURL = value + case "SUPPORT_URL": + osInfo.SupportURL = value + case "BUG_REPORT_URL": + osInfo.BugReportURL = value + case "PRIVACY_URL": + osInfo.PrivacyURL = value + } + } + + return osInfo +} + +// getMachineID 从 /etc/machine-id 文件中获取机器 ID +func getMachineID() string { + data, err := os.ReadFile("/etc/machine-id") + if err != nil { + log.Printf("Error reading /etc/machine-id: %v", err) + return "" + } + return strings.TrimSpace(string(data)) // 去除多余空格 +} + +// getKernelVersion 获取内核版本 +func getKernelVersion() string { + data, err := os.ReadFile("/proc/version") + if err != nil { + log.Printf("Error reading /proc/version: %v", err) + return "" + } + return string(data) +} diff --git a/cmii-uav-watchdog-agent/main.go b/cmii-uav-watchdog-agent/main.go index 75a6a81..458a1ce 100644 --- a/cmii-uav-watchdog-agent/main.go +++ b/cmii-uav-watchdog-agent/main.go @@ -1,7 +1,7 @@ package main import ( - "cmii-uav-watchdog-agent/services" + "cmii-uav-watchdog-agent/host_info" "fmt" "github.com/gin-gonic/gin" "net/http" diff --git a/cmii-uav-watchdog-common/models/in_project_model.go b/cmii-uav-watchdog-common/models/in_project_model.go index c8ff900..93e2d85 100644 --- a/cmii-uav-watchdog-common/models/in_project_model.go +++ b/cmii-uav-watchdog-common/models/in_project_model.go @@ -5,6 +5,7 @@ type CPUInfo struct { ModelName string `json:"model_name"` Cores int `json:"cores"` Architecture string `json:"architecture"` + UUID string `json:"uuid"` } // MemoryInfo holds the memory information. @@ -12,18 +13,22 @@ type MemoryInfo struct { Total uint64 `json:"total"` Free uint64 `json:"free"` Available uint64 `json:"available"` + Used uint64 `json:"used"` // 已用内存 + Buffers uint64 `json:"buffers"` // 缓冲区内存 + Cached uint64 `json:"cached"` // 缓存内存 + Shared uint64 `json:"shared"` // 共享内存 } // DiskInfo holds the disk information similar to df -Th output. type DiskInfo struct { - Device string `json:"device"` // 逻辑分区设备名称 - Filesystem string `json:"filesystem"` // 逻辑分区 - Type string `json:"type"` // 文件系统类型 - Size uint64 `json:"size"` // 总大小 - Used uint64 `json:"used"` // 已用空间 - Available uint64 `json:"available"` // 可用空间 - UsePercent string `json:"use_percent"` // 使用百分比 - MountPoint string `json:"mountpoint"` // 挂载点 + Device string `json:"device"` // 逻辑分区设备名称 + Filesystem string `json:"filesystem"` // 逻辑分区 + Type string `json:"type"` // 文件系统类型 + Size uint64 `json:"size"` // 总大小 + Used uint64 `json:"used"` // 已用空间 + Available uint64 `json:"available"` // 可用空间 + UsePercent string `json:"use_percent"` // 使用百分比 + MountPoint string `json:"mount_point"` PhysicalDevice string `json:"physical_device"` // 物理设备名称 PhysicalSize uint64 `json:"physical_size"` // 物理盘大小 } @@ -43,8 +48,28 @@ type MotherboardInfo struct { Serial string `json:"serial"` } +type SystemInfo struct { + MachineID string `json:"machine_id"` // 唯一标识符 + OS OSInfo `json:"os"` // 操作系统 + KernelVersion string `json:"kernel_version"` // 内核版本 +} + +type OSInfo struct { + Name string `json:"name"` + Version string `json:"version"` + ID string `json:"id"` + IDLike string `json:"id_like"` + VersionID string `json:"version_id"` + PrettyName string `json:"pretty_name"` + HomeURL string `json:"home_url"` + SupportURL string `json:"support_url"` + BugReportURL string `json:"bug_report_url"` + PrivacyURL string `json:"privacy_url"` +} + // HostInfo 主机信息模型 type HostInfo struct { + SystemInfo SystemInfo `json:"system_info"` CPUInfo CPUInfo `json:"cpu_info"` DiskInfo []DiskInfo `json:"disk_info"` MemoryInfo MemoryInfo `json:"memory_info"`