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

84 lines
2.2 KiB
Go

package vppstats
import (
"flag"
"log"
"time"
"go.fd.io/govpp/adapter/statsclient"
"go.fd.io/govpp/api"
"go.fd.io/govpp/core"
"govpp-snmp-agentx/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)
}
}