Files
govpp-snmp-agentx/vppstats/stats.go

75 lines
1.9 KiB
Go

package vppstats
import (
"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)
// 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) {
logger.Debugf("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) {
// 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)
}
}