package vppstats import ( "log" "time" "go.fd.io/govpp/adapter/statsclient" "go.fd.io/govpp/api" "go.fd.io/govpp/core" ) // StartStatsRoutine starts a goroutine that queries VPP interface stats at the specified interval func StartStatsRoutine(statsSocketPath string, period time.Duration) { go statsRoutine(statsSocketPath, period) } func statsRoutine(statsSocketPath string, period time.Duration) { 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) ticker := time.NewTicker(period) defer ticker.Stop() for { select { case <-ticker.C: queryInterfaceStats(c) } } } func queryInterfaceStats(c *core.StatsConnection) { 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 } // Now you have properly structured data for _, iface := range stats.Interfaces { log.Printf("Interface %d (%s):", iface.InterfaceIndex, iface.InterfaceName) log.Printf(" RX: %d packets, %d bytes", iface.Rx.Packets, iface.Rx.Bytes) log.Printf(" TX: %d packets, %d bytes", iface.Tx.Packets, iface.Tx.Bytes) log.Printf(" RX Errors: %d, TX Errors: %d", iface.RxErrors, iface.TxErrors) log.Printf(" Drops: %d, Punts: %d", iface.Drops, iface.Punts) } log.Printf("Retrieved stats for %d interfaces", len(stats.Interfaces)) }