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 }