github.com/apcera/util@v0.0.0-20180322191801-7a50bc84ee48/proc/proc.go (about)

     1  // Copyright 2013 Apcera Inc. All rights reserved.
     2  
     3  package proc
     4  
     5  import (
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  )
    10  
    11  type MountPoint struct {
    12  	Dev     string
    13  	Path    string
    14  	Fstype  string
    15  	Options string
    16  	Dump    int
    17  	Fsck    int
    18  }
    19  
    20  // This is the location of the proc mount point. Typically this is only
    21  // modified by unit testing.
    22  var MountProcFile string = "/proc/mounts"
    23  
    24  // Reads through /proc/mounts and returns the data associated with the mount
    25  // points as a list of MountPoint structures.
    26  func MountPoints() (map[string]*MountPoint, error) {
    27  	mp := make(map[string]*MountPoint, 0)
    28  	var current *MountPoint
    29  	err := ParseSimpleProcFile(
    30  		MountProcFile,
    31  		nil,
    32  		func(line int, index int, elm string) error {
    33  			switch index {
    34  			case 0:
    35  				current = new(MountPoint)
    36  				current.Dev = elm
    37  			case 1:
    38  				if len(elm) > 0 && elm[0] != '/' {
    39  					return fmt.Errorf(
    40  						"Invalid path on lin %d of file %s: %s",
    41  						line, MountProcFile, elm)
    42  				}
    43  				current.Path = elm
    44  				mp[elm] = current
    45  			case 2:
    46  				current.Fstype = elm
    47  			case 3:
    48  				current.Options = elm
    49  			case 4:
    50  				n, err := strconv.ParseUint(elm, 10, 32)
    51  				if err != nil {
    52  					return fmt.Errorf(
    53  						"Error parsing column %d on line %d of file %s: %s",
    54  						index, line, MountProcFile, elm)
    55  				}
    56  				current.Dump = int(n)
    57  			case 5:
    58  				n, err := strconv.ParseUint(elm, 10, 32)
    59  				if err != nil {
    60  					return fmt.Errorf(
    61  						"Error parsing column %d on line %d of file %s: %s",
    62  						index, line, MountProcFile, elm)
    63  				}
    64  				current.Fsck = int(n)
    65  			default:
    66  				return fmt.Errorf(
    67  					"Too many colums on line %d of file %s",
    68  					line, MountProcFile)
    69  			}
    70  			return nil
    71  		})
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	return mp, nil
    76  }
    77  
    78  // Stores interface statistics that are gleaned from /proc/dev/net.
    79  type InterfaceStat struct {
    80  	Device       string
    81  	RxBytes      uint64
    82  	RxPackets    uint64
    83  	RxErrors     uint64
    84  	RxDrop       uint64
    85  	RxFifo       uint64
    86  	RxFrame      uint64
    87  	RxCompressed uint64
    88  	RxMulticast  uint64
    89  	TxBytes      uint64
    90  	TxPackets    uint64
    91  	TxErrors     uint64
    92  	TxDrop       uint64
    93  	TxFifo       uint64
    94  	TxFrame      uint64
    95  	TxCompressed uint64
    96  	TxMulticast  uint64
    97  }
    98  
    99  // The file that stores network device statistics.
   100  var DeviceStatsFile string = "/proc/det/dev"
   101  
   102  // Returns the interface statistics as a map keyed off the interface name.
   103  func InterfaceStats() (map[string]InterfaceStat, error) {
   104  	ret := make(map[string]InterfaceStat, 0)
   105  	var current InterfaceStat
   106  	lastline := -1
   107  	lastindex := -1
   108  
   109  	lf := func(index int, line string) error {
   110  		if lastline == index && lastindex == 16 {
   111  			ret[current.Device] = current
   112  		}
   113  		current = InterfaceStat{}
   114  		return nil
   115  	}
   116  	el := func(line int, index int, elm string) (err error) {
   117  		switch index {
   118  		case 0:
   119  			current.Device = strings.Split(elm, ":")[0]
   120  		case 1:
   121  			current.RxBytes, err = strconv.ParseUint(elm, 10, 64)
   122  		case 2:
   123  			current.RxPackets, err = strconv.ParseUint(elm, 10, 64)
   124  		case 3:
   125  			current.RxErrors, err = strconv.ParseUint(elm, 10, 64)
   126  		case 4:
   127  			current.RxDrop, err = strconv.ParseUint(elm, 10, 64)
   128  		case 5:
   129  			current.RxFifo, err = strconv.ParseUint(elm, 10, 64)
   130  		case 6:
   131  			current.RxFrame, err = strconv.ParseUint(elm, 10, 64)
   132  		case 7:
   133  			current.RxCompressed, err = strconv.ParseUint(elm, 10, 64)
   134  		case 8:
   135  			current.RxMulticast, err = strconv.ParseUint(elm, 10, 64)
   136  		case 9:
   137  			current.TxBytes, err = strconv.ParseUint(elm, 10, 64)
   138  		case 10:
   139  			current.TxPackets, err = strconv.ParseUint(elm, 10, 64)
   140  		case 11:
   141  			current.TxErrors, err = strconv.ParseUint(elm, 10, 64)
   142  		case 12:
   143  			current.TxDrop, err = strconv.ParseUint(elm, 10, 64)
   144  		case 13:
   145  			current.TxFifo, err = strconv.ParseUint(elm, 10, 64)
   146  		case 14:
   147  			current.TxFrame, err = strconv.ParseUint(elm, 10, 64)
   148  		case 15:
   149  			current.TxCompressed, err = strconv.ParseUint(elm, 10, 64)
   150  		case 16:
   151  			current.TxMulticast, err = strconv.ParseUint(elm, 10, 64)
   152  		}
   153  		lastline = line
   154  		lastindex = index
   155  		return
   156  	}
   157  
   158  	// Now actually attempt to parse the config
   159  	if err := ParseSimpleProcFile(DeviceStatsFile, lf, el); err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	return ret, nil
   164  }