Stats API: added GetMemory()
[govpp.git] / examples / stats-client / stats_api.go
1 // Copyright (c) 2018 Cisco and/or its affiliates.
2 //
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:
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 package main
16
17 import (
18         "flag"
19         "fmt"
20         "log"
21         "os"
22         "strings"
23         "time"
24
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"
29 )
30
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 // ------------------------------------------------------------------
37
38 var (
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 )
43
44 func init() {
45         flag.Usage = func() {
46                 fmt.Fprintf(os.Stderr, "%s: usage [ls|dump|poll|errors|interfaces|nodes|system|buffers|memory] <patterns>...\n", os.Args[0])
47                 flag.PrintDefaults()
48                 os.Exit(1)
49         }
50 }
51
52 func main() {
53         flag.Parse()
54         skipZeros := !*dumpAll
55
56         var patterns []string
57         if flag.NArg() > 0 {
58                 patterns = flag.Args()[1:]
59         }
60
61         client := statsclient.NewStatsClient(*statsSocket)
62
63         c, err := core.ConnectStats(client)
64         if err != nil {
65                 log.Fatalln("Connecting failed:", err)
66         }
67         defer c.Disconnect()
68
69         switch cmd := flag.Arg(0); cmd {
70         case "system":
71                 stats := new(api.SystemStats)
72                 if err := c.GetSystemStats(stats); err != nil {
73                         log.Fatalln("getting system stats failed:", err)
74                 }
75                 fmt.Printf("System stats: %+v\n", stats)
76
77         case "poll-system":
78                 pollSystem(c)
79
80         case "nodes":
81                 fmt.Println("Listing node stats..")
82                 stats := new(api.NodeStats)
83                 if err := c.GetNodeStats(stats); err != nil {
84                         log.Fatalln("getting node stats failed:", err)
85                 }
86
87                 for _, node := range stats.Nodes {
88                         if skipZeros && node.Calls == 0 && node.Suspends == 0 && node.Clocks == 0 && node.Vectors == 0 {
89                                 continue
90                         }
91                         fmt.Printf(" - %+v\n", node)
92                 }
93                 fmt.Printf("Listed %d node counters\n", len(stats.Nodes))
94
95         case "interfaces":
96                 fmt.Println("Listing interface stats..")
97                 stats := new(api.InterfaceStats)
98                 if err := c.GetInterfaceStats(stats); err != nil {
99                         log.Fatalln("getting interface stats failed:", err)
100                 }
101                 for _, iface := range stats.Interfaces {
102                         fmt.Printf(" - %+v\n", iface)
103                 }
104                 fmt.Printf("Listed %d interface counters\n", len(stats.Interfaces))
105
106         case "poll-interfaces":
107                 pollInterfaces(c)
108
109         case "errors":
110                 fmt.Printf("Listing error stats.. %s\n", strings.Join(patterns, " "))
111                 stats := new(api.ErrorStats)
112                 if err := c.GetErrorStats(stats); err != nil {
113                         log.Fatalln("getting error stats failed:", err)
114                 }
115                 n := 0
116                 for _, counter := range stats.Errors {
117                         if skipZeros && counter.Value == 0 {
118                                 continue
119                         }
120                         fmt.Printf(" - %v\n", counter)
121                         n++
122                 }
123                 fmt.Printf("Listed %d (%d) error counters\n", n, len(stats.Errors))
124
125         case "buffers":
126                 stats := new(api.BufferStats)
127                 if err := c.GetBufferStats(stats); err != nil {
128                         log.Fatalln("getting buffer stats failed:", err)
129                 }
130                 fmt.Printf("Buffer stats: %+v\n", stats)
131
132         case "memory":
133                 stats := new(api.MemoryStats)
134                 if err := c.GetMemoryStats(stats); err != nil {
135                         log.Fatalln("getting memory stats failed:", err)
136                 }
137                 fmt.Printf("Memory stats: %+v\n", stats)
138
139         case "dump":
140                 fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " "))
141
142                 dumpStats(client, patterns, skipZeros)
143
144         case "poll":
145                 fmt.Printf("Polling stats.. %s\n", strings.Join(patterns, " "))
146
147                 pollStats(client, patterns, skipZeros)
148
149         case "list", "ls", "":
150                 fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " "))
151
152                 listStats(client, patterns)
153
154         default:
155                 fmt.Printf("invalid command: %q\n", cmd)
156         }
157 }
158
159 func listStats(client adapter.StatsAPI, patterns []string) {
160         list, err := client.ListStats(patterns...)
161         if err != nil {
162                 log.Fatalln("listing stats failed:", err)
163         }
164
165         for _, stat := range list {
166                 fmt.Printf(" - %v\n", stat)
167         }
168
169         fmt.Printf("Listed %d stats\n", len(list))
170 }
171
172 func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
173         stats, err := client.DumpStats(patterns...)
174         if err != nil {
175                 log.Fatalln("dumping stats failed:", err)
176         }
177
178         n := 0
179         for _, stat := range stats {
180                 if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
181                         continue
182                 }
183                 fmt.Printf(" - %-50s %25v %+v\n", stat.Name, stat.Type, stat.Data)
184                 n++
185         }
186
187         fmt.Printf("Dumped %d (%d) stats\n", n, len(stats))
188 }
189
190 func pollStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
191         dir, err := client.PrepareDir(patterns...)
192         if err != nil {
193                 log.Fatalln("preparing dir failed:", err)
194         }
195
196         tick := time.Tick(*pollPeriod)
197         for {
198                 n := 0
199                 fmt.Println(time.Now().Format(time.Stamp))
200                 for _, stat := range dir.Entries {
201                         if skipZeros && (stat.Data == nil || stat.Data.IsZero()) {
202                                 continue
203                         }
204                         fmt.Printf("%-50s %+v\n", stat.Name, stat.Data)
205                         n++
206                 }
207                 fmt.Println()
208
209                 select {
210                 case <-tick:
211                         if err := client.UpdateDir(dir); err != nil {
212                                 if err == adapter.ErrStatsDirStale {
213                                         if dir, err = client.PrepareDir(patterns...); err != nil {
214                                                 log.Fatalln("preparing dir failed:", err)
215                                         }
216                                         continue
217                                 }
218                                 log.Fatalln("updating dir failed:", err)
219                         }
220                 }
221         }
222 }
223
224 func pollSystem(client api.StatsProvider) {
225         stats := new(api.SystemStats)
226
227         if err := client.GetSystemStats(stats); err != nil {
228                 log.Fatalln("updating system stats failed:", err)
229         }
230
231         tick := time.Tick(*pollPeriod)
232         for {
233                 fmt.Printf("System stats: %+v\n", stats)
234                 fmt.Println()
235
236                 select {
237                 case <-tick:
238                         if err := client.GetSystemStats(stats); err != nil {
239                                 log.Println("updating system stats failed:", err)
240                         }
241                 }
242         }
243 }
244
245 func pollInterfaces(client api.StatsProvider) {
246         stats := new(api.InterfaceStats)
247
248         if err := client.GetInterfaceStats(stats); err != nil {
249                 log.Fatalln("updating system stats failed:", err)
250         }
251
252         tick := time.Tick(*pollPeriod)
253         for {
254                 fmt.Printf("Interface stats (%d interfaces)\n", len(stats.Interfaces))
255                 for i := range stats.Interfaces {
256                         fmt.Printf(" - %+v\n", stats.Interfaces[i])
257                 }
258                 fmt.Println()
259
260                 select {
261                 case <-tick:
262                         if err := client.GetInterfaceStats(stats); err != nil {
263                                 log.Println("updating system stats failed:", err)
264                         }
265                 }
266         }
267 }