Files
komari-agent/monitoring/unit/disk.go

147 lines
3.2 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 monitoring
import (
"fmt"
"strings"
"github.com/komari-monitor/komari-agent/cmd/flags"
"github.com/shirou/gopsutil/v4/disk"
)
type DiskInfo struct {
Total uint64 `json:"total"`
Used uint64 `json:"used"`
}
func Disk() DiskInfo {
diskinfo := DiskInfo{}
usage, err := disk.Partitions(true)
if err != nil {
diskinfo.Total = 0
diskinfo.Used = 0
} else {
// 如果指定了自定义挂载点,只统计指定的挂载点
if flags.IncludeMountpoints != "" {
includeMounts := strings.Split(flags.IncludeMountpoints, ";")
for _, mountpoint := range includeMounts {
mountpoint = strings.TrimSpace(mountpoint)
if mountpoint != "" {
u, err := disk.Usage(mountpoint)
if err != nil {
continue
} else {
diskinfo.Total += u.Total
diskinfo.Used += u.Used
}
}
}
} else {
// 使用默认逻辑,排除临时文件系统和网络驱动器
for _, part := range usage {
if isPhysicalDisk(part) {
u, err := disk.Usage(part.Mountpoint)
if err != nil {
continue
} else {
diskinfo.Total += u.Total
diskinfo.Used += u.Used
}
}
}
}
}
return diskinfo
}
// isPhysicalDisk 判断分区是否为物理磁盘
func isPhysicalDisk(part disk.PartitionStat) bool {
// 对于LXC等基于loop的根文件系统始终包含根挂载点
if part.Mountpoint == "/" {
return true
}
mountpoint := strings.ToLower(part.Mountpoint)
// 排除挂载点
var mountpointsToExclude = []string{
"/tmp",
"/var/tmp",
"/dev/shm",
"/run",
"/run/lock",
"/run/user",
"/var/lib/containers",
"/var/lib/docker",
"/proc",
"/dev/pts",
"/sys",
"/sys/fs/cgroup",
"/dev/mqueue",
"/etc/resolv.conf",
"/etc/host", // /etc/hosts,/etc/hostname
}
for _, mp := range mountpointsToExclude {
if mountpoint == mp || strings.HasPrefix(mountpoint, mp) {
return false
}
}
fstype := strings.ToLower(part.Fstype)
var fstypeToExclude = []string{
"tmpfs",
"devtmpfs",
"nfs",
"cifs",
"smb",
"vboxsf",
"9p",
"fuse",
"overlay",
"proc",
"devpts",
"sysfs",
"cgroup",
"mqueue",
}
for _, fs := range fstypeToExclude {
if fstype == fs || strings.HasPrefix(fstype, fs) {
return false
}
}
// Windows 网络驱动器通常是映射盘符但不容易通过fstype判断
// 可以通过opts判断Windows网络驱动通常有相关选项
optsStr := strings.ToLower(strings.Join(part.Opts, ","))
if strings.Contains(optsStr, "remote") || strings.Contains(optsStr, "network") {
return false
}
// 虚拟内存
if strings.HasPrefix(part.Device, "/dev/loop") {
return false
}
return true
}
func DiskList() ([]string, error) {
diskList := []string{}
if flags.IncludeMountpoints != "" {
includeMounts := strings.Split(flags.IncludeMountpoints, ";")
for _, mountpoint := range includeMounts {
mountpoint = strings.TrimSpace(mountpoint)
if mountpoint != "" {
diskList = append(diskList, mountpoint)
}
}
} else {
usage, err := disk.Partitions(true)
if err != nil {
return nil, err
}
for _, part := range usage {
if isPhysicalDisk(part) {
diskList = append(diskList, fmt.Sprintf("%s (%s)", part.Mountpoint, part.Fstype))
}
}
}
return diskList, nil
}