From efc9b1c365a299498fee351a73480a7837d7c2d7 Mon Sep 17 00:00:00 2001 From: Jacky Date: Sat, 15 Mar 2025 10:14:21 +0800 Subject: [PATCH] refactor(analytic): improved network stat #913 --- internal/analytic/network.go | 56 ++++++++++++++++++++++++++++ internal/analytic/record.go | 17 ++++++--- internal/transport/transport_test.go | 2 +- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/internal/analytic/network.go b/internal/analytic/network.go index 314bf8b7..c6f51f1a 100644 --- a/internal/analytic/network.go +++ b/internal/analytic/network.go @@ -2,6 +2,7 @@ package analytic import ( stdnet "net" + "strings" "github.com/shirou/gopsutil/v4/net" "github.com/uozi-tech/cosy/logger" @@ -46,6 +47,17 @@ func GetNetworkStat() (data *net.IOCountersStat, err error) { continue } + // Skip common virtual interfaces by name pattern + if isVirtualInterface(iface.Name) { + continue + } + + // Handle container main interfaces like eth0 in container environments + if isContainerInterface(iface.Name) { + externalInterfaces[iface.Name] = true + continue + } + // Get addresses for this interface addrs, err := iface.Addrs() if err != nil { @@ -106,6 +118,50 @@ func GetNetworkStat() (data *net.IOCountersStat, err error) { }, nil } +// isVirtualInterface checks if the interface is a virtual one based on name patterns +func isVirtualInterface(name string) bool { + // Common virtual interface name patterns + virtualPatterns := []string{ + "veth", "virbr", "vnet", "vmnet", "vboxnet", "docker", + "br-", "bridge", "tun", "tap", "bond", "dummy", + "vpn", "ipsec", "gre", "sit", "vlan", "virt", + "wg", "vmk", "ib", "vxlan", "geneve", "ovs", + "hyperv", "hyper-v", "awdl", "llw", "utun", + "vpn", "zt", "zerotier", "wireguard", + } + + for _, pattern := range virtualPatterns { + if strings.Contains(strings.ToLower(name), pattern) { + return true + } + } + + return false +} + +// isContainerInterface checks if this is a main container interface +func isContainerInterface(name string) bool { + // Common main container interface patterns + // eth0 is usually the main interface inside containers + // en0, en1 are common physical interfaces on macOS + // ens/enp/eno are common physical interfaces on Linux + containerPatterns := []string{ + "eth0", "en0", "en1", + "ens", "enp", "eno", + "eth1", "eth2", // Potential physical interfaces + "wlan", "wifi", "wl", // Wireless interfaces + "bond0", // Bonded interfaces that might be external + } + + for _, pattern := range containerPatterns { + if strings.HasPrefix(strings.ToLower(name), pattern) { + return true + } + } + + return false +} + // isRealExternalIP checks if an IP is a genuine external (public) IP func isRealExternalIP(ip stdnet.IP, ipNet *stdnet.IPNet) bool { // Skip if it's not a global unicast address diff --git a/internal/analytic/record.go b/internal/analytic/record.go index dc4bcdc1..9a67d70c 100644 --- a/internal/analytic/record.go +++ b/internal/analytic/record.go @@ -68,25 +68,32 @@ func recordCpu(now time.Time) { } func recordNetwork(now time.Time) { - // Get separate statistics for each interface + // Get network statistics using GetNetworkStat which includes Ethernet interfaces networkStats, err := GetNetworkStat() if err != nil { logger.Error(err) return } - LastNetRecv = networkStats.BytesRecv - LastNetSent = networkStats.BytesSent + // Calculate usage since last record + bytesRecv := networkStats.BytesRecv - LastNetRecv + bytesSent := networkStats.BytesSent - LastNetSent + // Update records NetRecvRecord = append(NetRecvRecord, Usage[uint64]{ Time: now, - Usage: networkStats.BytesRecv - LastNetRecv, + Usage: bytesRecv, }) NetSentRecord = append(NetSentRecord, Usage[uint64]{ Time: now, - Usage: networkStats.BytesSent - LastNetSent, + Usage: bytesSent, }) + // Update last values + LastNetRecv = networkStats.BytesRecv + LastNetSent = networkStats.BytesSent + + // Limit record size if len(NetRecvRecord) > 100 { NetRecvRecord = NetRecvRecord[1:] } diff --git a/internal/transport/transport_test.go b/internal/transport/transport_test.go index b138c547..85d263cc 100644 --- a/internal/transport/transport_test.go +++ b/internal/transport/transport_test.go @@ -15,7 +15,7 @@ func TestCreatesTransportWithDefaultSettings(t *testing.T) { require.NoError(t, err) assert.NotNil(t, transport) assert.ObjectsAreEqual(http.ProxyFromEnvironment, transport.Proxy) - assert.Equal(t, settings.ServerSettings.InsecureSkipVerify, transport.TLSClientConfig.InsecureSkipVerify) + assert.Equal(t, settings.HTTPSettings.InsecureSkipVerify, transport.TLSClientConfig.InsecureSkipVerify) } func TestCreatesTransportWithCustomProxy(t *testing.T) {