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:
MHSanaei
2026-05-06 17:28:41 +02:00
parent 9be11e109e
commit ad30298700

View File

@@ -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+"]") {