package vppstats import ( "flag" "log" "time" "go.fd.io/govpp/adapter/statsclient" "go.fd.io/govpp/api" "go.fd.io/govpp/core" "govpp-snmp-example/logger" ) type StatsCallback func(*api.InterfaceStats) var ( // Flags for VPP stats configuration StatsAddr = flag.String("vppstats.addr", "/var/run/vpp/stats.sock", "VPP stats socket path") IfIndexOffset = flag.Int("vppstats.ifindex-offset", 1000, "Offset to add to VPP interface indices for SNMP") Period = flag.Int("vppstats.period", 10, "Interval in seconds for querying VPP interface stats") ) // StartStatsRoutine starts a goroutine that queries VPP interface stats at the configured interval func StartStatsRoutine(callback StatsCallback) { period := time.Duration(*Period) * time.Second go statsRoutine(period, callback) } func statsRoutine(period time.Duration, callback StatsCallback) { logger.Debugf("Starting VPP stats routine with socket: %s, period: %v", *StatsAddr, period) // Create stats client client := statsclient.NewStatsClient(*StatsAddr) // 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) { // 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 { logger.Printf("Failed to get interface stats: %v", err) return } // Always log basic info logger.Printf("Retrieved stats for %d interfaces", len(stats.Interfaces)) // Debug logging for individual interfaces for _, iface := range stats.Interfaces { logger.Debugf("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) } }