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