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

     1  // Copied and modified from sigar_linux.go.
     2  
     3  package gosigar
     4  
     5  import (
     6  	"io/ioutil"
     7  	"runtime"
     8  	"strconv"
     9  	"strings"
    10  	"unsafe"
    11  )
    12  
    13  /*
    14  #include <sys/param.h>
    15  #include <sys/mount.h>
    16  #include <sys/ucred.h>
    17  #include <sys/types.h>
    18  #include <sys/sysctl.h>
    19  #include <stdlib.h>
    20  #include <stdint.h>
    21  #include <unistd.h>
    22  #include <time.h>
    23  */
    24  import "C"
    25  
    26  func init() {
    27  	system.ticks = uint64(C.sysconf(C._SC_CLK_TCK))
    28  
    29  	Procd = "/compat/linux/proc"
    30  
    31  	getLinuxBootTime()
    32  }
    33  
    34  func getMountTableFileName() string {
    35  	return Procd + "/mtab"
    36  }
    37  
    38  func (self *Uptime) Get() error {
    39  	ts := C.struct_timespec{}
    40  
    41  	if _, err := C.clock_gettime(C.CLOCK_UPTIME, &ts); err != nil {
    42  		return err
    43  	}
    44  
    45  	self.Length = float64(ts.tv_sec) + 1e-9*float64(ts.tv_nsec)
    46  
    47  	return nil
    48  }
    49  
    50  func (self *FDUsage) Get() error {
    51  	val := C.uint32_t(0)
    52  	sc := C.size_t(4)
    53  
    54  	name := C.CString("kern.openfiles")
    55  	_, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
    56  	C.free(unsafe.Pointer(name))
    57  	if err != nil {
    58  		return err
    59  	}
    60  	self.Open = uint64(val)
    61  
    62  	name = C.CString("kern.maxfiles")
    63  	_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
    64  	C.free(unsafe.Pointer(name))
    65  	if err != nil {
    66  		return err
    67  	}
    68  	self.Max = uint64(val)
    69  
    70  	self.Unused = self.Max - self.Open
    71  
    72  	return nil
    73  }
    74  
    75  func (self *ProcFDUsage) Get(pid int) error {
    76  	err := readFile("/proc/"+strconv.Itoa(pid)+"/rlimit", func(line string) bool {
    77  		if strings.HasPrefix(line, "nofile") {
    78  			fields := strings.Fields(line)
    79  			if len(fields) == 3 {
    80  				self.SoftLimit, _ = strconv.ParseUint(fields[1], 10, 64)
    81  				self.HardLimit, _ = strconv.ParseUint(fields[2], 10, 64)
    82  			}
    83  			return false
    84  		}
    85  		return true
    86  	})
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	// linprocfs only provides this information for this process (self).
    92  	fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
    93  	if err != nil {
    94  		return err
    95  	}
    96  	self.Open = uint64(len(fds))
    97  
    98  	return nil
    99  }
   100  
   101  func (self *HugeTLBPages) Get() error {
   102  	return ErrNotImplemented{runtime.GOOS}
   103  }
   104  
   105  func parseCpuStat(self *Cpu, line string) error {
   106  	fields := strings.Fields(line)
   107  
   108  	self.User, _ = strtoull(fields[1])
   109  	self.Nice, _ = strtoull(fields[2])
   110  	self.Sys, _ = strtoull(fields[3])
   111  	self.Idle, _ = strtoull(fields[4])
   112  	return nil
   113  }
   114  
   115  func (self *Mem) Get() error {
   116  	val := C.uint32_t(0)
   117  	sc := C.size_t(4)
   118  
   119  	name := C.CString("vm.stats.vm.v_page_count")
   120  	_, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
   121  	C.free(unsafe.Pointer(name))
   122  	if err != nil {
   123  		return err
   124  	}
   125  	pagecount := uint64(val)
   126  
   127  	name = C.CString("vm.stats.vm.v_page_size")
   128  	_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
   129  	C.free(unsafe.Pointer(name))
   130  	if err != nil {
   131  		return err
   132  	}
   133  	pagesize := uint64(val)
   134  
   135  	name = C.CString("vm.stats.vm.v_free_count")
   136  	_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
   137  	C.free(unsafe.Pointer(name))
   138  	if err != nil {
   139  		return err
   140  	}
   141  	self.Free = uint64(val) * pagesize
   142  
   143  	name = C.CString("vm.stats.vm.v_inactive_count")
   144  	_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
   145  	C.free(unsafe.Pointer(name))
   146  	if err != nil {
   147  		return err
   148  	}
   149  	kern := uint64(val)
   150  
   151  	self.Total = uint64(pagecount * pagesize)
   152  
   153  	self.Used = self.Total - self.Free
   154  	self.ActualFree = self.Free + (kern * pagesize)
   155  	self.ActualUsed = self.Used - (kern * pagesize)
   156  
   157  	return nil
   158  }