@@ -2,65 +2,13 @@ package analytic
2
2
3
3
import (
4
4
"fmt"
5
- "math"
6
5
7
6
"github.com/dustin/go-humanize"
8
7
"github.com/pkg/errors"
9
8
"github.com/shirou/gopsutil/v4/disk"
10
- "github.com/shirou/gopsutil/v4/mem"
11
9
"github.com/spf13/cast"
12
10
)
13
11
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
-
64
12
func GetDiskStat () (DiskStat , error ) {
65
13
// Get all partitions
66
14
partitions , err := disk .Partitions (false )
@@ -71,6 +19,8 @@ func GetDiskStat() (DiskStat, error) {
71
19
var totalSize uint64
72
20
var totalUsed uint64
73
21
var partitionStats []PartitionStat
22
+ // Track partitions to avoid double counting same partition with multiple mount points
23
+ partitionUsage := make (map [string ]* disk.UsageStat )
74
24
75
25
// Get usage for each partition
76
26
for _ , partition := range partitions {
@@ -85,6 +35,7 @@ func GetDiskStat() (DiskStat, error) {
85
35
continue
86
36
}
87
37
38
+ // Create partition stat for display purposes
88
39
partitionStat := PartitionStat {
89
40
Mountpoint : partition .Mountpoint ,
90
41
Device : partition .Device ,
@@ -94,10 +45,15 @@ func GetDiskStat() (DiskStat, error) {
94
45
Free : humanize .Bytes (usage .Free ),
95
46
Percentage : cast .ToFloat64 (fmt .Sprintf ("%.2f" , usage .UsedPercent )),
96
47
}
97
-
98
48
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
+ }
101
57
}
102
58
103
59
// Calculate overall percentage
0 commit comments