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