mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-08 14:36:13 +00:00
Exclude virtual interfaces from network stats
Switch net.IOCounters to per-interface mode and aggregate traffic while excluding loopback and common virtual/tunnel interfaces. Adds isVirtualInterface helper to filter interfaces by exact names and prefixes (docker, veth, tun, wg, tailscale, etc.), sums BytesSent/BytesRecv across valid interfaces, and assigns the totals to status.NetTraffic. Removes the previous warning branch when no counters were found and preserves NetIO rate calculations using lastStatus.
This commit is contained in:
@@ -315,13 +315,21 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status {
|
||||
}
|
||||
|
||||
// Network stats
|
||||
ioStats, err := net.IOCounters(false)
|
||||
ioStats, err := net.IOCounters(true)
|
||||
if err != nil {
|
||||
logger.Warning("get io counters failed:", err)
|
||||
} else if len(ioStats) > 0 {
|
||||
ioStat := ioStats[0]
|
||||
status.NetTraffic.Sent = ioStat.BytesSent
|
||||
status.NetTraffic.Recv = ioStat.BytesRecv
|
||||
} else {
|
||||
var totalSent, totalRecv uint64
|
||||
for _, iface := range ioStats {
|
||||
name := strings.ToLower(iface.Name)
|
||||
if isVirtualInterface(name) {
|
||||
continue
|
||||
}
|
||||
totalSent += iface.BytesSent
|
||||
totalRecv += iface.BytesRecv
|
||||
}
|
||||
status.NetTraffic.Sent = totalSent
|
||||
status.NetTraffic.Recv = totalRecv
|
||||
|
||||
if lastStatus != nil {
|
||||
duration := now.Sub(lastStatus.T)
|
||||
@@ -331,8 +339,6 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status {
|
||||
status.NetIO.Up = up
|
||||
status.NetIO.Down = down
|
||||
}
|
||||
} else {
|
||||
logger.Warning("can not find io counters")
|
||||
}
|
||||
|
||||
// TCP/UDP connections
|
||||
@@ -860,6 +866,34 @@ func (s *ServerService) GetXrayLogs(
|
||||
return entries
|
||||
}
|
||||
|
||||
// isVirtualInterface returns true for loopback and virtual/tunnel interfaces
|
||||
// that should be excluded from network traffic statistics.
|
||||
func isVirtualInterface(name string) bool {
|
||||
// Exact matches
|
||||
if name == "lo" || name == "lo0" {
|
||||
return true
|
||||
}
|
||||
// Prefix matches for virtual/tunnel interfaces
|
||||
virtualPrefixes := []string{
|
||||
"loopback",
|
||||
"docker",
|
||||
"br-",
|
||||
"veth",
|
||||
"virbr",
|
||||
"tun",
|
||||
"tap",
|
||||
"wg",
|
||||
"tailscale",
|
||||
"zt",
|
||||
}
|
||||
for _, prefix := range virtualPrefixes {
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func logEntryContains(line string, suffixes []string) bool {
|
||||
for _, sfx := range suffixes {
|
||||
if strings.Contains(line, sfx+"]") {
|
||||
|
||||
Reference in New Issue
Block a user