Skip to content

Commit 2734da5

Browse files
committed
fix: disk statistics issue #1119
1 parent 0f71fa4 commit 2734da5

File tree

3 files changed

+73
-55
lines changed

3 files changed

+73
-55
lines changed

internal/analytic/stat.go renamed to internal/analytic/disk.go

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,13 @@ package analytic
22

33
import (
44
"fmt"
5-
"math"
65

76
"github.com/dustin/go-humanize"
87
"github.com/pkg/errors"
98
"github.com/shirou/gopsutil/v4/disk"
10-
"github.com/shirou/gopsutil/v4/mem"
119
"github.com/spf13/cast"
1210
)
1311

14-
type MemStat struct {
15-
Total string `json:"total"`
16-
Used string `json:"used"`
17-
Cached string `json:"cached"`
18-
Free string `json:"free"`
19-
SwapUsed string `json:"swap_used"`
20-
SwapTotal string `json:"swap_total"`
21-
SwapCached string `json:"swap_cached"`
22-
SwapPercent float64 `json:"swap_percent"`
23-
Pressure float64 `json:"pressure"`
24-
}
25-
26-
type PartitionStat struct {
27-
Mountpoint string `json:"mountpoint"`
28-
Device string `json:"device"`
29-
Fstype string `json:"fstype"`
30-
Total string `json:"total"`
31-
Used string `json:"used"`
32-
Free string `json:"free"`
33-
Percentage float64 `json:"percentage"`
34-
}
35-
36-
type DiskStat struct {
37-
Total string `json:"total"`
38-
Used string `json:"used"`
39-
Percentage float64 `json:"percentage"`
40-
Writes Usage[uint64] `json:"writes"`
41-
Reads Usage[uint64] `json:"reads"`
42-
Partitions []PartitionStat `json:"partitions"`
43-
}
44-
45-
func GetMemoryStat() (MemStat, error) {
46-
memoryStat, err := mem.VirtualMemory()
47-
if err != nil {
48-
return MemStat{}, errors.Wrap(err, "error analytic getMemoryStat")
49-
}
50-
return MemStat{
51-
Total: humanize.Bytes(memoryStat.Total),
52-
Used: humanize.Bytes(memoryStat.Used),
53-
Cached: humanize.Bytes(memoryStat.Cached),
54-
Free: humanize.Bytes(memoryStat.Free),
55-
SwapUsed: humanize.Bytes(memoryStat.SwapTotal - memoryStat.SwapFree),
56-
SwapTotal: humanize.Bytes(memoryStat.SwapTotal),
57-
SwapCached: humanize.Bytes(memoryStat.SwapCached),
58-
SwapPercent: cast.ToFloat64(fmt.Sprintf("%.2f",
59-
100*float64(memoryStat.SwapTotal-memoryStat.SwapFree)/math.Max(float64(memoryStat.SwapTotal), 1))),
60-
Pressure: cast.ToFloat64(fmt.Sprintf("%.2f", memoryStat.UsedPercent)),
61-
}, nil
62-
}
63-
6412
func GetDiskStat() (DiskStat, error) {
6513
// Get all partitions
6614
partitions, err := disk.Partitions(false)
@@ -71,6 +19,8 @@ func GetDiskStat() (DiskStat, error) {
7119
var totalSize uint64
7220
var totalUsed uint64
7321
var partitionStats []PartitionStat
22+
// Track partitions to avoid double counting same partition with multiple mount points
23+
partitionUsage := make(map[string]*disk.UsageStat)
7424

7525
// Get usage for each partition
7626
for _, partition := range partitions {
@@ -85,6 +35,7 @@ func GetDiskStat() (DiskStat, error) {
8535
continue
8636
}
8737

38+
// Create partition stat for display purposes
8839
partitionStat := PartitionStat{
8940
Mountpoint: partition.Mountpoint,
9041
Device: partition.Device,
@@ -94,10 +45,15 @@ func GetDiskStat() (DiskStat, error) {
9445
Free: humanize.Bytes(usage.Free),
9546
Percentage: cast.ToFloat64(fmt.Sprintf("%.2f", usage.UsedPercent)),
9647
}
97-
9848
partitionStats = append(partitionStats, partitionStat)
99-
totalSize += usage.Total
100-
totalUsed += usage.Used
49+
50+
// Only count each partition device once for total calculation
51+
// This handles cases where same partition is mounted multiple times (e.g., bind mounts, overlayfs)
52+
if _, exists := partitionUsage[partition.Device]; !exists {
53+
partitionUsage[partition.Device] = usage
54+
totalSize += usage.Total
55+
totalUsed += usage.Used
56+
}
10157
}
10258

10359
// Calculate overall percentage

internal/analytic/memory.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package analytic
2+
3+
import (
4+
"fmt"
5+
"math"
6+
7+
"github.com/dustin/go-humanize"
8+
"github.com/pkg/errors"
9+
"github.com/shirou/gopsutil/v4/mem"
10+
"github.com/spf13/cast"
11+
)
12+
13+
func GetMemoryStat() (MemStat, error) {
14+
memoryStat, err := mem.VirtualMemory()
15+
if err != nil {
16+
return MemStat{}, errors.Wrap(err, "error analytic getMemoryStat")
17+
}
18+
return MemStat{
19+
Total: humanize.Bytes(memoryStat.Total),
20+
Used: humanize.Bytes(memoryStat.Used),
21+
Cached: humanize.Bytes(memoryStat.Cached),
22+
Free: humanize.Bytes(memoryStat.Free),
23+
SwapUsed: humanize.Bytes(memoryStat.SwapTotal - memoryStat.SwapFree),
24+
SwapTotal: humanize.Bytes(memoryStat.SwapTotal),
25+
SwapCached: humanize.Bytes(memoryStat.SwapCached),
26+
SwapPercent: cast.ToFloat64(fmt.Sprintf("%.2f",
27+
100*float64(memoryStat.SwapTotal-memoryStat.SwapFree)/math.Max(float64(memoryStat.SwapTotal), 1))),
28+
Pressure: cast.ToFloat64(fmt.Sprintf("%.2f", memoryStat.UsedPercent)),
29+
}, nil
30+
}

internal/analytic/types.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package analytic
2+
3+
type MemStat struct {
4+
Total string `json:"total"`
5+
Used string `json:"used"`
6+
Cached string `json:"cached"`
7+
Free string `json:"free"`
8+
SwapUsed string `json:"swap_used"`
9+
SwapTotal string `json:"swap_total"`
10+
SwapCached string `json:"swap_cached"`
11+
SwapPercent float64 `json:"swap_percent"`
12+
Pressure float64 `json:"pressure"`
13+
}
14+
15+
type PartitionStat struct {
16+
Mountpoint string `json:"mountpoint"`
17+
Device string `json:"device"`
18+
Fstype string `json:"fstype"`
19+
Total string `json:"total"`
20+
Used string `json:"used"`
21+
Free string `json:"free"`
22+
Percentage float64 `json:"percentage"`
23+
}
24+
25+
type DiskStat struct {
26+
Total string `json:"total"`
27+
Used string `json:"used"`
28+
Percentage float64 `json:"percentage"`
29+
Writes Usage[uint64] `json:"writes"`
30+
Reads Usage[uint64] `json:"reads"`
31+
Partitions []PartitionStat `json:"partitions"`
32+
}

0 commit comments

Comments
 (0)