1 // Copyright (c) 2018 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
25 "git.fd.io/govpp.git/adapter"
26 "git.fd.io/govpp.git/adapter/statsclient"
27 "git.fd.io/govpp.git/api"
28 "git.fd.io/govpp.git/core"
31 // ------------------------------------------------------------------
32 // Example - Stats API
33 // ------------------------------------------------------------------
34 // The example stats_api demonstrates how to retrieve stats
35 // from the VPP using the new stats API.
36 // ------------------------------------------------------------------
39 statsSocket = flag.String("socket", statsclient.DefaultSocketName, "Path to VPP stats socket")
40 dumpAll = flag.Bool("all", false, "Dump all stats including ones with zero values")
41 pollPeriod = flag.Duration("period", time.Second*5, "Polling interval period")
42 async = flag.Bool("async", false, "Use asynchronous connection")
47 fmt.Fprintf(os.Stderr, "%s: usage [ls|dump|poll|errors|interfaces|nodes|system|buffers|memory] <patterns>...\n", os.Args[0])
55 skipZeros := !*dumpAll
59 patterns = flag.Args()[1:]
63 client *statsclient.StatsClient
64 c *core.StatsConnection
69 var statsChan chan core.ConnectionEvent
70 client = statsclient.NewStatsClient(*statsSocket)
71 c, statsChan, err = core.AsyncConnectStats(client, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval)
73 log.Fatalln("Asynchronous connecting failed:", err)
76 case e := <-statsChan:
77 if e.State == core.Connected {
80 log.Fatalf("VPP stats asynchronous connection failed: %s\n", e.State.String())
84 client = statsclient.NewStatsClient(*statsSocket)
85 c, err = core.ConnectStats(client)
87 log.Fatalln("Connecting failed:", err)
92 switch cmd := flag.Arg(0); cmd {
94 stats := new(api.SystemStats)
95 if err := c.GetSystemStats(stats); err != nil {
96 log.Fatalln("getting system stats failed:", err)
98 fmt.Printf("System stats: %+v\n", stats)
104 fmt.Println("Listing node stats..")
105 stats := new(api.NodeStats)
106 if err := c.GetNodeStats(stats); err != nil {
107 log.Fatalln("getting node stats failed:", err)
110 for _, node := range stats.Nodes {
111 if skipZeros && node.Calls == 0 && node.Suspends == 0 && node.Clocks == 0 && node.Vectors == 0 {
114 fmt.Printf(" - %+v\n", node)
116 fmt.Printf("Listed %d node counters\n", len(stats.Nodes))
119 fmt.Println("Listing interface stats..")
120 stats := new(api.InterfaceStats)
121 if err := c.GetInterfaceStats(stats); err != nil {
122 log.Fatalln("getting interface stats failed:", err)
124 for _, iface := range stats.Interfaces {
125 fmt.Printf(" - %+v\n", iface)
127 fmt.Printf("Listed %d interface counters\n", len(stats.Interfaces))
129 case "poll-interfaces":
133 fmt.Printf("Listing error stats.. %s\n", strings.Join(patterns, " "))
134 stats := new(api.ErrorStats)
135 if err := c.GetErrorStats(stats); err != nil {
136 log.Fatalln("getting error stats failed:", err)
139 for _, counter := range stats.Errors {
141 for _, valuePerWorker := range counter.Values {
142 sum += uint32(valuePerWorker)
145 if skipZeros && sum == 0 {
148 fmt.Printf(" - %v %d (per worker: %v)\n", counter.CounterName, sum, counter.Values)
151 fmt.Printf("Listed %d (%d) error counters\n", n, len(stats.Errors))
154 stats := new(api.BufferStats)
155 if err := c.GetBufferStats(stats); err != nil {
156 log.Fatalln("getting buffer stats failed:", err)
158 fmt.Printf("Buffer stats: %+v\n", stats)
161 stats := new(api.MemoryStats)
162 if err := c.GetMemoryStats(stats); err != nil {
163 log.Fatalln("getting memory stats failed:", err)
165 fmt.Printf("Memory stats: %+v\n", stats)
168 fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " "))
170 dumpStats(client, patterns, skipZeros)
173 fmt.Printf("Polling stats.. %s\n", strings.Join(patterns, " "))
175 pollStats(client, patterns, skipZeros)
177 case "list", "ls", "":
178 fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " "))
180 listStats(client, patterns)
183 fmt.Printf("invalid command: %q\n", cmd)
187 func listStats(client adapter.StatsAPI, patterns []string) {
188 list, err := client.ListStats(patterns...)
190 log.Fatalln("listing stats failed:", err)
193 for _, stat := range list {
194 fmt.Printf(" - %v\n", stat)
197 fmt.Printf("Listed %d stats\n", len(list))
200 func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
201 stats, err := client.DumpStats(patterns...)
203 log.Fatalln("dumping stats failed:", err)
207 for _, stat := range stats {
208 if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
211 fmt.Printf(" - %-50s %25v %+v\n", stat.Name, stat.Type, stat.Data)
215 fmt.Printf("Dumped %d (%d) stats\n", n, len(stats))
218 func pollStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
219 dir, err := client.PrepareDir(patterns...)
221 log.Fatalln("preparing dir failed:", err)
224 tick := time.Tick(*pollPeriod)
227 fmt.Println(time.Now().Format(time.Stamp))
228 for _, stat := range dir.Entries {
229 if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
232 fmt.Printf("%-50s %+v\n", stat.Name, stat.Data)
239 if err := client.UpdateDir(dir); err != nil {
240 if err == adapter.ErrStatsDirStale {
241 if dir, err = client.PrepareDir(patterns...); err != nil {
242 log.Fatalln("preparing dir failed:", err)
246 log.Fatalln("updating dir failed:", err)
252 func pollSystem(client api.StatsProvider) {
253 stats := new(api.SystemStats)
255 if err := client.GetSystemStats(stats); err != nil {
256 log.Fatalln("updating system stats failed:", err)
259 tick := time.Tick(*pollPeriod)
261 fmt.Printf("System stats: %+v\n", stats)
266 if err := client.GetSystemStats(stats); err != nil {
267 log.Println("updating system stats failed:", err)
273 func pollInterfaces(client api.StatsProvider) {
274 stats := new(api.InterfaceStats)
276 if err := client.GetInterfaceStats(stats); err != nil {
277 log.Fatalln("updating system stats failed:", err)
280 tick := time.Tick(*pollPeriod)
282 fmt.Printf("Interface stats (%d interfaces)\n", len(stats.Interfaces))
283 for i := range stats.Interfaces {
284 fmt.Printf(" - %+v\n", stats.Interfaces[i])
290 if err := client.GetInterfaceStats(stats); err != nil {
291 log.Println("updating system stats failed:", err)