Mock VPP adapter nit
[govpp.git] / examples / cmd / stats-api / 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
24         "git.fd.io/govpp.git/adapter"
25         "git.fd.io/govpp.git/adapter/vppapiclient"
26 )
27
28 // ------------------------------------------------------------------
29 // Example - Stats API
30 // ------------------------------------------------------------------
31 // The example stats_api demonstrates how to retrieve stats
32 // from the VPP using the new stats API.
33 // ------------------------------------------------------------------
34
35 var (
36         statsSocket = flag.String("socket", vppapiclient.DefaultStatSocket, "VPP stats segment socket")
37         dumpAll     = flag.Bool("all", false, "Dump all stats including ones with zero values")
38 )
39
40 func init() {
41         flag.Usage = func() {
42                 fmt.Fprintf(os.Stderr, "%s: usage [ls|dump] <patterns>...\n", os.Args[0])
43                 flag.PrintDefaults()
44                 os.Exit(1)
45         }
46 }
47
48 func main() {
49         flag.Parse()
50
51         cmd := flag.Arg(0)
52
53         switch cmd {
54         case "", "ls", "dump":
55         default:
56                 flag.Usage()
57         }
58
59         var patterns []string
60         if flag.NArg() > 0 {
61                 patterns = flag.Args()[1:]
62         }
63
64         client := vppapiclient.NewStatClient(*statsSocket)
65
66         fmt.Printf("Connecting to stats socket: %s\n", *statsSocket)
67
68         if err := client.Connect(); err != nil {
69                 log.Fatalln("Connecting failed:", err)
70         }
71         defer client.Disconnect()
72
73         switch cmd {
74         case "dump":
75                 dumpStats(client, patterns, !*dumpAll)
76         default:
77                 listStats(client, patterns)
78         }
79 }
80
81 func listStats(client adapter.StatsAPI, patterns []string) {
82         fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " "))
83
84         list, err := client.ListStats(patterns...)
85         if err != nil {
86                 log.Fatalln("listing stats failed:", err)
87         }
88
89         for _, stat := range list {
90                 fmt.Printf(" - %v\n", stat)
91         }
92
93         fmt.Printf("Listed %d stats\n", len(list))
94 }
95
96 func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
97         fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " "))
98
99         stats, err := client.DumpStats(patterns...)
100         if err != nil {
101                 log.Fatalln("dumping stats failed:", err)
102         }
103
104         n := 0
105         for _, stat := range stats {
106                 if isZero(stat.Data) && skipZeros {
107                         continue
108                 }
109                 fmt.Printf(" - %-25s %25v %+v\n", stat.Name, stat.Type, stat.Data)
110                 n++
111         }
112
113         fmt.Printf("Dumped %d (%d) stats\n", n, len(stats))
114 }
115
116 func isZero(stat adapter.Stat) bool {
117         switch s := stat.(type) {
118         case adapter.ScalarStat:
119                 return s == 0
120         case adapter.ErrorStat:
121                 return s == 0
122         case adapter.SimpleCounterStat:
123                 for _, ss := range s {
124                         for _, sss := range ss {
125                                 if sss != 0 {
126                                         return false
127                                 }
128                         }
129                 }
130         case adapter.CombinedCounterStat:
131                 for _, ss := range s {
132                         for _, sss := range ss {
133                                 if sss.Bytes != 0 || sss.Packets != 0 {
134                                         return false
135                                 }
136                         }
137                 }
138         }
139         return true
140 }