diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go new file mode 100644 index 00000000..2415206b --- /dev/null +++ b/collector/meminfo_freebsd.go @@ -0,0 +1,98 @@ +// +build freebsd,!nomeminfo + +package collector + +import ( + "errors" + + "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" +) + +/* +#include +#include + +int _sysctl(const char* name) { + int val; + size_t size = sizeof(val); + int res = sysctlbyname(name, &val, &size, NULL, 0); + if (res == -1) { + return -1; + } + if (size != sizeof(val)) { + return -2; + } + return val; +} +*/ +import "C" + +const ( + memInfoSubsystem = "memory" +) + +type meminfoCollector struct { + config Config + metrics map[string]prometheus.Gauge +} + +func init() { + Factories["meminfo"] = NewMeminfoCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// memory stats. +func NewMeminfoCollector(config Config) (Collector, error) { + return &meminfoCollector{ + config: config, + metrics: map[string]prometheus.Gauge{}, + }, nil +} + +func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { + var pages map[string]C.int + pages = make(map[string]C.int) + + size := C._sysctl(C.CString("vm.stats.vm.v_page_size")) + if size == -1 { + return errors.New("sysctl(vm.stats.vm.v_page_size) failed!") + } + if size == -2 { + return errors.New("sysctl(vm.stats.vm.v_page_size) failed, wrong buffer size!") + } + + pages["active"] = C._sysctl(C.CString("vm.stats.vm.v_active_count")) + pages["inactive"] = C._sysctl(C.CString("vm.stats.vm.v_inactive_count")) + pages["wire"] = C._sysctl(C.CString("vm.stats.vm.v_wire_count")) + pages["cache"] = C._sysctl(C.CString("vm.stats.vm.v_cache_count")) + pages["free"] = C._sysctl(C.CString("vm.stats.vm.v_free_count")) + pages["swappgsin"] = C._sysctl(C.CString("vm.stats.vm.v_swappgsin")) + pages["swappgsout"] = C._sysctl(C.CString("vm.stats.vm.v_swappgsout")) + pages["total"] = C._sysctl(C.CString("vm.stats.vm.v_page_count")) + + for key := range pages { + if pages[key] == -1 { + return errors.New("sysctl() failed for " + key) + } + if pages[key] == -2 { + return errors.New("sysctl() failed for " + key + ", wrong buffer size!") + } + } + + glog.V(1).Infof("Set node_mem: %#v", pages) + for k, v := range pages { + if _, ok := c.metrics[k]; !ok { + c.metrics[k] = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: memInfoSubsystem, + Name: k, + Help: k + " from sysctl()", + }) + } + // Convert metrics to kB ( same as Linux meminfo) + c.metrics[k].Set(float64(v * size / 1024)) + c.metrics[k].Collect(ch) + } + return err +} diff --git a/collector/meminfo.go b/collector/meminfo_linux.go similarity index 100% rename from collector/meminfo.go rename to collector/meminfo_linux.go diff --git a/collector/meminfo_test.go b/collector/meminfo_linux_test.go similarity index 96% rename from collector/meminfo_test.go rename to collector/meminfo_linux_test.go index a1c2eca4..3e84fdc1 100644 --- a/collector/meminfo_test.go +++ b/collector/meminfo_linux_test.go @@ -1,3 +1,5 @@ +// +build linux + package collector import (