sysmonitord/test/main.go
wuko233 9510e730d5 chore: 添加go.mod和go.sum文件以管理依赖项;
feat: 新增获取服务器信息测试用例
2026-01-26 11:27:25 +08:00

427 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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