...

Source file src/github.com/prometheus/procfs/net_dev.go

Documentation: github.com/prometheus/procfs

     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  // NetDev returns kernel/system statistics read from /proc/net/dev.
    51  func (fs FS) NetDev() (NetDev, error) {
    52  	return newNetDev(fs.proc.Path("net/dev"))
    53  }
    54  
    55  // NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
    56  func (p Proc) NetDev() (NetDev, error) {
    57  	return newNetDev(p.path("net/dev"))
    58  }
    59  
    60  // newNetDev creates a new NetDev from the contents of the given file.
    61  func newNetDev(file string) (NetDev, error) {
    62  	f, err := os.Open(file)
    63  	if err != nil {
    64  		return NetDev{}, err
    65  	}
    66  	defer f.Close()
    67  
    68  	netDev := NetDev{}
    69  	s := bufio.NewScanner(f)
    70  	for n := 0; s.Scan(); n++ {
    71  		// Skip the 2 header lines.
    72  		if n < 2 {
    73  			continue
    74  		}
    75  
    76  		line, err := netDev.parseLine(s.Text())
    77  		if err != nil {
    78  			return netDev, err
    79  		}
    80  
    81  		netDev[line.Name] = *line
    82  	}
    83  
    84  	return netDev, s.Err()
    85  }
    86  
    87  // parseLine parses a single line from the /proc/net/dev file. Header lines
    88  // must be filtered prior to calling this method.
    89  func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) {
    90  	idx := strings.LastIndex(rawLine, ":")
    91  	if idx == -1 {
    92  		return nil, errors.New("invalid net/dev line, missing colon")
    93  	}
    94  	fields := strings.Fields(strings.TrimSpace(rawLine[idx+1:]))
    95  
    96  	var err error
    97  	line := &NetDevLine{}
    98  
    99  	// Interface Name
   100  	line.Name = strings.TrimSpace(rawLine[:idx])
   101  	if line.Name == "" {
   102  		return nil, errors.New("invalid net/dev line, empty interface name")
   103  	}
   104  
   105  	// RX
   106  	line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  	line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	// TX
   140  	line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  	line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)
   161  	if err != nil {
   162  		return nil, err
   163  	}
   164  	line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  
   173  	return line, nil
   174  }
   175  
   176  // Total aggregates the values across interfaces and returns a new NetDevLine.
   177  // The Name field will be a sorted comma separated list of interface names.
   178  func (netDev NetDev) Total() NetDevLine {
   179  	total := NetDevLine{}
   180  
   181  	names := make([]string, 0, len(netDev))
   182  	for _, ifc := range netDev {
   183  		names = append(names, ifc.Name)
   184  		total.RxBytes += ifc.RxBytes
   185  		total.RxPackets += ifc.RxPackets
   186  		total.RxErrors += ifc.RxErrors
   187  		total.RxDropped += ifc.RxDropped
   188  		total.RxFIFO += ifc.RxFIFO
   189  		total.RxFrame += ifc.RxFrame
   190  		total.RxCompressed += ifc.RxCompressed
   191  		total.RxMulticast += ifc.RxMulticast
   192  		total.TxBytes += ifc.TxBytes
   193  		total.TxPackets += ifc.TxPackets
   194  		total.TxErrors += ifc.TxErrors
   195  		total.TxDropped += ifc.TxDropped
   196  		total.TxFIFO += ifc.TxFIFO
   197  		total.TxCollisions += ifc.TxCollisions
   198  		total.TxCarrier += ifc.TxCarrier
   199  		total.TxCompressed += ifc.TxCompressed
   200  	}
   201  	sort.Strings(names)
   202  	total.Name = strings.Join(names, ", ")
   203  
   204  	return total
   205  }
   206  

View as plain text