123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- 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"
- )
- type MemStat struct {
- Total string `json:"total"`
- Used string `json:"used"`
- Cached string `json:"cached"`
- Free string `json:"free"`
- SwapUsed string `json:"swap_used"`
- SwapTotal string `json:"swap_total"`
- SwapCached string `json:"swap_cached"`
- SwapPercent float64 `json:"swap_percent"`
- 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"`
- Partitions []PartitionStat `json:"partitions"`
- }
- func GetMemoryStat() (MemStat, error) {
- memoryStat, err := mem.VirtualMemory()
- if err != nil {
- return MemStat{}, errors.Wrap(err, "error analytic getMemoryStat")
- }
- return MemStat{
- Total: humanize.Bytes(memoryStat.Total),
- Used: humanize.Bytes(memoryStat.Used),
- Cached: humanize.Bytes(memoryStat.Cached),
- Free: humanize.Bytes(memoryStat.Free),
- SwapUsed: humanize.Bytes(memoryStat.SwapTotal - memoryStat.SwapFree),
- SwapTotal: humanize.Bytes(memoryStat.SwapTotal),
- SwapCached: humanize.Bytes(memoryStat.SwapCached),
- SwapPercent: cast.ToFloat64(fmt.Sprintf("%.2f",
- 100*float64(memoryStat.SwapTotal-memoryStat.SwapFree)/math.Max(float64(memoryStat.SwapTotal), 1))),
- Pressure: cast.ToFloat64(fmt.Sprintf("%.2f", memoryStat.UsedPercent)),
- }, nil
- }
- func GetDiskStat() (DiskStat, error) {
- // Get all partitions
- partitions, err := disk.Partitions(false)
- if err != nil {
- 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(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]
- }
|