diff --git a/monitoring/unit/disk.go b/monitoring/unit/disk.go index 3497d15..5222d9f 100644 --- a/monitoring/unit/disk.go +++ b/monitoring/unit/disk.go @@ -1,6 +1,8 @@ package monitoring import ( + "strings" + "github.com/shirou/gopsutil/disk" ) @@ -11,19 +13,17 @@ type DiskInfo struct { func Disk() DiskInfo { diskinfo := DiskInfo{} - usage, err := disk.Partitions(true) + usage, err := disk.Partitions(false) // 使用 false 只获取物理分区 if err != nil { diskinfo.Total = 0 diskinfo.Used = 0 } else { for _, part := range usage { - if part.Mountpoint != "/tmp" && part.Mountpoint != "/var/tmp" && part.Mountpoint != "/dev/shm" { - // Skip /tmp, /var/tmp, and /dev/shm - // 获取磁盘使用情况 + // 排除临时文件系统和网络驱动器 + if isPhysicalDisk(part) { u, err := disk.Usage(part.Mountpoint) if err != nil { - diskinfo.Total = 0 - diskinfo.Used = 0 + continue } else { diskinfo.Total += u.Total diskinfo.Used += u.Used @@ -33,3 +33,39 @@ func Disk() DiskInfo { } return diskinfo } + +// isPhysicalDisk 判断分区是否为物理磁盘 +func isPhysicalDisk(part disk.PartitionStat) bool { + mountpoint := strings.ToLower(part.Mountpoint) + // 临时文件系统 + if mountpoint == "/tmp" || mountpoint == "/var/tmp" || mountpoint == "/dev/shm" || + mountpoint == "/run" || mountpoint == "/run/lock" { + return false + } + + fstype := strings.ToLower(part.Fstype) + // 网络驱动器 + if strings.HasPrefix(fstype, "nfs") || strings.HasPrefix(fstype, "cifs") || + strings.HasPrefix(fstype, "smb") || fstype == "vboxsf" || fstype == "9p" || + strings.Contains(fstype, "fuse") { + return false + } + // Windows 网络驱动器通常是映射盘符,但不容易通过fstype判断 + // 可以通过opts判断,Windows网络驱动通常有相关选项 + optsStr := strings.ToLower(part.Opts) + if strings.Contains(optsStr, "remote") || strings.Contains(optsStr, "network") { + return false + } + + // Docker overlay + if fstype == "overlay" { + return false + } + + // 虚拟内存 + if strings.HasPrefix(part.Device, "/dev/loop") || fstype == "devtmpfs" || fstype == "tmpfs" { + return false + } + + return true +}