Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / prometheus / procfs / net_dev.go
1 // Copyright 2018 The Prometheus Authors
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package procfs
15
16 import (
17         "bufio"
18         "errors"
19         "os"
20         "sort"
21         "strconv"
22         "strings"
23 )
24
25 // NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev.
26 type NetDevLine struct {
27         Name         string `json:"name"`          // The name of the interface.
28         RxBytes      uint64 `json:"rx_bytes"`      // Cumulative count of bytes received.
29         RxPackets    uint64 `json:"rx_packets"`    // Cumulative count of packets received.
30         RxErrors     uint64 `json:"rx_errors"`     // Cumulative count of receive errors encountered.
31         RxDropped    uint64 `json:"rx_dropped"`    // Cumulative count of packets dropped while receiving.
32         RxFIFO       uint64 `json:"rx_fifo"`       // Cumulative count of FIFO buffer errors.
33         RxFrame      uint64 `json:"rx_frame"`      // Cumulative count of packet framing errors.
34         RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver.
35         RxMulticast  uint64 `json:"rx_multicast"`  // Cumulative count of multicast frames received by the device driver.
36         TxBytes      uint64 `json:"tx_bytes"`      // Cumulative count of bytes transmitted.
37         TxPackets    uint64 `json:"tx_packets"`    // Cumulative count of packets transmitted.
38         TxErrors     uint64 `json:"tx_errors"`     // Cumulative count of transmit errors encountered.
39         TxDropped    uint64 `json:"tx_dropped"`    // Cumulative count of packets dropped while transmitting.
40         TxFIFO       uint64 `json:"tx_fifo"`       // Cumulative count of FIFO buffer errors.
41         TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface.
42         TxCarrier    uint64 `json:"tx_carrier"`    // Cumulative count of carrier losses detected by the device driver.
43         TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver.
44 }
45
46 // NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys
47 // are interface names.
48 type NetDev map[string]NetDevLine
49
50 // NewNetDev returns kernel/system statistics read from /proc/net/dev.
51 func NewNetDev() (NetDev, error) {
52         fs, err := NewFS(DefaultMountPoint)
53         if err != nil {
54                 return nil, err
55         }
56
57         return fs.NewNetDev()
58 }
59
60 // NewNetDev returns kernel/system statistics read from /proc/net/dev.
61 func (fs FS) NewNetDev() (NetDev, error) {
62         return newNetDev(fs.Path("net/dev"))
63 }
64
65 // NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
66 func (p Proc) NewNetDev() (NetDev, error) {
67         return newNetDev(p.path("net/dev"))
68 }
69
70 // newNetDev creates a new NetDev from the contents of the given file.
71 func newNetDev(file string) (NetDev, error) {
72         f, err := os.Open(file)
73         if err != nil {
74                 return NetDev{}, err
75         }
76         defer f.Close()
77
78         nd := NetDev{}
79         s := bufio.NewScanner(f)
80         for n := 0; s.Scan(); n++ {
81                 // Skip the 2 header lines.
82                 if n < 2 {
83                         continue
84                 }
85
86                 line, err := nd.parseLine(s.Text())
87                 if err != nil {
88                         return nd, err
89                 }
90
91                 nd[line.Name] = *line
92         }
93
94         return nd, s.Err()
95 }
96
97 // parseLine parses a single line from the /proc/net/dev file. Header lines
98 // must be filtered prior to calling this method.
99 func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
100         parts := strings.SplitN(rawLine, ":", 2)
101         if len(parts) != 2 {
102                 return nil, errors.New("invalid net/dev line, missing colon")
103         }
104         fields := strings.Fields(strings.TrimSpace(parts[1]))
105
106         var err error
107         line := &NetDevLine{}
108
109         // Interface Name
110         line.Name = strings.TrimSpace(parts[0])
111         if line.Name == "" {
112                 return nil, errors.New("invalid net/dev line, empty interface name")
113         }
114
115         // RX
116         line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)
117         if err != nil {
118                 return nil, err
119         }
120         line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)
121         if err != nil {
122                 return nil, err
123         }
124         line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)
125         if err != nil {
126                 return nil, err
127         }
128         line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)
129         if err != nil {
130                 return nil, err
131         }
132         line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)
133         if err != nil {
134                 return nil, err
135         }
136         line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)
137         if err != nil {
138                 return nil, err
139         }
140         line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)
141         if err != nil {
142                 return nil, err
143         }
144         line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)
145         if err != nil {
146                 return nil, err
147         }
148
149         // TX
150         line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)
151         if err != nil {
152                 return nil, err
153         }
154         line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)
155         if err != nil {
156                 return nil, err
157         }
158         line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)
159         if err != nil {
160                 return nil, err
161         }
162         line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)
163         if err != nil {
164                 return nil, err
165         }
166         line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)
167         if err != nil {
168                 return nil, err
169         }
170         line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)
171         if err != nil {
172                 return nil, err
173         }
174         line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)
175         if err != nil {
176                 return nil, err
177         }
178         line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)
179         if err != nil {
180                 return nil, err
181         }
182
183         return line, nil
184 }
185
186 // Total aggregates the values across interfaces and returns a new NetDevLine.
187 // The Name field will be a sorted comma separated list of interface names.
188 func (nd NetDev) Total() NetDevLine {
189         total := NetDevLine{}
190
191         names := make([]string, 0, len(nd))
192         for _, ifc := range nd {
193                 names = append(names, ifc.Name)
194                 total.RxBytes += ifc.RxBytes
195                 total.RxPackets += ifc.RxPackets
196                 total.RxPackets += ifc.RxPackets
197                 total.RxErrors += ifc.RxErrors
198                 total.RxDropped += ifc.RxDropped
199                 total.RxFIFO += ifc.RxFIFO
200                 total.RxFrame += ifc.RxFrame
201                 total.RxCompressed += ifc.RxCompressed
202                 total.RxMulticast += ifc.RxMulticast
203                 total.TxBytes += ifc.TxBytes
204                 total.TxPackets += ifc.TxPackets
205                 total.TxErrors += ifc.TxErrors
206                 total.TxDropped += ifc.TxDropped
207                 total.TxFIFO += ifc.TxFIFO
208                 total.TxCollisions += ifc.TxCollisions
209                 total.TxCarrier += ifc.TxCarrier
210                 total.TxCompressed += ifc.TxCompressed
211         }
212         sort.Strings(names)
213         total.Name = strings.Join(names, ", ")
214
215         return total
216 }