package vppstats import ( "log" "time" "go.fd.io/govpp/adapter/statsclient" "go.fd.io/govpp/api" "go.fd.io/govpp/core" ) type StatsCallback func(*api.InterfaceStats) // StartStatsRoutine starts a goroutine that queries VPP interface stats at the specified interval func StartStatsRoutine(statsSocketPath string, period time.Duration, callback StatsCallback) { go statsRoutine(statsSocketPath, period, callback) } func statsRoutine(statsSocketPath string, period time.Duration, callback StatsCallback) { log.Printf("Starting VPP stats routine with socket: %s, period: %v", statsSocketPath, period) // Create stats client client := statsclient.NewStatsClient(statsSocketPath) // Connect using core.ConnectStats (proper way) c, err := core.ConnectStats(client) if err != nil { log.Printf("Failed to connect to VPP stats: %v", err) return } defer c.Disconnect() // Query stats immediately on startup queryInterfaceStats(c, callback) ticker := time.NewTicker(period) defer ticker.Stop() for { select { case <-ticker.C: queryInterfaceStats(c, callback) } } } func queryInterfaceStats(c *core.StatsConnection, callback StatsCallback) { log.Printf("Querying VPP interface stats at %s", time.Now().Format(time.RFC3339)) // Create the proper struct for interface stats stats := new(api.InterfaceStats) // Use the GetInterfaceStats method - this is the correct approach if err := c.GetInterfaceStats(stats); err != nil { log.Printf("Failed to get interface stats: %v", err) return } // Log basic info log.Printf("Retrieved stats for %d interfaces", len(stats.Interfaces)) for _, iface := range stats.Interfaces { log.Printf("Interface %d (%s): RX %d pkts/%d bytes, TX %d pkts/%d bytes", iface.InterfaceIndex, iface.InterfaceName, iface.Rx.Packets, iface.Rx.Bytes, iface.Tx.Packets, iface.Tx.Bytes) } // Call the callback to update the MIB if callback != nil { callback(stats) } }