Recognize stat_dir_type_empty
[govpp.git] / adapter / stats_api.go
1 // Copyright (c) 2019 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 adapter
16
17 import (
18         "errors"
19         "fmt"
20 )
21
22 const (
23         // DefaultStatsSocket defines a default socket file path for VPP stats API.
24         DefaultStatsSocket = "/run/vpp/stats.sock"
25 )
26
27 var (
28         ErrStatsDataBusy     = errors.New("stats data busy")
29         ErrStatsDirStale     = errors.New("stats dir stale")
30         ErrStatsDisconnected = errors.New("stats disconnected")
31         ErrStatsAccessFailed = errors.New("stats access failed")
32 )
33
34 // StatsAPI provides connection to VPP stats API.
35 type StatsAPI interface {
36         // Connect establishes client connection to the stats API.
37         Connect() error
38         // Disconnect terminates client connection.
39         Disconnect() error
40
41         // ListStats lists names for stats matching patterns.
42         ListStats(patterns ...string) (names []string, err error)
43         // DumpStats dumps all stat entries.
44         DumpStats(patterns ...string) (entries []StatEntry, err error)
45
46         // PrepareDir prepares new stat dir for entries that match any of prefixes.
47         PrepareDir(patterns ...string) (*StatDir, error)
48         // UpdateDir updates stat dir and all of their entries.
49         UpdateDir(dir *StatDir) error
50 }
51
52 // StatType represents type of stat directory and simply
53 // defines what type of stat data is stored in the stat entry.
54 type StatType int
55
56 const (
57         _                     StatType = 0
58         ScalarIndex           StatType = 1
59         SimpleCounterVector   StatType = 2
60         CombinedCounterVector StatType = 3
61         ErrorIndex            StatType = 4
62         NameVector            StatType = 5
63         Empty                 StatType = 6
64 )
65
66 func (d StatType) String() string {
67         switch d {
68         case ScalarIndex:
69                 return "ScalarIndex"
70         case SimpleCounterVector:
71                 return "SimpleCounterVector"
72         case CombinedCounterVector:
73                 return "CombinedCounterVector"
74         case ErrorIndex:
75                 return "ErrorIndex"
76         case NameVector:
77                 return "NameVector"
78         case Empty:
79                 return "Empty"
80         }
81         return fmt.Sprintf("UnknownStatType(%d)", d)
82 }
83
84 // StatDir defines directory of stats entries created by PrepareDir.
85 type StatDir struct {
86         Epoch   int64
87         Indexes []uint32
88         Entries []StatEntry
89 }
90
91 // StatEntry represents single stat entry. The type of stat stored in Data
92 // is defined by Type.
93 type StatEntry struct {
94         Name []byte
95         Type StatType
96         Data Stat
97 }
98
99 // Counter represents simple counter with single value, which is usually packet count.
100 type Counter uint64
101
102 // CombinedCounter represents counter with two values, for packet count and bytes count.
103 type CombinedCounter [2]uint64
104
105 func (s CombinedCounter) Packets() uint64 {
106         return uint64(s[0])
107 }
108
109 func (s CombinedCounter) Bytes() uint64 {
110         return uint64(s[1])
111 }
112
113 // Name represents string value stored under name vector.
114 type Name []byte
115
116 func (n Name) String() string {
117         return string(n)
118 }
119
120 // Stat represents some type of stat which is usually defined by StatType.
121 type Stat interface {
122         // IsZero returns true if all of its values equal to zero.
123         IsZero() bool
124
125         // isStat is intentionally  unexported to limit implementations of interface to this package,
126         isStat()
127 }
128
129 // ScalarStat represents stat for ScalarIndex.
130 type ScalarStat float64
131
132 // ErrorStat represents stat for ErrorIndex. The array represents workers.
133 type ErrorStat []Counter
134
135 // SimpleCounterStat represents stat for SimpleCounterVector.
136 // The outer array represents workers and the inner array represents interface/node/.. indexes.
137 // Values should be aggregated per interface/node for every worker.
138 // ReduceSimpleCounterStatIndex can be used to reduce specific index.
139 type SimpleCounterStat [][]Counter
140
141 // CombinedCounterStat represents stat for CombinedCounterVector.
142 // The outer array represents workers and the inner array represents interface/node/.. indexes.
143 // Values should be aggregated per interface/node for every worker.
144 // ReduceCombinedCounterStatIndex can be used to reduce specific index.
145 type CombinedCounterStat [][]CombinedCounter
146
147 // NameStat represents stat for NameVector.
148 type NameStat []Name
149
150 // EmptyStat represents removed counter directory
151 type EmptyStat string
152
153 func (ScalarStat) isStat()          {}
154 func (ErrorStat) isStat()           {}
155 func (SimpleCounterStat) isStat()   {}
156 func (CombinedCounterStat) isStat() {}
157 func (NameStat) isStat()            {}
158 func (EmptyStat) isStat()           {}
159
160 func (s ScalarStat) IsZero() bool {
161         return s == 0
162 }
163 func (s ErrorStat) IsZero() bool {
164         if s == nil {
165                 return true
166         }
167         for _, ss := range s {
168                 if ss != 0 {
169                         return false
170                 }
171         }
172         return true
173 }
174 func (s SimpleCounterStat) IsZero() bool {
175         if s == nil {
176                 return true
177         }
178         for _, ss := range s {
179                 for _, sss := range ss {
180                         if sss != 0 {
181                                 return false
182                         }
183                 }
184         }
185         return true
186 }
187 func (s CombinedCounterStat) IsZero() bool {
188         if s == nil {
189                 return true
190         }
191         for _, ss := range s {
192                 if ss == nil {
193                         return true
194                 }
195                 for _, sss := range ss {
196                         if sss[0] != 0 || sss[1] != 0 {
197                                 return false
198                         }
199                 }
200         }
201         return true
202 }
203 func (s NameStat) IsZero() bool {
204         if s == nil {
205                 return true
206         }
207         for _, ss := range s {
208                 if len(ss) > 0 {
209                         return false
210                 }
211         }
212         return true
213 }
214 func (s EmptyStat) IsZero() bool {
215         return true
216 }
217
218 // ReduceSimpleCounterStatIndex returns reduced SimpleCounterStat s for index i.
219 func ReduceSimpleCounterStatIndex(s SimpleCounterStat, i int) uint64 {
220         var val uint64
221         for _, w := range s {
222                 val += uint64(w[i])
223         }
224         return val
225 }
226
227 // ReduceCombinedCounterStatIndex returns reduced CombinedCounterStat s for index i.
228 func ReduceCombinedCounterStatIndex(s CombinedCounterStat, i int) [2]uint64 {
229         var val [2]uint64
230         for _, w := range s {
231                 val[0] += uint64(w[i][0])
232                 val[1] += uint64(w[i][1])
233         }
234         return val
235 }