package main import ( "fmt" "runtime" "time" "github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/disk" "github.com/shirou/gopsutil/v4/host" "github.com/shirou/gopsutil/v4/load" // 添加 load 包导入 "github.com/shirou/gopsutil/v4/mem" "github.com/shirou/gopsutil/v4/net" "github.com/shirou/gopsutil/v4/process" ) func main() { fmt.Println("================ 服务器监控系统 ================") // 1. 获取系统信息 getHostInfo() // 2. 获取CPU信息 getCPUInfo() // 3. 获取内存信息 getMemoryInfo() // 4. 获取磁盘信息 getDiskInfo() // 5. 获取网络信息 getNetworkInfo() // 6. 获取负载信息(Linux特有) getLoadInfo() // 7. 获取进程信息 getProcessInfo(3) // 8. 显示运行时信息 getRuntimeInfo() fmt.Println("\n================ 实时监控示例 ================") // 9. 快速收集一次指标(不等待10秒) getQuickMetrics() } // 获取主机信息 func getHostInfo() { fmt.Println("\n=== 主机信息 ===") hostInfo, err := host.Info() if err != nil { fmt.Printf("获取主机信息失败: %v\n", err) return } fmt.Printf("主机名: %s\n", hostInfo.Hostname) fmt.Printf("操作系统: %s\n", hostInfo.OS) fmt.Printf("平台: %s\n", hostInfo.Platform) fmt.Printf("平台版本: %s\n", hostInfo.PlatformVersion) fmt.Printf("内核版本: %s\n", hostInfo.KernelVersion) // 格式化启动时间 bootTime := time.Unix(int64(hostInfo.BootTime), 0) uptime := time.Since(bootTime) hours := int(uptime.Hours()) minutes := int(uptime.Minutes()) % 60 fmt.Printf("系统启动时间: %s\n", bootTime.Format("2006-01-02 15:04:05")) fmt.Printf("系统已运行: %d小时%d分钟\n", hours, minutes) fmt.Printf("CPU数量: %d\n", hostInfo.Procs) fmt.Printf("系统架构: %s\n", hostInfo.KernelArch) fmt.Printf("主机ID: %s\n", hostInfo.HostID) } // 获取CPU信息 func getCPUInfo() { fmt.Println("\n=== CPU信息 ===") // 获取CPU核心数 physicalCount, _ := cpu.Counts(false) logicalCount, _ := cpu.Counts(true) fmt.Printf("物理CPU核心数: %d\n", physicalCount) fmt.Printf("逻辑CPU核心数: %d\n", logicalCount) // 获取CPU使用率(采样200毫秒,减少等待时间) percent, err := cpu.Percent(200*time.Millisecond, false) if err != nil { fmt.Printf("获取CPU使用率失败: %v\n", err) } else if len(percent) > 0 { fmt.Printf("CPU总使用率: %.2f%%\n", percent[0]) } // 每个核心的使用率(可选) perCorePercent, err := cpu.Percent(200*time.Millisecond, true) if err == nil && len(perCorePercent) > 0 { fmt.Printf("各核心使用率: ") for i, p := range perCorePercent { if i > 0 { fmt.Printf(", ") } fmt.Printf("CPU%d:%.1f%%", i, p) } fmt.Println() } // 获取CPU详细信息 cpuInfo, err := cpu.Info() if err == nil && len(cpuInfo) > 0 { cpu := cpuInfo[0] // 第一个CPU的信息 fmt.Printf("CPU型号: %s\n", cpu.ModelName) fmt.Printf("CPU频率: %.2f GHz\n", cpu.Mhz/1000) if cpu.CacheSize > 0 { fmt.Printf("缓存大小: %d KB\n", cpu.CacheSize) } fmt.Printf("每个CPU的核心数: %d\n", cpu.Cores) fmt.Printf("逻辑核心数: %d\n", int(cpu.Cores)*len(cpuInfo)) } } // 获取内存信息 func getMemoryInfo() { fmt.Println("\n=== 内存信息 ===") vMem, err := mem.VirtualMemory() if err != nil { fmt.Printf("获取内存信息失败: %v\n", err) return } // 格式化内存大小 totalGB := float64(vMem.Total) / (1024 * 1024 * 1024) availableGB := float64(vMem.Available) / (1024 * 1024 * 1024) usedGB := float64(vMem.Used) / (1024 * 1024 * 1024) fmt.Printf("总内存: %.2f GB\n", totalGB) fmt.Printf("可用内存: %.2f GB (%.1f%%)\n", availableGB, (float64(vMem.Available)/float64(vMem.Total))*100) fmt.Printf("已用内存: %.2f GB (%.1f%%)\n", usedGB, vMem.UsedPercent) fmt.Printf("空闲内存: %.2f GB\n", float64(vMem.Free)/(1024*1024*1024)) if vMem.Cached > 0 { fmt.Printf("缓存内存: %.2f GB\n", float64(vMem.Cached)/(1024*1024*1024)) } if vMem.Buffers > 0 { fmt.Printf("缓冲区内存: %.2f GB\n", float64(vMem.Buffers)/(1024*1024*1024)) } // 交换空间 swap, err := mem.SwapMemory() if err == nil && swap.Total > 0 { fmt.Printf("\n交换空间: %.2f GB\n", float64(swap.Total)/(1024*1024*1024)) fmt.Printf("交换空间使用率: %.2f%%\n", swap.UsedPercent) } } // 获取磁盘信息 func getDiskInfo() { fmt.Println("\n=== 磁盘信息 ===") partitions, err := disk.Partitions(false) if err != nil { fmt.Printf("获取磁盘分区失败: %v\n", err) return } fmt.Printf("发现 %d 个分区:\n", len(partitions)) for i, partition := range partitions { // 过滤掉特殊文件系统 if partition.Fstype == "" || partition.Fstype == "tmpfs" || partition.Fstype == "devtmpfs" || partition.Fstype == "squashfs" { continue } usage, err := disk.Usage(partition.Mountpoint) if err != nil { continue } usedGB := float64(usage.Used) / (1024 * 1024 * 1024) totalGB := float64(usage.Total) / (1024 * 1024 * 1024) freeGB := float64(usage.Free) / (1024 * 1024 * 1024) fmt.Printf("%d. %s\n", i+1, partition.Mountpoint) fmt.Printf(" 设备: %s\n", partition.Device) fmt.Printf(" 文件系统: %s\n", partition.Fstype) fmt.Printf(" 总容量: %.2f GB\n", totalGB) fmt.Printf(" 已用空间: %.2f GB\n", usedGB) fmt.Printf(" 可用空间: %.2f GB\n", freeGB) fmt.Printf(" 使用率: %.2f%%\n", usage.UsedPercent) // 使用进度条显示使用率 printUsageBar(usage.UsedPercent) if usage.InodesUsedPercent > 0 { fmt.Printf(" Inode使用率: %.2f%%\n", usage.InodesUsedPercent) } fmt.Println() } } // 打印使用率进度条 func printUsageBar(percent float64) { barLength := 20 usedBars := int(percent * float64(barLength) / 100) if usedBars > barLength { usedBars = barLength } bar := "[" for i := 0; i < barLength; i++ { if i < usedBars { bar += "=" } else { bar += " " } } bar += "]" fmt.Printf(" 使用情况: %s\n", bar) } // 获取网络信息 func getNetworkInfo() { fmt.Println("\n=== 网络信息 ===") // 获取网络接口 interfaces, err := net.Interfaces() if err != nil { fmt.Printf("获取网络接口失败: %v\n", err) return } activeInterfaces := 0 for _, iface := range interfaces { if len(iface.Addrs) > 0 && iface.Name != "lo" { // 排除回环接口 activeInterfaces++ fmt.Printf("接口 %d: %s\n", activeInterfaces, iface.Name) if iface.HardwareAddr != "" { fmt.Printf(" 硬件地址: %s\n", iface.HardwareAddr) } if len(iface.Addrs) > 0 { fmt.Printf(" IP地址: ") for j, addr := range iface.Addrs { if j > 0 { fmt.Printf(", ") } fmt.Printf("%s", addr.Addr) } fmt.Println() } } } // 获取网络IO统计 ioCounters, err := net.IOCounters(true) // true 表示按接口分别统计 if err == nil { var totalRecv, totalSent uint64 for _, io := range ioCounters { totalRecv += io.BytesRecv totalSent += io.BytesSent } fmt.Printf("\n网络流量统计:\n") fmt.Printf(" 总接收: %.2f MB\n", float64(totalRecv)/(1024*1024)) fmt.Printf(" 总发送: %.2f MB\n", float64(totalSent)/(1024*1024)) } // 获取TCP连接数 tcpConns, err := net.Connections("tcp") if err == nil { established := 0 for _, conn := range tcpConns { if conn.Status == "ESTABLISHED" { established++ } } fmt.Printf(" TCP连接数: %d (已建立: %d)\n", len(tcpConns), established) } } // 获取负载信息(Linux特有) func getLoadInfo() { fmt.Println("\n=== 系统负载 ===") avg, err := load.Avg() if err != nil { fmt.Printf("获取系统负载失败: %v\n", err) return } logicalCount, _ := cpu.Counts(true) fmt.Printf("1分钟负载: %.2f\n", avg.Load1) fmt.Printf("5分钟负载: %.2f\n", avg.Load5) fmt.Printf("15分钟负载: %.2f\n", avg.Load15) // 负载除以CPU核心数得到相对负载 if logicalCount > 0 { relativeLoad1 := avg.Load1 / float64(logicalCount) relativeLoad5 := avg.Load5 / float64(logicalCount) relativeLoad15 := avg.Load15 / float64(logicalCount) fmt.Printf("相对1分钟负载(每核心): %.2f\n", relativeLoad1) fmt.Printf("相对5分钟负载(每核心): %.2f\n", relativeLoad5) fmt.Printf("相对15分钟负载(每核心): %.2f\n", relativeLoad15) // 负载状态评估 fmt.Printf("负载状态: ") if relativeLoad1 < 0.7 { fmt.Println("轻松") } else if relativeLoad1 < 1.5 { fmt.Println("正常") } else if relativeLoad1 < 3.0 { fmt.Println("较高") } else { fmt.Println("过高") } } // 获取运行队列中的任务数 misc, err := load.Misc() if err == nil { fmt.Printf("运行中进程数: %d\n", misc.ProcsRunning) fmt.Printf("总进程数: %d\n", misc.ProcsTotal) } } // 获取进程信息 func getProcessInfo(limit int) { fmt.Printf("\n=== 进程信息(前%d个) ===\n", limit) processes, err := process.Processes() if err != nil { fmt.Printf("获取进程列表失败: %v\n", err) return } fmt.Printf("总进程数: %d\n", len(processes)) if limit > len(processes) { limit = len(processes) } count := 0 for _, p := range processes { if count >= limit { break } name, err := p.Name() if err != nil { continue } // 只显示有意义(非空)的进程 if name == "" || name == " " { continue } cmdline, _ := p.Cmdline() memInfo, _ := p.MemoryInfo() cpuPercent, _ := p.CPUPercent() count++ fmt.Printf("\n%d. PID: %d\n", count, p.Pid) fmt.Printf(" 名称: %s\n", name) if cmdline != "" && len(cmdline) < 100 { // 限制命令行长度 fmt.Printf(" 命令: %s\n", cmdline) } if memInfo != nil { fmt.Printf(" 内存: %.2f MB\n", float64(memInfo.RSS)/(1024*1024)) } if cpuPercent > 0 { fmt.Printf(" CPU: %.2f%%\n", cpuPercent) } } } // 获取运行时信息 func getRuntimeInfo() { fmt.Println("\n=== Go运行时信息 ===") fmt.Printf("Go版本: %s\n", runtime.Version()) fmt.Printf("操作系统: %s\n", runtime.GOOS) fmt.Printf("CPU架构: %s\n", runtime.GOARCH) fmt.Printf("GOROOT: %s\n", runtime.GOROOT()) fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Printf("CPU核心数: %d\n", runtime.NumCPU()) fmt.Printf("Goroutine数: %d\n", runtime.NumGoroutine()) } // 快速收集一次指标 func getQuickMetrics() { fmt.Println("正在收集系统指标...") // 1. CPU使用率 cpuPercent, _ := cpu.Percent(100*time.Millisecond, false) // 2. 内存使用率 memInfo, _ := mem.VirtualMemory() // 3. 磁盘使用率(只检查根分区) rootUsage, _ := disk.Usage("/") currentTime := time.Now().Format("15:04:05") fmt.Printf("时间: %s\n", currentTime) if len(cpuPercent) > 0 { fmt.Printf("CPU使用率: %.2f%%\n", cpuPercent[0]) } if memInfo != nil { fmt.Printf("内存使用率: %.2f%%\n", memInfo.UsedPercent) fmt.Printf("可用内存: %.2f GB\n", float64(memInfo.Available)/(1024*1024*1024)) } if rootUsage != nil { fmt.Printf("根分区使用率: %.2f%%\n", rootUsage.UsedPercent) } }