add machine_id

This commit is contained in:
boge
2025-03-18 15:56:00 +08:00
parent 58b470e95f
commit 6001907e8a
7 changed files with 286 additions and 27 deletions

View File

@@ -1,8 +1,8 @@
package cmd package cmd
import ( import (
"cmii-uav-watchdog-agent/host_info"
"cmii-uav-watchdog-agent/rpc" "cmii-uav-watchdog-agent/rpc"
"cmii-uav-watchdog-agent/services"
"cmii-uav-watchdog-agent/totp" "cmii-uav-watchdog-agent/totp"
"cmii-uav-watchdog-common/models" "cmii-uav-watchdog-common/models"
"fmt" "fmt"

View File

@@ -14,26 +14,106 @@ func NewCPUInfo() models.CPUInfo {
ModelName: "unknown", ModelName: "unknown",
Cores: 0, Cores: 0,
Architecture: "unknown", Architecture: "unknown",
UUID: "unknown",
} }
} }
const (
exePath = "/proc/self/exe"
elfMagic = 0x7f
elfMagicString = "ELF"
eMachineOffset = 18
)
// parseLine 解析单行 CPU 信息 // parseLine 解析单行 CPU 信息
func parseLine(line string, cpuInfo *models.CPUInfo) { func parseLine(line string, cpuInfo *models.CPUInfo) {
if strings.HasPrefix(line, "model name") { if strings.HasPrefix(line, "model name") {
cpuInfo.ModelName = strings.TrimSpace(strings.Split(line, ":")[1]) 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 { func GetCPUInfo() models.CPUInfo {
cpuInfo := NewCPUInfo() cpuInfo := NewCPUInfo()
// 读取 /proc/cpuinfo
file, err := os.Open("/proc/cpuinfo") file, err := os.Open("/proc/cpuinfo")
if err != nil { if err != nil {
fmt.Println("Error opening /proc/cpuinfo:", err) fmt.Println("Error opening /proc/cpuinfo:", err)
@@ -54,6 +134,24 @@ func GetCPUInfo() models.CPUInfo {
return 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 return cpuInfo
} }

View File

@@ -3,11 +3,11 @@ package services
import "cmii-uav-watchdog-common/models" import "cmii-uav-watchdog-common/models"
type Data struct { type Data struct {
CPUInfo models.CPUInfo `json:"cpu_info"` SystemInfo models.SystemInfo `json:"system_info"`
DiskInfo []models.DiskInfo `json:"disk_info"` CPUInfo models.CPUInfo `json:"cpu_info"`
MemoryInfo models.MemoryInfo `json:"memory_info"` DiskInfo []models.DiskInfo `json:"disk_info"`
NetInfo []models.NetworkInterfaceInfo `json:"net_info"` MemoryInfo models.MemoryInfo `json:"memory_info"`
MotherboardInfo models.MotherboardInfo `json:"motherboard_info"` NetInfo []models.NetworkInterfaceInfo `json:"net_info"`
} }
/* /*
@@ -16,11 +16,11 @@ type Data struct {
func GetAllInfo() Data { func GetAllInfo() Data {
data := Data{ data := Data{
CPUInfo: GetCPUInfo(), SystemInfo: GetSystemInfo(),
DiskInfo: GetDiskInfo(), CPUInfo: GetCPUInfo(),
MemoryInfo: GetMemoryInfo(), DiskInfo: GetDiskInfo(),
NetInfo: GetNetworkInterfaces(), MemoryInfo: GetMemoryInfo(),
MotherboardInfo: GetMotherboardInfo(), NetInfo: GetNetworkInterfaces(),
} }
return data return data

View File

@@ -14,6 +14,10 @@ func NewMemoryInfo() models.MemoryInfo {
Total: 0, Total: 0,
Free: 0, Free: 0,
Available: 0, Available: 0,
Used: 0,
Buffers: 0,
Cached: 0,
Shared: 0,
} }
} }
@@ -46,9 +50,18 @@ func GetMemoryInfo() models.MemoryInfo {
memInfo.Free = value memInfo.Free = value
case "MemAvailable:": case "MemAvailable:":
memInfo.Available = value 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 return memInfo
} }

View File

@@ -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)
}

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"cmii-uav-watchdog-agent/services" "cmii-uav-watchdog-agent/host_info"
"fmt" "fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http" "net/http"

View File

@@ -5,6 +5,7 @@ type CPUInfo struct {
ModelName string `json:"model_name"` ModelName string `json:"model_name"`
Cores int `json:"cores"` Cores int `json:"cores"`
Architecture string `json:"architecture"` Architecture string `json:"architecture"`
UUID string `json:"uuid"`
} }
// MemoryInfo holds the memory information. // MemoryInfo holds the memory information.
@@ -12,18 +13,22 @@ type MemoryInfo struct {
Total uint64 `json:"total"` Total uint64 `json:"total"`
Free uint64 `json:"free"` Free uint64 `json:"free"`
Available uint64 `json:"available"` 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. // DiskInfo holds the disk information similar to df -Th output.
type DiskInfo struct { type DiskInfo struct {
Device string `json:"device"` // 逻辑分区设备名称 Device string `json:"device"` // 逻辑分区设备名称
Filesystem string `json:"filesystem"` // 逻辑分区 Filesystem string `json:"filesystem"` // 逻辑分区
Type string `json:"type"` // 文件系统类型 Type string `json:"type"` // 文件系统类型
Size uint64 `json:"size"` // 总大小 Size uint64 `json:"size"` // 总大小
Used uint64 `json:"used"` // 已用空间 Used uint64 `json:"used"` // 已用空间
Available uint64 `json:"available"` // 可用空间 Available uint64 `json:"available"` // 可用空间
UsePercent string `json:"use_percent"` // 使用百分比 UsePercent string `json:"use_percent"` // 使用百分比
MountPoint string `json:"mountpoint"` // 挂载点 MountPoint string `json:"mount_point"`
PhysicalDevice string `json:"physical_device"` // 物理设备名称 PhysicalDevice string `json:"physical_device"` // 物理设备名称
PhysicalSize uint64 `json:"physical_size"` // 物理盘大小 PhysicalSize uint64 `json:"physical_size"` // 物理盘大小
} }
@@ -43,8 +48,28 @@ type MotherboardInfo struct {
Serial string `json:"serial"` 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 主机信息模型 // HostInfo 主机信息模型
type HostInfo struct { type HostInfo struct {
SystemInfo SystemInfo `json:"system_info"`
CPUInfo CPUInfo `json:"cpu_info"` CPUInfo CPUInfo `json:"cpu_info"`
DiskInfo []DiskInfo `json:"disk_info"` DiskInfo []DiskInfo `json:"disk_info"`
MemoryInfo MemoryInfo `json:"memory_info"` MemoryInfo MemoryInfo `json:"memory_info"`