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  }