github.com/elastic/gosigar@v0.14.3/sigar_linux.go (about)

     1  // Copyright (c) 2012 VMware, Inc.
     2  
     3  package gosigar
     4  
     5  import (
     6  	"io/ioutil"
     7  	"strconv"
     8  	"strings"
     9  	"syscall"
    10  )
    11  
    12  func init() {
    13  	system.ticks = 100 // C.sysconf(C._SC_CLK_TCK)
    14  
    15  	Procd = "/proc"
    16  
    17  	getLinuxBootTime()
    18  }
    19  
    20  func getMountTableFileName() string {
    21  	return "/etc/mtab"
    22  }
    23  
    24  // Get returns uptime data
    25  func (self *Uptime) Get() error {
    26  	sysinfo := syscall.Sysinfo_t{}
    27  
    28  	if err := syscall.Sysinfo(&sysinfo); err != nil {
    29  		return err
    30  	}
    31  
    32  	self.Length = float64(sysinfo.Uptime)
    33  
    34  	return nil
    35  }
    36  
    37  // Get returns FD usage data
    38  func (self *FDUsage) Get() error {
    39  	return readFile(Procd+"/sys/fs/file-nr", func(line string) bool {
    40  		fields := strings.Fields(line)
    41  		if len(fields) == 3 {
    42  			self.Open, _ = strconv.ParseUint(fields[0], 10, 64)
    43  			self.Unused, _ = strconv.ParseUint(fields[1], 10, 64)
    44  			self.Max, _ = strconv.ParseUint(fields[2], 10, 64)
    45  		}
    46  		return false
    47  	})
    48  }
    49  
    50  // Get returns hugepages data
    51  func (self *HugeTLBPages) Get() error {
    52  	table, err := parseMeminfo()
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	self.Total, _ = table["HugePages_Total"]
    58  	self.Free, _ = table["HugePages_Free"]
    59  	self.Reserved, _ = table["HugePages_Rsvd"]
    60  	self.Surplus, _ = table["HugePages_Surp"]
    61  	self.DefaultSize, _ = table["Hugepagesize"]
    62  
    63  	if totalSize, found := table["Hugetlb"]; found {
    64  		self.TotalAllocatedSize = totalSize
    65  	} else {
    66  		// If Hugetlb is not present, or huge pages of different sizes
    67  		// are used, this figure can be unaccurate.
    68  		// TODO (jsoriano): Extract information from /sys/kernel/mm/hugepages too
    69  		self.TotalAllocatedSize = (self.Total - self.Free + self.Reserved) * self.DefaultSize
    70  	}
    71  
    72  	return nil
    73  }
    74  
    75  // Get returns process FD usage
    76  func (self *ProcFDUsage) Get(pid int) error {
    77  	err := readFile(procFileName(pid, "limits"), func(line string) bool {
    78  		if strings.HasPrefix(line, "Max open files") {
    79  			fields := strings.Fields(line)
    80  			if len(fields) == 6 {
    81  				self.SoftLimit, _ = strconv.ParseUint(fields[3], 10, 64)
    82  				self.HardLimit, _ = strconv.ParseUint(fields[4], 10, 64)
    83  			}
    84  			return false
    85  		}
    86  		return true
    87  	})
    88  	if err != nil {
    89  		return err
    90  	}
    91  	fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
    92  	if err != nil {
    93  		return err
    94  	}
    95  	self.Open = uint64(len(fds))
    96  	return nil
    97  }
    98  
    99  func parseCpuStat(self *Cpu, line string) error {
   100  	fields := strings.Fields(line)
   101  
   102  	self.User, _ = strtoull(fields[1])
   103  	self.Nice, _ = strtoull(fields[2])
   104  	self.Sys, _ = strtoull(fields[3])
   105  	self.Idle, _ = strtoull(fields[4])
   106  	self.Wait, _ = strtoull(fields[5])
   107  	self.Irq, _ = strtoull(fields[6])
   108  	self.SoftIrq, _ = strtoull(fields[7])
   109  	self.Stolen, _ = strtoull(fields[8])
   110  
   111  	return nil
   112  }
   113  
   114  // Get returns memory data
   115  func (self *Mem) Get() error {
   116  
   117  	table, err := parseMeminfo()
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	self.Total, _ = table["MemTotal"]
   123  	self.Free, _ = table["MemFree"]
   124  	buffers, _ := table["Buffers"]
   125  	self.Cached, _ = table["Cached"]
   126  
   127  	if available, ok := table["MemAvailable"]; ok {
   128  		// MemAvailable is in /proc/meminfo (kernel 3.14+)
   129  		self.ActualFree = available
   130  	} else {
   131  		self.ActualFree = self.Free + buffers + self.Cached
   132  	}
   133  
   134  	self.Used = self.Total - self.Free
   135  	self.ActualUsed = self.Total - self.ActualFree
   136  
   137  	return nil
   138  }