github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/prometheus/procfs/net_dev.go (about) 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 }