From cfde75e21e9ac3501812aef506cc7b2fdf3f412c Mon Sep 17 00:00:00 2001 From: yumusb <43062104+yumusb@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:37:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A3=81=E7=9B=98=E9=87=87=E9=9B=86?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A1=AC=E7=9B=98=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=8F=AA=E9=87=87=E9=9B=86=E7=B3=BB=E7=BB=9F=E7=9B=98?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 默认采集所有真实存储设备而非仅根分区 - 通过设备路径白名单识别真实磁盘(块设备/网络存储) - 排除 tmpfs、proc、cgroup 等虚拟文件系统 - 排除 macOS APFS 冗余系统卷(Preboot/VM/Update 等) --- pkg/agent/collector/disk.go | 68 ++++++++++++++++++++++++++++++++++--- pkg/agent/config/config.go | 14 ++++---- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/pkg/agent/collector/disk.go b/pkg/agent/collector/disk.go index ec61350..dd9b561 100644 --- a/pkg/agent/collector/disk.go +++ b/pkg/agent/collector/disk.go @@ -1,11 +1,24 @@ package collector import ( + "strings" + "github.com/dushixiang/pika/internal/protocol" "github.com/dushixiang/pika/pkg/agent/config" "github.com/shirou/gopsutil/v4/disk" ) +// 不以 /dev/ 开头但仍是真实存储的文件系统类型 +var realFSTypes = map[string]bool{ + "nfs": true, + "nfs4": true, + "cifs": true, + "smbfs": true, + "zfs": true, + "glusterfs": true, + "cephfs": true, +} + // DiskCollector 磁盘监控采集器 type DiskCollector struct { config *config.Config @@ -18,6 +31,43 @@ func NewDiskCollector(cfg *config.Config) *DiskCollector { } } +// isRealDisk 判断是否为真实存储设备 +func isRealDisk(device, fstype string) bool { + // Windows 盘符 + if len(device) == 2 && device[1] == ':' { + return true + } + // Unix 块设备 + if strings.HasPrefix(device, "/dev/") { + return true + } + // 网络/集群存储 + return realFSTypes[fstype] +} + +// macOS APFS 容器内与数据卷共享物理空间的系统辅助卷 +var macosSystemVolumes = map[string]bool{ + "Preboot": true, + "VM": true, + "Update": true, + "xarts": true, + "iSCPreboot": true, + "Hardware": true, +} + +// isMacOSRedundant 判断是否为 macOS APFS 冗余系统卷 +func isMacOSRedundant(mountPoint, fstype string) bool { + if fstype != "apfs" { + return false + } + const prefix = "/System/Volumes/" + if !strings.HasPrefix(mountPoint, prefix) { + return false + } + volumeName := strings.TrimPrefix(mountPoint, prefix) + return macosSystemVolumes[volumeName] +} + // Collect 采集磁盘数据 // 只采集配置的 DiskInclude 白名单中的挂载点 func (d *DiskCollector) Collect() ([]protocol.DiskData, error) { @@ -28,6 +78,16 @@ func (d *DiskCollector) Collect() ([]protocol.DiskData, error) { var diskDataList []protocol.DiskData for _, partition := range partitions { + // 跳过虚拟文件系统 + if !isRealDisk(partition.Device, partition.Fstype) { + continue + } + + // 跳过 macOS APFS 冗余系统卷(与 Data 共享物理空间) + if isMacOSRedundant(partition.Mountpoint, partition.Fstype) { + continue + } + // 检查是否在白名单中 if !d.config.ShouldIncludeDiskMountPoint(partition.Mountpoint) { continue @@ -39,12 +99,12 @@ func (d *DiskCollector) Collect() ([]protocol.DiskData, error) { continue // 跳过无法访问的分区 } - // 跳过容量为 0 的分区(可能是虚拟文件系统) + // 跳过容量为 0 的分区 if usage.Total == 0 { continue } - diskData := protocol.DiskData{ + diskDataList = append(diskDataList, protocol.DiskData{ MountPoint: partition.Mountpoint, Device: partition.Device, Fstype: partition.Fstype, @@ -52,9 +112,7 @@ func (d *DiskCollector) Collect() ([]protocol.DiskData, error) { Used: usage.Used, Free: usage.Free, UsagePercent: usage.UsedPercent, - } - - diskDataList = append(diskDataList, diskData) + }) } // 所有白名单分区均采集失败时,返回空列表表示异常 diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index e1a091c..a052fd9 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -388,23 +388,21 @@ func (c *Config) ShouldExcludeNetworkInterface(interfaceName string) bool { } // GetDiskInclude 获取磁盘包含的挂载点列表(白名单) -// 如果配置为空,返回默认的根分区匹配规则 -// Linux/macOS: ["/"] -// Windows: ["C:"] +// 返回 nil 表示未配置白名单,采集所有挂载点 func (c *Config) GetDiskInclude() []string { if len(c.Collector.DiskInclude) == 0 { - if runtime.GOOS == "windows" { - return []string{"C:"} - } - return []string{"/"} + return nil } return c.Collector.DiskInclude } // ShouldIncludeDiskMountPoint 检查挂载点是否应该被采集 -// 只有在 DiskInclude 白名单中的挂载点才会被采集 +// 未配置白名单时采集所有挂载点 func (c *Config) ShouldIncludeDiskMountPoint(mountPoint string) bool { includeMounts := c.GetDiskInclude() + if len(includeMounts) == 0 { + return true // 未配置白名单,采集所有 + } for _, mount := range includeMounts { if mountPoint == mount { return true