|
1 | 1 | package analytic
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + stdnet "net" |
| 5 | + "runtime" |
| 6 | + "time" |
| 7 | + |
4 | 8 | "github.com/shirou/gopsutil/v4/cpu"
|
5 | 9 | "github.com/shirou/gopsutil/v4/disk"
|
6 | 10 | "github.com/shirou/gopsutil/v4/net"
|
7 | 11 | "github.com/uozi-tech/cosy/logger"
|
8 |
| - "runtime" |
9 |
| - "time" |
10 | 12 | )
|
11 | 13 |
|
12 | 14 | func getTotalDiskIO() (read, write uint64) {
|
@@ -68,25 +70,90 @@ func recordCpu(now time.Time) {
|
68 | 70 | }
|
69 | 71 |
|
70 | 72 | func recordNetwork(now time.Time) {
|
71 |
| - network, err := net.IOCounters(false) |
| 73 | + // Get separate statistics for each interface |
| 74 | + networkStats, err := net.IOCounters(true) |
72 | 75 | if err != nil {
|
73 | 76 | logger.Error(err)
|
74 | 77 | return
|
75 | 78 | }
|
76 | 79 |
|
77 |
| - if len(network) == 0 { |
| 80 | + if len(networkStats) == 0 { |
78 | 81 | return
|
79 | 82 | }
|
| 83 | + |
| 84 | + // Get all network interfaces |
| 85 | + interfaces, err := stdnet.Interfaces() |
| 86 | + if err != nil { |
| 87 | + logger.Error(err) |
| 88 | + return |
| 89 | + } |
| 90 | + |
| 91 | + var totalBytesRecv uint64 |
| 92 | + var totalBytesSent uint64 |
| 93 | + var externalInterfaceFound bool |
| 94 | + |
| 95 | + // Iterate through all interfaces to find external ones |
| 96 | + for _, iface := range interfaces { |
| 97 | + // Skip interfaces that are down |
| 98 | + if iface.Flags&stdnet.FlagUp == 0 { |
| 99 | + continue |
| 100 | + } |
| 101 | + |
| 102 | + // Get IP addresses for the interface |
| 103 | + addrs, err := iface.Addrs() |
| 104 | + if err != nil { |
| 105 | + logger.Error(err) |
| 106 | + continue |
| 107 | + } |
| 108 | + |
| 109 | + // Check if this is an external interface |
| 110 | + for _, addr := range addrs { |
| 111 | + if ipNet, ok := addr.(*stdnet.IPNet); ok { |
| 112 | + // Exclude loopback addresses and private IPs |
| 113 | + if !ipNet.IP.IsLoopback() { |
| 114 | + // Found external interface, accumulate its statistics |
| 115 | + for _, stat := range networkStats { |
| 116 | + if stat.Name == iface.Name { |
| 117 | + totalBytesRecv += stat.BytesRecv |
| 118 | + totalBytesSent += stat.BytesSent |
| 119 | + externalInterfaceFound = true |
| 120 | + break |
| 121 | + } |
| 122 | + } |
| 123 | + break |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + // If no external interface is found, use fallback option |
| 130 | + if !externalInterfaceFound { |
| 131 | + // Fallback: use all non-loopback interfaces |
| 132 | + for _, iface := range interfaces { |
| 133 | + if iface.Flags&stdnet.FlagLoopback == 0 && iface.Flags&stdnet.FlagUp != 0 { |
| 134 | + for _, stat := range networkStats { |
| 135 | + if stat.Name == iface.Name { |
| 136 | + totalBytesRecv += stat.BytesRecv |
| 137 | + totalBytesSent += stat.BytesSent |
| 138 | + break |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + } |
| 143 | + } |
| 144 | + |
| 145 | + LastNetRecv = totalBytesRecv |
| 146 | + LastNetSent = totalBytesSent |
| 147 | + |
80 | 148 | NetRecvRecord = append(NetRecvRecord, Usage[uint64]{
|
81 | 149 | Time: now,
|
82 |
| - Usage: network[0].BytesRecv - LastNetRecv, |
| 150 | + Usage: totalBytesRecv - LastNetRecv, |
83 | 151 | })
|
84 | 152 | NetSentRecord = append(NetSentRecord, Usage[uint64]{
|
85 | 153 | Time: now,
|
86 |
| - Usage: network[0].BytesSent - LastNetSent, |
| 154 | + Usage: totalBytesSent - LastNetSent, |
87 | 155 | })
|
88 |
| - LastNetRecv = network[0].BytesRecv |
89 |
| - LastNetSent = network[0].BytesSent |
| 156 | + |
90 | 157 | if len(NetRecvRecord) > 100 {
|
91 | 158 | NetRecvRecord = NetRecvRecord[1:]
|
92 | 159 | }
|
|
0 commit comments