From 824496c402bae80ec6b0513823351acbb366bc93 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Mon, 9 Jun 2025 17:13:07 +0200 Subject: [PATCH] Add a VppStatsRoutine() alongside main --- go.mod | 17 +++++++++++-- go.sum | 32 ++++++++++++++++++++---- main.go | 5 ++++ vppstats/stats.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 vppstats/stats.go diff --git a/go.mod b/go.mod index aff297f..41831c8 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,20 @@ module govpp-snmp-example -go 1.23.5 +go 1.23.8 -require github.com/posteo/go-agentx v0.2.1 +toolchain go1.23.10 + +require ( + github.com/posteo/go-agentx v0.2.1 + go.fd.io/govpp v0.12.0 +) + +require ( + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/ftrvxmtrx/fd v0.0.0-20150925145434-c6d800382fff // indirect + github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/sys v0.31.0 // indirect +) replace github.com/posteo/go-agentx => ./go-agentx diff --git a/go.sum b/go.sum index 0a074d2..2d7299f 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,34 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/ftrvxmtrx/fd v0.0.0-20150925145434-c6d800382fff h1:zk1wwii7uXmI0znwU+lqg+wFL9G5+vm5I+9rv2let60= +github.com/ftrvxmtrx/fd v0.0.0-20150925145434-c6d800382fff/go.mod h1:yUhRXHewUVJ1k89wHKP68xfzk7kwXUx/DV1nx4EBMbw= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe h1:ewr1srjRCmcQogPQ/NCx6XCk6LGVmsVCc9Y3vvPZj+Y= +github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= +github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= +github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posteo/go-agentx v0.2.1 h1:HO0zO/+GosL0RYEodu7KNH9OF/rL5bJbhXNP1z3hkT8= -github.com/posteo/go-agentx v0.2.1/go.mod h1:EUR75CfAEDstQn3WqCs26Ti64EsggaSXDk2dgxPQ5TI= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.fd.io/govpp v0.12.0 h1:5HnMzsKHSFdxglsFyEhR0g+CzncWiLYXG2NDYgNUrnE= +go.fd.io/govpp v0.12.0/go.mod h1:6qp4J/+jumgXXoowrtVAk13PSXS6+ghPrDG8CyuU/Is= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 8d68026..bfb5522 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,8 @@ import ( "github.com/posteo/go-agentx" "github.com/posteo/go-agentx/pdu" "github.com/posteo/go-agentx/value" + + "govpp-snmp-example/vppstats" ) func main() { @@ -89,6 +91,9 @@ func main() { log.Fatalf("Failed to register: %v", err) } + // Start VPP stats routine + vppstats.StartStatsRoutine() + for { time.Sleep(100 * time.Millisecond) } diff --git a/vppstats/stats.go b/vppstats/stats.go new file mode 100644 index 0000000..3aa1fce --- /dev/null +++ b/vppstats/stats.go @@ -0,0 +1,64 @@ +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 every 10 seconds +func StartStatsRoutine() { + go statsRoutine() +} + +func statsRoutine() { + log.Println("Starting VPP stats routine...") + + // Create stats client + client := statsclient.NewStatsClient("/var/run/vpp/stats.sock") + + // 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() + + ticker := time.NewTicker(10 * time.Second) + 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)) +} \ No newline at end of file