|
@@ -2,12 +2,13 @@ package analytic
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "math"
|
|
|
+
|
|
|
"github.com/dustin/go-humanize"
|
|
|
"github.com/pkg/errors"
|
|
|
"github.com/shirou/gopsutil/v4/disk"
|
|
|
"github.com/shirou/gopsutil/v4/mem"
|
|
|
"github.com/spf13/cast"
|
|
|
- "math"
|
|
|
)
|
|
|
|
|
|
type MemStat struct {
|
|
@@ -22,12 +23,23 @@ type MemStat struct {
|
|
|
Pressure float64 `json:"pressure"`
|
|
|
}
|
|
|
|
|
|
+type PartitionStat struct {
|
|
|
+ Mountpoint string `json:"mountpoint"`
|
|
|
+ Device string `json:"device"`
|
|
|
+ Fstype string `json:"fstype"`
|
|
|
+ Total string `json:"total"`
|
|
|
+ Used string `json:"used"`
|
|
|
+ Free string `json:"free"`
|
|
|
+ Percentage float64 `json:"percentage"`
|
|
|
+}
|
|
|
+
|
|
|
type DiskStat struct {
|
|
|
- Total string `json:"total"`
|
|
|
- Used string `json:"used"`
|
|
|
- Percentage float64 `json:"percentage"`
|
|
|
- Writes Usage[uint64] `json:"writes"`
|
|
|
- Reads Usage[uint64] `json:"reads"`
|
|
|
+ Total string `json:"total"`
|
|
|
+ Used string `json:"used"`
|
|
|
+ Percentage float64 `json:"percentage"`
|
|
|
+ Writes Usage[uint64] `json:"writes"`
|
|
|
+ Reads Usage[uint64] `json:"reads"`
|
|
|
+ Partitions []PartitionStat `json:"partitions"`
|
|
|
}
|
|
|
|
|
|
func GetMemoryStat() (MemStat, error) {
|
|
@@ -50,17 +62,87 @@ func GetMemoryStat() (MemStat, error) {
|
|
|
}
|
|
|
|
|
|
func GetDiskStat() (DiskStat, error) {
|
|
|
- diskUsage, err := disk.Usage(".")
|
|
|
-
|
|
|
+ // Get all partitions
|
|
|
+ partitions, err := disk.Partitions(false)
|
|
|
if err != nil {
|
|
|
- return DiskStat{}, errors.Wrap(err, "error analytic getDiskStat")
|
|
|
+ return DiskStat{}, errors.Wrap(err, "error analytic getDiskStat - getting partitions")
|
|
|
+ }
|
|
|
+
|
|
|
+ var totalSize uint64
|
|
|
+ var totalUsed uint64
|
|
|
+ var partitionStats []PartitionStat
|
|
|
+
|
|
|
+ // Get usage for each partition
|
|
|
+ for _, partition := range partitions {
|
|
|
+ usage, err := disk.Usage(partition.Mountpoint)
|
|
|
+ if err != nil {
|
|
|
+ // Skip partitions that can't be accessed
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // Skip virtual filesystems and special filesystems
|
|
|
+ if isVirtualFilesystem(partition.Fstype) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ partitionStat := PartitionStat{
|
|
|
+ Mountpoint: partition.Mountpoint,
|
|
|
+ Device: partition.Device,
|
|
|
+ Fstype: partition.Fstype,
|
|
|
+ Total: humanize.Bytes(usage.Total),
|
|
|
+ Used: humanize.Bytes(usage.Used),
|
|
|
+ Free: humanize.Bytes(usage.Free),
|
|
|
+ Percentage: cast.ToFloat64(fmt.Sprintf("%.2f", usage.UsedPercent)),
|
|
|
+ }
|
|
|
+
|
|
|
+ partitionStats = append(partitionStats, partitionStat)
|
|
|
+ totalSize += usage.Total
|
|
|
+ totalUsed += usage.Used
|
|
|
+ }
|
|
|
+
|
|
|
+ // Calculate overall percentage
|
|
|
+ var overallPercentage float64
|
|
|
+ if totalSize > 0 {
|
|
|
+ overallPercentage = cast.ToFloat64(fmt.Sprintf("%.2f", float64(totalUsed)/float64(totalSize)*100))
|
|
|
}
|
|
|
|
|
|
return DiskStat{
|
|
|
- Used: humanize.Bytes(diskUsage.Used),
|
|
|
- Total: humanize.Bytes(diskUsage.Total),
|
|
|
- Percentage: cast.ToFloat64(fmt.Sprintf("%.2f", diskUsage.UsedPercent)),
|
|
|
+ Used: humanize.Bytes(totalUsed),
|
|
|
+ Total: humanize.Bytes(totalSize),
|
|
|
+ Percentage: overallPercentage,
|
|
|
Writes: DiskWriteRecord[len(DiskWriteRecord)-1],
|
|
|
Reads: DiskReadRecord[len(DiskReadRecord)-1],
|
|
|
+ Partitions: partitionStats,
|
|
|
}, nil
|
|
|
}
|
|
|
+
|
|
|
+// isVirtualFilesystem checks if the filesystem type is virtual
|
|
|
+func isVirtualFilesystem(fstype string) bool {
|
|
|
+ virtualFSTypes := map[string]bool{
|
|
|
+ "proc": true,
|
|
|
+ "sysfs": true,
|
|
|
+ "devfs": true,
|
|
|
+ "devpts": true,
|
|
|
+ "tmpfs": true,
|
|
|
+ "debugfs": true,
|
|
|
+ "securityfs": true,
|
|
|
+ "cgroup": true,
|
|
|
+ "cgroup2": true,
|
|
|
+ "pstore": true,
|
|
|
+ "bpf": true,
|
|
|
+ "tracefs": true,
|
|
|
+ "hugetlbfs": true,
|
|
|
+ "mqueue": true,
|
|
|
+ "overlay": true,
|
|
|
+ "autofs": true,
|
|
|
+ "binfmt_misc": true,
|
|
|
+ "configfs": true,
|
|
|
+ "fusectl": true,
|
|
|
+ "rpc_pipefs": true,
|
|
|
+ "selinuxfs": true,
|
|
|
+ "systemd-1": true,
|
|
|
+ "none": true,
|
|
|
+ }
|
|
|
+
|
|
|
+ return virtualFSTypes[fstype]
|
|
|
+}
|