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, statsclient.SetSocketRetryPeriod(1*time.Second),
71 statsclient.SetSocketRetryTimeout(10*time.Second))
72 c, statsChan, err = core.AsyncConnectStats(client, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval)
74 log.Fatalln("Asynchronous connecting failed:", err)
77 case e := <-statsChan:
78 if e.State == core.Connected {
81 log.Fatalf("VPP stats asynchronous connection failed: %s\n", e.State.String())
85 client = statsclient.NewStatsClient(*statsSocket)
86 c, err = core.ConnectStats(client)
88 log.Fatalln("Connecting failed:", err)
93 switch cmd := flag.Arg(0); cmd {
95 stats := new(api.SystemStats)
96 if err := c.GetSystemStats(stats); err != nil {
97 log.Fatalln("getting system stats failed:", err)
99 fmt.Printf("System stats: %+v\n", stats)
105 fmt.Println("Listing node stats..")
106 stats := new(api.NodeStats)
107 if err := c.GetNodeStats(stats); err != nil {
108 log.Fatalln("getting node stats failed:", err)
111 for _, node := range stats.Nodes {
112 if skipZeros && node.Calls == 0 && node.Suspends == 0 && node.Clocks == 0 && node.Vectors == 0 {
115 fmt.Printf(" - %+v\n", node)
117 fmt.Printf("Listed %d node counters\n", len(stats.Nodes))
120 fmt.Println("Listing interface stats..")
121 stats := new(api.InterfaceStats)
122 if err := c.GetInterfaceStats(stats); err != nil {
123 log.Fatalln("getting interface stats failed:", err)
125 for _, iface := range stats.Interfaces {
126 fmt.Printf(" - %+v\n", iface)
128 fmt.Printf("Listed %d interface counters\n", len(stats.Interfaces))
130 case "poll-interfaces":
134 fmt.Printf("Listing error stats.. %s\n", strings.Join(patterns, " "))
135 stats := new(api.ErrorStats)
136 if err := c.GetErrorStats(stats); err != nil {
137 log.Fatalln("getting error stats failed:", err)
140 for _, counter := range stats.Errors {
142 for _, valuePerWorker := range counter.Values {
143 sum += uint32(valuePerWorker)
146 if skipZeros && sum == 0 {
149 fmt.Printf(" - %v %d (per worker: %v)\n", counter.CounterName, sum, counter.Values)
152 fmt.Printf("Listed %d (%d) error counters\n", n, len(stats.Errors))
155 stats := new(api.BufferStats)
156 if err := c.GetBufferStats(stats); err != nil {
157 log.Fatalln("getting buffer stats failed:", err)
159 fmt.Printf("Buffer stats: %+v\n", stats)
162 stats := new(api.MemoryStats)
163 if err := c.GetMemoryStats(stats); err != nil {
164 log.Fatalln("getting memory stats failed:", err)
166 fmt.Printf("Memory stats: %+v\n", stats)
169 fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " "))
171 dumpStats(client, patterns, skipZeros)
174 fmt.Printf("Polling stats.. %s\n", strings.Join(patterns, " "))
176 pollStats(client, patterns, skipZeros)
178 case "list", "ls", "":
179 fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " "))
181 listStats(client, patterns)
184 fmt.Printf("invalid command: %q\n", cmd)
188 func listStats(client adapter.StatsAPI, patterns []string) {
189 list, err := client.ListStats(patterns...)
191 log.Fatalln("listing stats failed:", err)
194 for _, stat := range list {
195 fmt.Printf(" - %v\n", stat)
198 fmt.Printf("Listed %d stats\n", len(list))
201 func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
202 stats, err := client.DumpStats(patterns...)
204 log.Fatalln("dumping stats failed:", err)
208 for _, stat := range stats {
209 if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
212 fmt.Printf(" - %-50s %25v %+v\n", stat.Name, stat.Type, stat.Data)
216 fmt.Printf("Dumped %d (%d) stats\n", n, len(stats))
219 func pollStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
220 dir, err := client.PrepareDir(patterns...)
222 log.Fatalln("preparing dir failed:", err)
225 tick := time.Tick(*pollPeriod)
228 fmt.Println(time.Now().Format(time.Stamp))
229 for _, stat := range dir.Entries {
230 if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
233 fmt.Printf("%-50s %+v\n", stat.Name, stat.Data)
240 if err := client.UpdateDir(dir); err != nil {
241 if err == adapter.ErrStatsDirStale {
242 if dir, err = client.PrepareDir(patterns...); err != nil {
243 log.Fatalln("preparing dir failed:", err)
247 log.Fatalln("updating dir failed:", err)
253 func pollSystem(client api.StatsProvider) {
254 stats := new(api.SystemStats)
256 if err := client.GetSystemStats(stats); err != nil {
257 log.Fatalln("updating system stats failed:", err)
260 tick := time.Tick(*pollPeriod)
262 fmt.Printf("System stats: %+v\n", stats)
267 if err := client.GetSystemStats(stats); err != nil {
268 log.Println("updating system stats failed:", err)
274 func pollInterfaces(client api.StatsProvider) {
275 stats := new(api.InterfaceStats)
277 if err := client.GetInterfaceStats(stats); err != nil {
278 log.Fatalln("updating system stats failed:", err)
281 tick := time.Tick(*pollPeriod)
283 fmt.Printf("Interface stats (%d interfaces)\n", len(stats.Interfaces))
284 for i := range stats.Interfaces {
285 fmt.Printf(" - %+v\n", stats.Interfaces[i])
291 if err := client.GetInterfaceStats(stats); err != nil {
292 log.Println("updating system stats failed:", err)