From f9fa6d05cfe7aad84cf2fec561dd39e1ce5807a5 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 10:16:08 +0430 Subject: [PATCH 01/28] loadavg: Use getloadavg() from stdlib.h --- collector/loadavg.go | 29 +++++++++++------------------ collector/loadavg_test.go | 14 -------------- 2 files changed, 11 insertions(+), 32 deletions(-) delete mode 100644 collector/loadavg_test.go diff --git a/collector/loadavg.go b/collector/loadavg.go index bdf72988..d1eab262 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -3,18 +3,17 @@ package collector import ( + "errors" "fmt" - "io/ioutil" - "strconv" - "strings" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/log" ) -const ( - procLoad = "/proc/loadavg" -) +// #include +import "C" + +var loadavg [1]C.double type loadavgCollector struct { metric prometheus.Gauge @@ -22,6 +21,7 @@ type loadavgCollector struct { func init() { Factories["loadavg"] = NewLoadavgCollector + loadavg[0] = 0 } // Takes a prometheus registry and returns a new Collector exposing @@ -48,18 +48,11 @@ func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) { } func getLoad1() (float64, error) { - data, err := ioutil.ReadFile(procLoad) - if err != nil { - return 0, err + samples := C.getloadavg(&loadavg[0], 1) + if samples > 0 { + return float64(loadavg[0]), nil + } else { + return 0, errors.New("Failed to get load average!") } - return parseLoad(string(data)) -} -func parseLoad(data string) (float64, error) { - parts := strings.Fields(data) - load, err := strconv.ParseFloat(parts[0], 64) - if err != nil { - return 0, fmt.Errorf("Could not parse load '%s': %s", parts[0], err) - } - return load, nil } diff --git a/collector/loadavg_test.go b/collector/loadavg_test.go deleted file mode 100644 index e83822a6..00000000 --- a/collector/loadavg_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package collector - -import "testing" - -func TestLoad(t *testing.T) { - load, err := parseLoad("0.21 0.37 0.39 1/719 19737") - if err != nil { - t.Fatal(err) - } - - if want := 0.21; want != load { - t.Fatalf("want load %f, got %f", want, load) - } -} From 23bb9c44b95fbaca3fab86fa3929f03a302ce388 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 11:43:08 +0430 Subject: [PATCH 02/28] Add cpu collector for FreeBSD. --- collector/cpu_freebsd.go | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 collector/cpu_freebsd.go diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go new file mode 100644 index 00000000..78bdb3a8 --- /dev/null +++ b/collector/cpu_freebsd.go @@ -0,0 +1,71 @@ +// +build freebsd,!nostat + +package collector + +import ( + "errors" + "strconv" + "unsafe" + + "github.com/prometheus/client_golang/prometheus" +) + +/* +#cgo LDFLAGS: -lkvm +#include +#include +#include +#include +#include +*/ +import "C" + +const () + +type statCollector struct { + config Config + cpu *prometheus.CounterVec +} + +func init() { + Factories["cpu"] = NewStatCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// network device stats. +func NewStatCollector(config Config) (Collector, error) { + return &statCollector{ + config: config, + cpu: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: Namespace, + Name: "cpu", + Help: "Seconds the cpus spent in each mode.", + }, + []string{"cpu", "mode"}, + ), + }, nil +} + +// Expose cpu stats using kvm +func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { + var errbuf *C.char + kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) + if errbuf != nil { + return errors.New("Failed to call kvm_open().") + } + defer C.kvm_close(kd) + + ncpus := C.kvm_getncpus(kd) + for i := 0; i < int(ncpus); i++ { + pcpu := C.kvm_getpcpu(kd, C.int(i)) + cp_time := ((*C.struct_pcpu)(unsafe.Pointer(pcpu))).pc_cp_time + c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "user"}).Set(float64(cp_time[C.CP_USER])) + c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "nice"}).Set(float64(cp_time[C.CP_NICE])) + c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "system"}).Set(float64(cp_time[C.CP_SYS])) + c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "interrupt"}).Set(float64(cp_time[C.CP_INTR])) + c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "idle"}).Set(float64(cp_time[C.CP_IDLE])) + } + c.cpu.Collect(ch) + return err +} From ad73b87d1ea95f37f51166c4fdc8e9e9f44e1104 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 11:46:44 +0430 Subject: [PATCH 03/28] Add build constraint for linux collectors. --- collector/bonding.go | 2 +- collector/diskstats.go | 2 +- collector/filesystem.go | 2 +- collector/interrupts.go | 2 +- collector/lastlogin.go | 2 +- collector/megacli.go | 2 +- collector/meminfo.go | 2 +- collector/netdev.go | 2 +- collector/netstat.go | 2 +- collector/stat.go | 2 +- collector/tcpstat.go | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/collector/bonding.go b/collector/bonding.go index 05cc9afc..7b309eef 100644 --- a/collector/bonding.go +++ b/collector/bonding.go @@ -1,4 +1,4 @@ -// +build !nobonding +// +build linux,!nobonding package collector diff --git a/collector/diskstats.go b/collector/diskstats.go index 57c703bc..c34ef7bf 100644 --- a/collector/diskstats.go +++ b/collector/diskstats.go @@ -1,4 +1,4 @@ -// +build !nodiskstats +// +build linux,!nodiskstats package collector diff --git a/collector/filesystem.go b/collector/filesystem.go index dc7724f6..f0473868 100644 --- a/collector/filesystem.go +++ b/collector/filesystem.go @@ -1,4 +1,4 @@ -// +build !nofilesystem +// +build linux,!nofilesystem package collector diff --git a/collector/interrupts.go b/collector/interrupts.go index aebe184b..b0c93b8d 100644 --- a/collector/interrupts.go +++ b/collector/interrupts.go @@ -1,4 +1,4 @@ -// +build !nointerrupts +// +build linux,!nointerrupts package collector diff --git a/collector/lastlogin.go b/collector/lastlogin.go index 1a0c39dd..bbfbc6ee 100644 --- a/collector/lastlogin.go +++ b/collector/lastlogin.go @@ -1,4 +1,4 @@ -// +build !nolastlogin +// +build linux,!nolastlogin package collector diff --git a/collector/megacli.go b/collector/megacli.go index f66da864..77ec64a6 100644 --- a/collector/megacli.go +++ b/collector/megacli.go @@ -1,4 +1,4 @@ -// +build !nomegacli +// +build linux,!nomegacli package collector diff --git a/collector/meminfo.go b/collector/meminfo.go index 5ed920b1..6656ff4b 100644 --- a/collector/meminfo.go +++ b/collector/meminfo.go @@ -1,4 +1,4 @@ -// +build !nomeminfo +// +build linux,!nomeminfo package collector diff --git a/collector/netdev.go b/collector/netdev.go index ee1de005..003a17e1 100644 --- a/collector/netdev.go +++ b/collector/netdev.go @@ -1,4 +1,4 @@ -// +build !nonetdev +// +build linux,!nonetdev package collector diff --git a/collector/netstat.go b/collector/netstat.go index 67b9fba1..46278776 100644 --- a/collector/netstat.go +++ b/collector/netstat.go @@ -1,4 +1,4 @@ -// +build !nonetstat +// +build linux,!nonetstat package collector diff --git a/collector/stat.go b/collector/stat.go index 80ceb3d8..939af5d1 100644 --- a/collector/stat.go +++ b/collector/stat.go @@ -1,4 +1,4 @@ -// +build !nostat +// +build linux,!nostat package collector diff --git a/collector/tcpstat.go b/collector/tcpstat.go index 2753b45c..b787b0ce 100644 --- a/collector/tcpstat.go +++ b/collector/tcpstat.go @@ -1,4 +1,4 @@ -// +build !notcpstat +// +build linux,!notcpstat package collector From 4c5db2787e6eab7b65792a871d44543c4c40069e Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 13:05:28 +0430 Subject: [PATCH 04/28] Add meminfo collector for FreeBSD. --- collector/meminfo_freebsd.go | 98 +++++++++++++++++++ collector/{meminfo.go => meminfo_linux.go} | 0 ...{meminfo_test.go => meminfo_linux_test.go} | 2 + 3 files changed, 100 insertions(+) create mode 100644 collector/meminfo_freebsd.go rename collector/{meminfo.go => meminfo_linux.go} (100%) rename collector/{meminfo_test.go => meminfo_linux_test.go} (96%) 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 ( From d7ec7eac1f8142c59090709acfb5cebd22af4954 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 15:36:41 +0430 Subject: [PATCH 05/28] Revert "Add build constraint for linux collectors." --- collector/bonding.go | 2 +- collector/diskstats.go | 2 +- collector/filesystem.go | 2 +- collector/interrupts.go | 2 +- collector/lastlogin.go | 2 +- collector/megacli.go | 2 +- collector/meminfo_linux.go | 2 +- collector/netdev.go | 2 +- collector/netstat.go | 2 +- collector/stat.go | 6 +++--- collector/tcpstat.go | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/collector/bonding.go b/collector/bonding.go index 7b309eef..05cc9afc 100644 --- a/collector/bonding.go +++ b/collector/bonding.go @@ -1,4 +1,4 @@ -// +build linux,!nobonding +// +build !nobonding package collector diff --git a/collector/diskstats.go b/collector/diskstats.go index c34ef7bf..57c703bc 100644 --- a/collector/diskstats.go +++ b/collector/diskstats.go @@ -1,4 +1,4 @@ -// +build linux,!nodiskstats +// +build !nodiskstats package collector diff --git a/collector/filesystem.go b/collector/filesystem.go index f0473868..dc7724f6 100644 --- a/collector/filesystem.go +++ b/collector/filesystem.go @@ -1,4 +1,4 @@ -// +build linux,!nofilesystem +// +build !nofilesystem package collector diff --git a/collector/interrupts.go b/collector/interrupts.go index b0c93b8d..aebe184b 100644 --- a/collector/interrupts.go +++ b/collector/interrupts.go @@ -1,4 +1,4 @@ -// +build linux,!nointerrupts +// +build !nointerrupts package collector diff --git a/collector/lastlogin.go b/collector/lastlogin.go index bbfbc6ee..1a0c39dd 100644 --- a/collector/lastlogin.go +++ b/collector/lastlogin.go @@ -1,4 +1,4 @@ -// +build linux,!nolastlogin +// +build !nolastlogin package collector diff --git a/collector/megacli.go b/collector/megacli.go index 77ec64a6..f66da864 100644 --- a/collector/megacli.go +++ b/collector/megacli.go @@ -1,4 +1,4 @@ -// +build linux,!nomegacli +// +build !nomegacli package collector diff --git a/collector/meminfo_linux.go b/collector/meminfo_linux.go index 6656ff4b..5ed920b1 100644 --- a/collector/meminfo_linux.go +++ b/collector/meminfo_linux.go @@ -1,4 +1,4 @@ -// +build linux,!nomeminfo +// +build !nomeminfo package collector diff --git a/collector/netdev.go b/collector/netdev.go index 003a17e1..ee1de005 100644 --- a/collector/netdev.go +++ b/collector/netdev.go @@ -1,4 +1,4 @@ -// +build linux,!nonetdev +// +build !nonetdev package collector diff --git a/collector/netstat.go b/collector/netstat.go index 46278776..67b9fba1 100644 --- a/collector/netstat.go +++ b/collector/netstat.go @@ -1,4 +1,4 @@ -// +build linux,!nonetstat +// +build !nonetstat package collector diff --git a/collector/stat.go b/collector/stat.go index 939af5d1..4f7241e5 100644 --- a/collector/stat.go +++ b/collector/stat.go @@ -1,4 +1,4 @@ -// +build linux,!nostat +// +build !nostat package collector @@ -98,11 +98,11 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { // Only some of these may be present, depending on kernel version. cpuFields := []string{"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest"} // OpenVZ guests lack the "guest" CPU field, which needs to be ignored. - expectedFieldNum := len(cpuFields) + 1 + expectedFieldNum := len(cpuFields)+1 if expectedFieldNum > len(parts) { expectedFieldNum = len(parts) } - for i, v := range parts[1:expectedFieldNum] { + for i, v := range parts[1 : expectedFieldNum] { value, err := strconv.ParseFloat(v, 64) if err != nil { return err diff --git a/collector/tcpstat.go b/collector/tcpstat.go index b787b0ce..2753b45c 100644 --- a/collector/tcpstat.go +++ b/collector/tcpstat.go @@ -1,4 +1,4 @@ -// +build linux,!notcpstat +// +build !notcpstat package collector From 66e0171159f3a85778cd323c1ba741e27cfb35be Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 15:55:42 +0430 Subject: [PATCH 06/28] Rename linux collectors for build constraints. --- collector/{bonding.go => bonding_linux.go} | 0 collector/{bonding_test.go => bonding_linux_test.go} | 0 collector/{diskstats.go => diskstats_linux.go} | 0 collector/{diskstats_test.go => diskstats_linux_test.go} | 0 collector/{filesystem.go => filesystem_linux.go} | 0 collector/{interrupts.go => interrupts_linux.go} | 0 collector/{interrupts_test.go => interrupts_linux_test.go} | 0 collector/{lastlogin.go => lastlogin_linux.go} | 0 collector/{netdev.go => netdev_linux.go} | 0 collector/{netdev_test.go => netdev_linux_test.go} | 0 collector/{netstat.go => netstat_linux.go} | 0 collector/{netstat_test.go => netstat_linux_test.go} | 0 collector/{stat.go => stat_linux.go} | 0 collector/{tcpstat.go => tcpstat_linux.go} | 0 collector/{tcpstat_test.go => tcpstat_linux_test.go} | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename collector/{bonding.go => bonding_linux.go} (100%) rename collector/{bonding_test.go => bonding_linux_test.go} (100%) rename collector/{diskstats.go => diskstats_linux.go} (100%) rename collector/{diskstats_test.go => diskstats_linux_test.go} (100%) rename collector/{filesystem.go => filesystem_linux.go} (100%) rename collector/{interrupts.go => interrupts_linux.go} (100%) rename collector/{interrupts_test.go => interrupts_linux_test.go} (100%) rename collector/{lastlogin.go => lastlogin_linux.go} (100%) rename collector/{netdev.go => netdev_linux.go} (100%) rename collector/{netdev_test.go => netdev_linux_test.go} (100%) rename collector/{netstat.go => netstat_linux.go} (100%) rename collector/{netstat_test.go => netstat_linux_test.go} (100%) rename collector/{stat.go => stat_linux.go} (100%) rename collector/{tcpstat.go => tcpstat_linux.go} (100%) rename collector/{tcpstat_test.go => tcpstat_linux_test.go} (100%) diff --git a/collector/bonding.go b/collector/bonding_linux.go similarity index 100% rename from collector/bonding.go rename to collector/bonding_linux.go diff --git a/collector/bonding_test.go b/collector/bonding_linux_test.go similarity index 100% rename from collector/bonding_test.go rename to collector/bonding_linux_test.go diff --git a/collector/diskstats.go b/collector/diskstats_linux.go similarity index 100% rename from collector/diskstats.go rename to collector/diskstats_linux.go diff --git a/collector/diskstats_test.go b/collector/diskstats_linux_test.go similarity index 100% rename from collector/diskstats_test.go rename to collector/diskstats_linux_test.go diff --git a/collector/filesystem.go b/collector/filesystem_linux.go similarity index 100% rename from collector/filesystem.go rename to collector/filesystem_linux.go diff --git a/collector/interrupts.go b/collector/interrupts_linux.go similarity index 100% rename from collector/interrupts.go rename to collector/interrupts_linux.go diff --git a/collector/interrupts_test.go b/collector/interrupts_linux_test.go similarity index 100% rename from collector/interrupts_test.go rename to collector/interrupts_linux_test.go diff --git a/collector/lastlogin.go b/collector/lastlogin_linux.go similarity index 100% rename from collector/lastlogin.go rename to collector/lastlogin_linux.go diff --git a/collector/netdev.go b/collector/netdev_linux.go similarity index 100% rename from collector/netdev.go rename to collector/netdev_linux.go diff --git a/collector/netdev_test.go b/collector/netdev_linux_test.go similarity index 100% rename from collector/netdev_test.go rename to collector/netdev_linux_test.go diff --git a/collector/netstat.go b/collector/netstat_linux.go similarity index 100% rename from collector/netstat.go rename to collector/netstat_linux.go diff --git a/collector/netstat_test.go b/collector/netstat_linux_test.go similarity index 100% rename from collector/netstat_test.go rename to collector/netstat_linux_test.go diff --git a/collector/stat.go b/collector/stat_linux.go similarity index 100% rename from collector/stat.go rename to collector/stat_linux.go diff --git a/collector/tcpstat.go b/collector/tcpstat_linux.go similarity index 100% rename from collector/tcpstat.go rename to collector/tcpstat_linux.go diff --git a/collector/tcpstat_test.go b/collector/tcpstat_linux_test.go similarity index 100% rename from collector/tcpstat_test.go rename to collector/tcpstat_linux_test.go From ae5aea0191d46cf8bc1bae772f31d93e221c76d9 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 17:48:05 +0430 Subject: [PATCH 07/28] Add netdev collector for FreeBSD. --- collector/netdev_freebsd.go | 111 ++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 collector/netdev_freebsd.go diff --git a/collector/netdev_freebsd.go b/collector/netdev_freebsd.go new file mode 100644 index 00000000..5705108f --- /dev/null +++ b/collector/netdev_freebsd.go @@ -0,0 +1,111 @@ +// +build !nonetdev + +package collector + +import ( + "errors" + "fmt" + "strconv" + + "github.com/prometheus/client_golang/prometheus" +) + +/* +#include +#include +#include +#include +#include +*/ +import "C" + +const ( + netDevSubsystem = "network" +) + +type netDevCollector struct { + config Config + metrics map[string]*prometheus.GaugeVec +} + +func init() { + Factories["netdev"] = NewNetDevCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// network device stats. +func NewNetDevCollector(config Config) (Collector, error) { + return &netDevCollector{ + config: config, + metrics: map[string]*prometheus.GaugeVec{}, + }, nil +} + +func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) { + netDev, err := getNetDevStats() + if err != nil { + return fmt.Errorf("Couldn't get netstats: %s", err) + } + for direction, devStats := range netDev { + for dev, stats := range devStats { + for t, value := range stats { + key := direction + "_" + t + if _, ok := c.metrics[key]; !ok { + c.metrics[key] = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: netDevSubsystem, + Name: key, + Help: fmt.Sprintf("%s %s from getifaddrs().", t, direction), + }, + []string{"device"}, + ) + } + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return fmt.Errorf("Invalid value %s in netstats: %s", value, err) + } + c.metrics[key].WithLabelValues(dev).Set(v) + } + } + } + for _, m := range c.metrics { + m.Collect(ch) + } + return err +} + +func getNetDevStats() (map[string]map[string]map[string]string, error) { + netDev := map[string]map[string]map[string]string{} + netDev["transmit"] = map[string]map[string]string{} + netDev["receive"] = map[string]map[string]string{} + + var ifap, ifa *C.struct_ifaddrs + if C.getifaddrs(&ifap) == -1 { + return nil, errors.New("getifaddrs() failed!") + } + for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { + if ifa.ifa_addr.sa_family == C.AF_LINK { + receive := map[string]string{} + transmit := map[string]string{} + //var data *C.struct_if_data + data := (*C.struct_if_data)(ifa.ifa_data) + receive["packets"] = strconv.Itoa(int(data.ifi_ipackets)) + transmit["packets"] = strconv.Itoa(int(data.ifi_opackets)) + receive["errs"] = strconv.Itoa(int(data.ifi_ierrors)) + transmit["errs"] = strconv.Itoa(int(data.ifi_oerrors)) + receive["bytes"] = strconv.Itoa(int(data.ifi_ibytes)) + transmit["bytes"] = strconv.Itoa(int(data.ifi_obytes)) + receive["multicast"] = strconv.Itoa(int(data.ifi_imcasts)) + transmit["multicast"] = strconv.Itoa(int(data.ifi_omcasts)) + receive["drop"] = strconv.Itoa(int(data.ifi_iqdrops)) + //transmit["drops"] = strconv.Itoa(int(data.ifi_oqdrops)) + + netDev["receive"][C.GoString(ifa.ifa_name)] = receive + netDev["transmit"][C.GoString(ifa.ifa_name)] = transmit + } + } + defer C.freeifaddrs(ifap) + + return netDev, nil +} From 13d5f969a5be036b67ba76683f35ae8b9b7decbe Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 12 May 2015 18:55:28 +0430 Subject: [PATCH 08/28] Removed freebsd build constraints from source code. --- collector/cpu_freebsd.go | 2 +- collector/meminfo_freebsd.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 78bdb3a8..a5615809 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -1,4 +1,4 @@ -// +build freebsd,!nostat +// +build !nostat package collector diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go index 2415206b..a142c9dc 100644 --- a/collector/meminfo_freebsd.go +++ b/collector/meminfo_freebsd.go @@ -1,4 +1,4 @@ -// +build freebsd,!nomeminfo +// +build !nomeminfo package collector From 6ef3b7a4e81e3ad629a55655714cff33e190395a Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 13 May 2015 14:57:59 +0430 Subject: [PATCH 09/28] Add filesystem collector for FreeBSD. --- collector/filesystem_freebsd.go | 128 ++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 collector/filesystem_freebsd.go diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go new file mode 100644 index 00000000..d33a1d6d --- /dev/null +++ b/collector/filesystem_freebsd.go @@ -0,0 +1,128 @@ +// +build !nofilesystem + +package collector + +import ( + "errors" + "flag" + "regexp" + "unsafe" + + "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" +) + +/* +#include +#include +#include +#include +*/ +import "C" + +const ( + procMounts = "/proc/mounts" + filesystemSubsystem = "filesystem" +) + +var ( + ignoredMountPoints = flag.String("collector.filesystem.ignored-mount-points", "^/(dev)($|/)", "Regexp of mount points to ignore for filesystem collector.") +) + +type filesystemCollector struct { + config Config + ignoredMountPointsPattern *regexp.Regexp + + size, free, avail, files, filesFree *prometheus.GaugeVec +} + +func init() { + Factories["filesystem"] = NewFilesystemCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// network device filesystems. +func NewFilesystemCollector(config Config) (Collector, error) { + var filesystemLabelNames = []string{"filesystem"} + + return &filesystemCollector{ + config: config, + ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints), + size: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: filesystemSubsystem, + Name: "size", + Help: "Filesystem size in bytes.", + }, + filesystemLabelNames, + ), + free: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: filesystemSubsystem, + Name: "free", + Help: "Filesystem free space in bytes.", + }, + filesystemLabelNames, + ), + avail: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: filesystemSubsystem, + Name: "avail", + Help: "Filesystem space available to non-root users in bytes.", + }, + filesystemLabelNames, + ), + files: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: filesystemSubsystem, + Name: "files", + Help: "Filesystem total file nodes.", + }, + filesystemLabelNames, + ), + filesFree: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: filesystemSubsystem, + Name: "files_free", + Help: "Filesystem total free file nodes.", + }, + filesystemLabelNames, + ), + }, nil +} + +// Expose filesystem fullness. +func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { + var mntbuf *C.struct_statfs + count := C.getmntinfo(&mntbuf, C.MNT_NOWAIT) + if count == 0 { + return errors.New("getmntinfo() failed!") + } + + mnt := (*[1 << 30]C.struct_statfs)(unsafe.Pointer(mntbuf)) + for i := 0; i < int(count); i++ { + //printf("path: %s\t%lu\n", mntbuf[i].f_mntonname, mntbuf[i].f_bfree) + name := C.GoString(&mnt[i].f_mntonname[0]) + if c.ignoredMountPointsPattern.MatchString(name) { + glog.V(1).Infof("Ignoring mount point: %s", name) + continue + } + c.size.WithLabelValues(name).Set(float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize)) + c.free.WithLabelValues(name).Set(float64(mnt[i].f_bfree) * float64(mnt[i].f_bsize)) + c.avail.WithLabelValues(name).Set(float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize)) + c.files.WithLabelValues(name).Set(float64(mnt[i].f_files)) + c.filesFree.WithLabelValues(name).Set(float64(mnt[i].f_ffree)) + } + + c.size.Collect(ch) + c.free.Collect(ch) + c.avail.Collect(ch) + c.files.Collect(ch) + c.filesFree.Collect(ch) + return err +} From a10ab2c10231aad6948c0684931ecf62184cda77 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 20 May 2015 12:22:00 +0430 Subject: [PATCH 10/28] Check caller's euid and egid when accessing /dev/mem on FreeBSD. --- collector/cpu_freebsd.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index a5615809..54fa8cbf 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -4,6 +4,7 @@ package collector import ( "errors" + "os" "strconv" "unsafe" @@ -49,6 +50,10 @@ func NewStatCollector(config Config) (Collector, error) { // Expose cpu stats using kvm func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { + if os.Geteuid() != 0 && os.Getegid() != 2 { + return errors.New("Caller should be either root user or kmem group to access /dev/mem") + } + var errbuf *C.char kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) if errbuf != nil { From c651d7ccd9f9ec83cebcd1a82317532ea2ff8fc7 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Mon, 1 Jun 2015 14:08:09 +0430 Subject: [PATCH 11/28] meminfo: use bytes, fix type conversion bug. --- collector/meminfo_freebsd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go index a142c9dc..9d655a5c 100644 --- a/collector/meminfo_freebsd.go +++ b/collector/meminfo_freebsd.go @@ -91,7 +91,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { }) } // Convert metrics to kB ( same as Linux meminfo) - c.metrics[k].Set(float64(v * size / 1024)) + c.metrics[k].Set(float64(v) * float64(size)) c.metrics[k].Collect(ch) } return err From 9b6843db6098cda7aed5bf59c778da8c221cc0f9 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Mon, 1 Jun 2015 14:48:43 +0430 Subject: [PATCH 12/28] netdev: use counters instead of gauges. --- collector/netdev_freebsd.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collector/netdev_freebsd.go b/collector/netdev_freebsd.go index 5705108f..36ea91e3 100644 --- a/collector/netdev_freebsd.go +++ b/collector/netdev_freebsd.go @@ -25,7 +25,7 @@ const ( type netDevCollector struct { config Config - metrics map[string]*prometheus.GaugeVec + metrics map[string]*prometheus.CounterVec } func init() { @@ -37,7 +37,7 @@ func init() { func NewNetDevCollector(config Config) (Collector, error) { return &netDevCollector{ config: config, - metrics: map[string]*prometheus.GaugeVec{}, + metrics: map[string]*prometheus.CounterVec{}, }, nil } @@ -51,8 +51,8 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) { for t, value := range stats { key := direction + "_" + t if _, ok := c.metrics[key]; !ok { - c.metrics[key] = prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + c.metrics[key] = prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: netDevSubsystem, Name: key, From 1ebda4c0aa4ffeb1d8daad909128e12724d4c026 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Mon, 1 Jun 2015 17:08:38 +0430 Subject: [PATCH 13/28] Remove linux build contraint from meminfo test source code. --- collector/meminfo_linux_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/collector/meminfo_linux_test.go b/collector/meminfo_linux_test.go index 3e84fdc1..a1c2eca4 100644 --- a/collector/meminfo_linux_test.go +++ b/collector/meminfo_linux_test.go @@ -1,5 +1,3 @@ -// +build linux - package collector import ( From f7563fe7a2f7ea2698350d11d89824f51ac1b64f Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 23 Jun 2015 18:19:18 +0430 Subject: [PATCH 14/28] Remove config from collectors. --- collector/cpu_freebsd.go | 9 +++------ collector/filesystem_freebsd.go | 7 ++----- collector/loadavg.go | 3 +-- collector/meminfo_freebsd.go | 5 +---- collector/netdev_freebsd.go | 5 +---- 5 files changed, 8 insertions(+), 21 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 54fa8cbf..39ffc50c 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -24,19 +24,16 @@ import "C" const () type statCollector struct { - config Config - cpu *prometheus.CounterVec + cpu *prometheus.CounterVec } func init() { Factories["cpu"] = NewStatCollector } -// Takes a config struct and prometheus registry and returns a new Collector exposing -// network device stats. -func NewStatCollector(config Config) (Collector, error) { +// cpu stats. +func NewStatCollector() (Collector, error) { return &statCollector{ - config: config, cpu: prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: Namespace, diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index d33a1d6d..b726a656 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -30,7 +30,6 @@ var ( ) type filesystemCollector struct { - config Config ignoredMountPointsPattern *regexp.Regexp size, free, avail, files, filesFree *prometheus.GaugeVec @@ -40,13 +39,11 @@ func init() { Factories["filesystem"] = NewFilesystemCollector } -// Takes a config struct and prometheus registry and returns a new Collector exposing -// network device filesystems. -func NewFilesystemCollector(config Config) (Collector, error) { +// filesystems stats. +func NewFilesystemCollector() (Collector, error) { var filesystemLabelNames = []string{"filesystem"} return &filesystemCollector{ - config: config, ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints), size: prometheus.NewGaugeVec( prometheus.GaugeOpts{ diff --git a/collector/loadavg.go b/collector/loadavg.go index d1eab262..6be49616 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -24,8 +24,7 @@ func init() { loadavg[0] = 0 } -// Takes a prometheus registry and returns a new Collector exposing -// load, seconds since last login and a list of tags as specified by config. +// load1 stat. func NewLoadavgCollector() (Collector, error) { return &loadavgCollector{ metric: prometheus.NewGauge(prometheus.GaugeOpts{ diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go index 9d655a5c..7c9e2469 100644 --- a/collector/meminfo_freebsd.go +++ b/collector/meminfo_freebsd.go @@ -33,7 +33,6 @@ const ( ) type meminfoCollector struct { - config Config metrics map[string]prometheus.Gauge } @@ -41,11 +40,9 @@ 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) { +func NewMeminfoCollector() (Collector, error) { return &meminfoCollector{ - config: config, metrics: map[string]prometheus.Gauge{}, }, nil } diff --git a/collector/netdev_freebsd.go b/collector/netdev_freebsd.go index 36ea91e3..ad07aaca 100644 --- a/collector/netdev_freebsd.go +++ b/collector/netdev_freebsd.go @@ -24,7 +24,6 @@ const ( ) type netDevCollector struct { - config Config metrics map[string]*prometheus.CounterVec } @@ -32,11 +31,9 @@ func init() { Factories["netdev"] = NewNetDevCollector } -// Takes a config struct and prometheus registry and returns a new Collector exposing // network device stats. -func NewNetDevCollector(config Config) (Collector, error) { +func NewNetDevCollector() (Collector, error) { return &netDevCollector{ - config: config, metrics: map[string]*prometheus.CounterVec{}, }, nil } From c5669f0a1a5842f567705d895a64766bcfa92bd8 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 23 Jun 2015 18:20:12 +0430 Subject: [PATCH 15/28] Add devstat collector for FreeBSD. --- collector/devstat_freebsd.go | 239 +++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 collector/devstat_freebsd.go diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go new file mode 100644 index 00000000..6528c08f --- /dev/null +++ b/collector/devstat_freebsd.go @@ -0,0 +1,239 @@ +// +build !nodiskstats + +package collector + +import ( + "errors" + "fmt" + + "github.com/prometheus/client_golang/prometheus" +) + +/* +#cgo LDFLAGS: -ldevstat -lkvm +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + uint64_t read; + uint64_t write; + uint64_t free; +} Bytes; + +typedef struct { + uint64_t other; + uint64_t read; + uint64_t write; + uint64_t free; +} Transfers; + +typedef struct { + double other; + double read; + double write; + double free; +} Duration; + +typedef struct { + char device[DEVSTAT_NAME_LEN]; + int unit; + Bytes bytes; + Transfers transfers; + Duration duration; + long busyTime; + uint64_t blocks; +} Stats; + +int _get_ndevs() { + struct statinfo current; + int num_devices; + + current.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); + if (current.dinfo == NULL) + return -2; + + devstat_checkversion(NULL); + + if (devstat_getdevs(NULL, ¤t) == -1) + return -1; + + return current.dinfo->numdevs; +} + +Stats _get_stats(int i) { + struct statinfo current; + int num_devices; + + current.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); + devstat_getdevs(NULL, ¤t); + + num_devices = current.dinfo->numdevs; + Stats stats; + uint64_t bytes_read, bytes_write, bytes_free; + uint64_t transfers_other, transfers_read, transfers_write, transfers_free; + long double duration_other, duration_read, duration_write, duration_free; + long double busy_time; + uint64_t blocks; + + strcpy(stats.device, current.dinfo->devices[i].device_name); + stats.unit = current.dinfo->devices[i].unit_number; + devstat_compute_statistics(¤t.dinfo->devices[i], + NULL, + 1.0, + DSM_TOTAL_BYTES_READ, &bytes_read, + DSM_TOTAL_BYTES_WRITE, &bytes_write, + DSM_TOTAL_BYTES_FREE, &bytes_free, + DSM_TOTAL_TRANSFERS_OTHER, &transfers_other, + DSM_TOTAL_TRANSFERS_READ, &transfers_read, + DSM_TOTAL_TRANSFERS_WRITE, &transfers_write, + DSM_TOTAL_TRANSFERS_FREE, &transfers_free, + DSM_TOTAL_DURATION_OTHER, &duration_other, + DSM_TOTAL_DURATION_READ, &duration_read, + DSM_TOTAL_DURATION_WRITE, &duration_write, + DSM_TOTAL_DURATION_FREE, &duration_free, + DSM_TOTAL_BUSY_TIME, &busy_time, + DSM_TOTAL_BLOCKS, &blocks, + DSM_NONE); + + stats.bytes.read = bytes_read; + stats.bytes.write = bytes_write; + stats.bytes.free = bytes_free; + stats.transfers.other = transfers_other; + stats.transfers.read = transfers_read; + stats.transfers.write = transfers_write; + stats.transfers.free = transfers_free; + stats.duration.other = duration_other; + stats.duration.read = duration_read; + stats.duration.write = duration_write; + stats.duration.free = duration_free; + stats.busyTime = busy_time; + stats.blocks = blocks; + + return stats; +} +*/ +import "C" + +const ( + devstatSubsystem = "devstat" +) + +type devstatCollector struct { + bytes *prometheus.GaugeVec + transfers *prometheus.GaugeVec + duration *prometheus.GaugeVec + busyTime *prometheus.GaugeVec + blocks *prometheus.GaugeVec +} + +func init() { + Factories["devstat"] = NewDevstatCollector +} + +// device stats. +func NewDevstatCollector() (Collector, error) { + //var diskLabelNames = []string{"device"} + //var ioType = []string{"type"} + + return &devstatCollector{ + // Docs from https://www.kernel.org/doc/Documentation/iostats.txt + bytes: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: devstatSubsystem, + Name: "bytes", + Help: "The total number of bytes transferred", + }, + []string{"device", "type"}, + ), + transfers: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: devstatSubsystem, + Name: "transfers", + Help: "The total number of transactions", + }, + []string{"device", "type"}, + ), + duration: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: devstatSubsystem, + Name: "duration", + Help: "The total duration of transactions", + }, + []string{"device", "type"}, + ), + busyTime: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: devstatSubsystem, + Name: "busy_time", + Help: "Total time the device had one or more transactions outstanding", + }, + []string{"device"}, + ), + blocks: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: devstatSubsystem, + Name: "blocks", + Help: "The total number of blocks transferred", + }, + []string{"device"}, + ), + }, nil +} + +func (c *devstatCollector) Update(ch chan<- prometheus.Metric) (err error) { + /* + var busyTime [3]C.longlong + var blocks [3]C.uint64_t + var kbPerTransfer [3]C.longlong + var transfersPerSecond [3]C.longlong + var mbPerSecond [3]C.longlong + var blocksPerSecond [3]C.longlong + var msPerTransaction [3]C.longlong + var busyPCT C.longlong + var queueLength C.uint64_t + + */ + count := C._get_ndevs() + if count == -1 { + return errors.New("devstat_getdevs() failed!") + } + if count == -2 { + return errors.New("calloc() failed!") + } + + for i := C.int(0); i < count; i++ { + stats := C._get_stats(i) + device := fmt.Sprintf("%s%d", C.GoString(&stats.device[0]), stats.unit) + c.bytes.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.bytes.read)) + c.bytes.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.bytes.write)) + c.bytes.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.bytes.free)) + c.transfers.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.transfers.other)) + c.transfers.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.transfers.read)) + c.transfers.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.transfers.write)) + c.transfers.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.transfers.free)) + c.duration.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.duration.other)) + c.duration.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.duration.read)) + c.duration.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.duration.write)) + c.duration.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.duration.free)) + c.busyTime.With(prometheus.Labels{"device": device}).Set(float64(stats.busyTime)) + c.blocks.With(prometheus.Labels{"device": device}).Set(float64(stats.blocks)) + } + + c.bytes.Collect(ch) + c.transfers.Collect(ch) + c.duration.Collect(ch) + c.busyTime.Collect(ch) + c.blocks.Collect(ch) + + return err +} From 71abff14b106597fd9c385db96536f73b02e0767 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 23 Jun 2015 19:00:23 +0430 Subject: [PATCH 16/28] devstat: Fix wrong labels for 'other' metrics. --- collector/devstat_freebsd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go index 6528c08f..17554a73 100644 --- a/collector/devstat_freebsd.go +++ b/collector/devstat_freebsd.go @@ -217,11 +217,11 @@ func (c *devstatCollector) Update(ch chan<- prometheus.Metric) (err error) { c.bytes.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.bytes.read)) c.bytes.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.bytes.write)) c.bytes.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.bytes.free)) - c.transfers.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.transfers.other)) + c.transfers.With(prometheus.Labels{"device": device, "type": "other"}).Set(float64(stats.transfers.other)) c.transfers.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.transfers.read)) c.transfers.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.transfers.write)) c.transfers.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.transfers.free)) - c.duration.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.duration.other)) + c.duration.With(prometheus.Labels{"device": device, "type": "other"}).Set(float64(stats.duration.other)) c.duration.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.duration.read)) c.duration.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.duration.write)) c.duration.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.duration.free)) From ccbea3446553f639ba4a9052f4fa1d924508841d Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 23 Jun 2015 22:39:45 +0430 Subject: [PATCH 17/28] filesystem: Remove unused const variable. --- collector/filesystem_freebsd.go | 1 - 1 file changed, 1 deletion(-) diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index b726a656..957e383b 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -21,7 +21,6 @@ import ( import "C" const ( - procMounts = "/proc/mounts" filesystemSubsystem = "filesystem" ) From f93125ba10548ae54319e379a21ae5047912237e Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 23 Jun 2015 22:43:03 +0430 Subject: [PATCH 18/28] loadavg: Remove unnecessary global variable. --- collector/loadavg.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/collector/loadavg.go b/collector/loadavg.go index 6be49616..6ecb7edb 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -13,15 +13,12 @@ import ( // #include import "C" -var loadavg [1]C.double - type loadavgCollector struct { metric prometheus.Gauge } func init() { Factories["loadavg"] = NewLoadavgCollector - loadavg[0] = 0 } // load1 stat. @@ -47,6 +44,7 @@ func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) { } func getLoad1() (float64, error) { + var loadavg [1]C.double samples := C.getloadavg(&loadavg[0], 1) if samples > 0 { return float64(loadavg[0]), nil From 462b708742e40ee4158efd634647aed68f30af99 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 00:44:52 +0430 Subject: [PATCH 19/28] cpu: Code cleanup. --- collector/cpu_freebsd.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 39ffc50c..ac19399a 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -1,4 +1,4 @@ -// +build !nostat +// +build !cpu package collector @@ -21,8 +21,6 @@ import ( */ import "C" -const () - type statCollector struct { cpu *prometheus.CounterVec } @@ -31,30 +29,31 @@ func init() { Factories["cpu"] = NewStatCollector } -// cpu stats. +// Takes a prometheus registry and returns a new Collector exposing +// CPU stats. func NewStatCollector() (Collector, error) { return &statCollector{ cpu: prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: Namespace, - Name: "cpu", - Help: "Seconds the cpus spent in each mode.", + Name: "cpu_seconds_total", + Help: "Seconds the CPU spent in each mode.", }, []string{"cpu", "mode"}, ), }, nil } -// Expose cpu stats using kvm +// Expose CPU stats using KVM. func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { if os.Geteuid() != 0 && os.Getegid() != 2 { - return errors.New("Caller should be either root user or kmem group to access /dev/mem") + return errors.New("caller should be either root user or kmem group to access /dev/mem") } var errbuf *C.char kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) if errbuf != nil { - return errors.New("Failed to call kvm_open().") + return errors.New("failed to call kvm_open().") } defer C.kvm_close(kd) From 78bf63ffd8ffba675cfe6f98211dffe36deac786 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 10:35:09 +0430 Subject: [PATCH 20/28] filesystem: Code cleanup. --- collector/filesystem_freebsd.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index 957e383b..73a15fd9 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -8,8 +8,8 @@ import ( "regexp" "unsafe" - "github.com/golang/glog" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/log" ) /* @@ -38,7 +38,8 @@ func init() { Factories["filesystem"] = NewFilesystemCollector } -// filesystems stats. +// Takes a prometheus registry and returns a new Collector exposing +// Filesystems stats. func NewFilesystemCollector() (Collector, error) { var filesystemLabelNames = []string{"filesystem"} @@ -48,7 +49,7 @@ func NewFilesystemCollector() (Collector, error) { prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, - Name: "size", + Name: "size_bytes", Help: "Filesystem size in bytes.", }, filesystemLabelNames, @@ -57,7 +58,7 @@ func NewFilesystemCollector() (Collector, error) { prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, - Name: "free", + Name: "free_bytes", Help: "Filesystem free space in bytes.", }, filesystemLabelNames, @@ -66,7 +67,7 @@ func NewFilesystemCollector() (Collector, error) { prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, - Name: "avail", + Name: "avail_bytes", Help: "Filesystem space available to non-root users in bytes.", }, filesystemLabelNames, @@ -75,7 +76,7 @@ func NewFilesystemCollector() (Collector, error) { prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, - Name: "files", + Name: "file_nodes", Help: "Filesystem total file nodes.", }, filesystemLabelNames, @@ -84,7 +85,7 @@ func NewFilesystemCollector() (Collector, error) { prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, - Name: "files_free", + Name: "file_free_nodes", Help: "Filesystem total free file nodes.", }, filesystemLabelNames, @@ -102,10 +103,9 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { mnt := (*[1 << 30]C.struct_statfs)(unsafe.Pointer(mntbuf)) for i := 0; i < int(count); i++ { - //printf("path: %s\t%lu\n", mntbuf[i].f_mntonname, mntbuf[i].f_bfree) name := C.GoString(&mnt[i].f_mntonname[0]) if c.ignoredMountPointsPattern.MatchString(name) { - glog.V(1).Infof("Ignoring mount point: %s", name) + log.Debugf("Ignoring mount point: %s", name) continue } c.size.WithLabelValues(name).Set(float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize)) From 720198e04775194d07e8ac7f33d17451795e0107 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 16:32:12 +0430 Subject: [PATCH 21/28] netdev: Code cleanup. --- collector/netdev_freebsd.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/collector/netdev_freebsd.go b/collector/netdev_freebsd.go index ad07aaca..8892869a 100644 --- a/collector/netdev_freebsd.go +++ b/collector/netdev_freebsd.go @@ -11,6 +11,7 @@ import ( ) /* +#cgo CFLAGS: -D_IFI_OQDROPS #include #include #include @@ -31,7 +32,8 @@ func init() { Factories["netdev"] = NewNetDevCollector } -// network device stats. +// Takes a prometheus registry and returns a new Collector exposing +// Network device stats. func NewNetDevCollector() (Collector, error) { return &netDevCollector{ metrics: map[string]*prometheus.CounterVec{}, @@ -41,7 +43,7 @@ func NewNetDevCollector() (Collector, error) { func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) { netDev, err := getNetDevStats() if err != nil { - return fmt.Errorf("Couldn't get netstats: %s", err) + return fmt.Errorf("couldn't get netstats: %s", err) } for direction, devStats := range netDev { for dev, stats := range devStats { @@ -60,7 +62,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) { } v, err := strconv.ParseFloat(value, 64) if err != nil { - return fmt.Errorf("Invalid value %s in netstats: %s", value, err) + return fmt.Errorf("invalid value %s in netstats: %s", value, err) } c.metrics[key].WithLabelValues(dev).Set(v) } @@ -81,11 +83,12 @@ func getNetDevStats() (map[string]map[string]map[string]string, error) { if C.getifaddrs(&ifap) == -1 { return nil, errors.New("getifaddrs() failed!") } + defer C.freeifaddrs(ifap) + for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { if ifa.ifa_addr.sa_family == C.AF_LINK { receive := map[string]string{} transmit := map[string]string{} - //var data *C.struct_if_data data := (*C.struct_if_data)(ifa.ifa_data) receive["packets"] = strconv.Itoa(int(data.ifi_ipackets)) transmit["packets"] = strconv.Itoa(int(data.ifi_opackets)) @@ -96,13 +99,12 @@ func getNetDevStats() (map[string]map[string]map[string]string, error) { receive["multicast"] = strconv.Itoa(int(data.ifi_imcasts)) transmit["multicast"] = strconv.Itoa(int(data.ifi_omcasts)) receive["drop"] = strconv.Itoa(int(data.ifi_iqdrops)) - //transmit["drops"] = strconv.Itoa(int(data.ifi_oqdrops)) + transmit["drop"] = strconv.Itoa(int(data.ifi_oqdrops)) netDev["receive"][C.GoString(ifa.ifa_name)] = receive netDev["transmit"][C.GoString(ifa.ifa_name)] = transmit } } - defer C.freeifaddrs(ifap) return netDev, nil } From d80b2af492ab3aeeec233af08115799cbb036cc3 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 16:38:43 +0430 Subject: [PATCH 22/28] loadavg: Split the collector for linux and other platforms. --- collector/loadavg.go | 3 +- collector/loadavg_linux.go | 65 +++++++++++++++++++++++++++++++++ collector/loadavg_linux_test.go | 14 +++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 collector/loadavg_linux.go create mode 100644 collector/loadavg_linux_test.go diff --git a/collector/loadavg.go b/collector/loadavg.go index 6ecb7edb..7d7611a6 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -1,4 +1,4 @@ -// +build !noloadavg +// +build !linux !noloadavg package collector @@ -21,6 +21,7 @@ func init() { Factories["loadavg"] = NewLoadavgCollector } +// Takes a prometheus registry and returns a new Collector exposing // load1 stat. func NewLoadavgCollector() (Collector, error) { return &loadavgCollector{ diff --git a/collector/loadavg_linux.go b/collector/loadavg_linux.go new file mode 100644 index 00000000..bdf72988 --- /dev/null +++ b/collector/loadavg_linux.go @@ -0,0 +1,65 @@ +// +build !noloadavg + +package collector + +import ( + "fmt" + "io/ioutil" + "strconv" + "strings" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/log" +) + +const ( + procLoad = "/proc/loadavg" +) + +type loadavgCollector struct { + metric prometheus.Gauge +} + +func init() { + Factories["loadavg"] = NewLoadavgCollector +} + +// Takes a prometheus registry and returns a new Collector exposing +// load, seconds since last login and a list of tags as specified by config. +func NewLoadavgCollector() (Collector, error) { + return &loadavgCollector{ + metric: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "load1", + Help: "1m load average.", + }), + }, nil +} + +func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) { + load, err := getLoad1() + if err != nil { + return fmt.Errorf("Couldn't get load: %s", err) + } + log.Debugf("Set node_load: %f", load) + c.metric.Set(load) + c.metric.Collect(ch) + return err +} + +func getLoad1() (float64, error) { + data, err := ioutil.ReadFile(procLoad) + if err != nil { + return 0, err + } + return parseLoad(string(data)) +} + +func parseLoad(data string) (float64, error) { + parts := strings.Fields(data) + load, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return 0, fmt.Errorf("Could not parse load '%s': %s", parts[0], err) + } + return load, nil +} diff --git a/collector/loadavg_linux_test.go b/collector/loadavg_linux_test.go new file mode 100644 index 00000000..e83822a6 --- /dev/null +++ b/collector/loadavg_linux_test.go @@ -0,0 +1,14 @@ +package collector + +import "testing" + +func TestLoad(t *testing.T) { + load, err := parseLoad("0.21 0.37 0.39 1/719 19737") + if err != nil { + t.Fatal(err) + } + + if want := 0.21; want != load { + t.Fatalf("want load %f, got %f", want, load) + } +} From d303a2ebc3f0778430933bb8ffee8dd0400f3551 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 17:01:21 +0430 Subject: [PATCH 23/28] loadavg: Fix build constraints. --- collector/loadavg.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collector/loadavg.go b/collector/loadavg.go index 7d7611a6..74ccbaf4 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -1,4 +1,5 @@ -// +build !linux !noloadavg +// +build !noloadavg +// +build !linux package collector From 9e66d4f2aea9d20e5917ac46b77d4dcf13a7d7ea Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 17:14:39 +0430 Subject: [PATCH 24/28] meminfo: Code cleanup. --- collector/meminfo_freebsd.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go index 7c9e2469..d0376d6c 100644 --- a/collector/meminfo_freebsd.go +++ b/collector/meminfo_freebsd.go @@ -5,8 +5,8 @@ package collector import ( "errors" - "github.com/golang/glog" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/log" ) /* @@ -40,7 +40,8 @@ func init() { Factories["meminfo"] = NewMeminfoCollector } -// memory stats. +// Takes a prometheus registry and returns a new Collector exposing +// Memory stats. func NewMeminfoCollector() (Collector, error) { return &meminfoCollector{ metrics: map[string]prometheus.Gauge{}, @@ -77,7 +78,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { } } - glog.V(1).Infof("Set node_mem: %#v", pages) + log.Debugf("Set node_mem: %#v", pages) for k, v := range pages { if _, ok := c.metrics[k]; !ok { c.metrics[k] = prometheus.NewGauge(prometheus.GaugeOpts{ @@ -87,7 +88,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { Help: k + " from sysctl()", }) } - // Convert metrics to kB ( same as Linux meminfo) + // Convert metrics to kB ( same as Linux meminfo). c.metrics[k].Set(float64(v) * float64(size)) c.metrics[k].Collect(ch) } From f8ede8248820fce28659abaeaf133e7a6dc21ef4 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Wed, 24 Jun 2015 17:15:40 +0430 Subject: [PATCH 25/28] cpu: Fix build constraints. --- collector/cpu_freebsd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index ac19399a..d86bc9dc 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -1,4 +1,4 @@ -// +build !cpu +// +build !nocpu package collector From 93708f3dda10011a6eea0c8c57cce74dcdbab6bb Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Mon, 13 Jul 2015 18:30:14 +0430 Subject: [PATCH 26/28] devstat: Fix metric types, disable free metrics. --- collector/devstat_freebsd.go | 79 +++++++++++++++--------------------- 1 file changed, 33 insertions(+), 46 deletions(-) diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go index 17554a73..5a24f511 100644 --- a/collector/devstat_freebsd.go +++ b/collector/devstat_freebsd.go @@ -1,4 +1,4 @@ -// +build !nodiskstats +// +build !nodevstat package collector @@ -124,66 +124,64 @@ const ( ) type devstatCollector struct { - bytes *prometheus.GaugeVec - transfers *prometheus.GaugeVec - duration *prometheus.GaugeVec - busyTime *prometheus.GaugeVec - blocks *prometheus.GaugeVec + bytes *prometheus.CounterVec + bytes_total *prometheus.CounterVec + transfers *prometheus.CounterVec + duration *prometheus.CounterVec + busyTime *prometheus.CounterVec + blocks *prometheus.CounterVec } func init() { Factories["devstat"] = NewDevstatCollector } -// device stats. +// Takes a prometheus registry and returns a new Collector exposing +// Device stats. func NewDevstatCollector() (Collector, error) { - //var diskLabelNames = []string{"device"} - //var ioType = []string{"type"} - return &devstatCollector{ - // Docs from https://www.kernel.org/doc/Documentation/iostats.txt - bytes: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + bytes: prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: devstatSubsystem, - Name: "bytes", - Help: "The total number of bytes transferred", + Name: "bytes_total", + Help: "The total number of bytes in transactions.", }, []string{"device", "type"}, ), - transfers: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + transfers: prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: devstatSubsystem, - Name: "transfers", - Help: "The total number of transactions", + Name: "transfers_total", + Help: "The total number of transactions.", }, []string{"device", "type"}, ), - duration: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + duration: prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: devstatSubsystem, - Name: "duration", - Help: "The total duration of transactions", + Name: "duration_seconds_total", + Help: "The total duration of transactions in seconds.", }, []string{"device", "type"}, ), - busyTime: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + busyTime: prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: devstatSubsystem, - Name: "busy_time", - Help: "Total time the device had one or more transactions outstanding", + Name: "busy_time_seconds_total", + Help: "Total time the device had one or more transactions outstanding in seconds.", }, []string{"device"}, ), - blocks: prometheus.NewGaugeVec( - prometheus.GaugeOpts{ + blocks: prometheus.NewCounterVec( + prometheus.CounterOpts{ Namespace: Namespace, Subsystem: devstatSubsystem, - Name: "blocks", - Help: "The total number of blocks transferred", + Name: "blocks_transferred_total", + Help: "The total number of blocks transferred.", }, []string{"device"}, ), @@ -191,18 +189,6 @@ func NewDevstatCollector() (Collector, error) { } func (c *devstatCollector) Update(ch chan<- prometheus.Metric) (err error) { - /* - var busyTime [3]C.longlong - var blocks [3]C.uint64_t - var kbPerTransfer [3]C.longlong - var transfersPerSecond [3]C.longlong - var mbPerSecond [3]C.longlong - var blocksPerSecond [3]C.longlong - var msPerTransaction [3]C.longlong - var busyPCT C.longlong - var queueLength C.uint64_t - - */ count := C._get_ndevs() if count == -1 { return errors.New("devstat_getdevs() failed!") @@ -214,17 +200,18 @@ func (c *devstatCollector) Update(ch chan<- prometheus.Metric) (err error) { for i := C.int(0); i < count; i++ { stats := C._get_stats(i) device := fmt.Sprintf("%s%d", C.GoString(&stats.device[0]), stats.unit) + // Free metrics are disabled for now, please see PR #88 for more details. c.bytes.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.bytes.read)) c.bytes.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.bytes.write)) - c.bytes.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.bytes.free)) + //c.bytes.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.bytes.free)) c.transfers.With(prometheus.Labels{"device": device, "type": "other"}).Set(float64(stats.transfers.other)) c.transfers.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.transfers.read)) c.transfers.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.transfers.write)) - c.transfers.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.transfers.free)) + //c.transfers.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.transfers.free)) c.duration.With(prometheus.Labels{"device": device, "type": "other"}).Set(float64(stats.duration.other)) c.duration.With(prometheus.Labels{"device": device, "type": "read"}).Set(float64(stats.duration.read)) c.duration.With(prometheus.Labels{"device": device, "type": "write"}).Set(float64(stats.duration.write)) - c.duration.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.duration.free)) + //c.duration.With(prometheus.Labels{"device": device, "type": "free"}).Set(float64(stats.duration.free)) c.busyTime.With(prometheus.Labels{"device": device}).Set(float64(stats.busyTime)) c.blocks.With(prometheus.Labels{"device": device}).Set(float64(stats.blocks)) } From dddb273dfc75864f448fb61bf6d6e05d84c22b25 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 14 Jul 2015 01:59:55 +0430 Subject: [PATCH 27/28] Fix some error messages. --- collector/cpu_freebsd.go | 2 +- collector/devstat_freebsd.go | 4 ++-- collector/filesystem_freebsd.go | 2 +- collector/loadavg.go | 2 +- collector/meminfo_freebsd.go | 8 ++++---- collector/netdev_freebsd.go | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index d86bc9dc..632f0959 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -53,7 +53,7 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { var errbuf *C.char kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) if errbuf != nil { - return errors.New("failed to call kvm_open().") + return errors.New("failed to call kvm_open()") } defer C.kvm_close(kd) diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go index 5a24f511..2b9300c0 100644 --- a/collector/devstat_freebsd.go +++ b/collector/devstat_freebsd.go @@ -191,10 +191,10 @@ func NewDevstatCollector() (Collector, error) { func (c *devstatCollector) Update(ch chan<- prometheus.Metric) (err error) { count := C._get_ndevs() if count == -1 { - return errors.New("devstat_getdevs() failed!") + return errors.New("devstat_getdevs() failed") } if count == -2 { - return errors.New("calloc() failed!") + return errors.New("calloc() failed") } for i := C.int(0); i < count; i++ { diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index 73a15fd9..c1bd6280 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -98,7 +98,7 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { var mntbuf *C.struct_statfs count := C.getmntinfo(&mntbuf, C.MNT_NOWAIT) if count == 0 { - return errors.New("getmntinfo() failed!") + return errors.New("getmntinfo() failed") } mnt := (*[1 << 30]C.struct_statfs)(unsafe.Pointer(mntbuf)) diff --git a/collector/loadavg.go b/collector/loadavg.go index 74ccbaf4..5ead9e90 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -51,7 +51,7 @@ func getLoad1() (float64, error) { if samples > 0 { return float64(loadavg[0]), nil } else { - return 0, errors.New("Failed to get load average!") + return 0, errors.New("failed to get load average") } } diff --git a/collector/meminfo_freebsd.go b/collector/meminfo_freebsd.go index d0376d6c..fca410cc 100644 --- a/collector/meminfo_freebsd.go +++ b/collector/meminfo_freebsd.go @@ -54,10 +54,10 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { 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!") + 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!") + 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")) @@ -74,7 +74,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { return errors.New("sysctl() failed for " + key) } if pages[key] == -2 { - return errors.New("sysctl() failed for " + key + ", wrong buffer size!") + return errors.New("sysctl() failed for " + key + ", wrong buffer size") } } @@ -88,7 +88,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) { Help: k + " from sysctl()", }) } - // Convert metrics to kB ( same as Linux meminfo). + // Convert metrics to kB (same as Linux meminfo). c.metrics[k].Set(float64(v) * float64(size)) c.metrics[k].Collect(ch) } diff --git a/collector/netdev_freebsd.go b/collector/netdev_freebsd.go index 8892869a..68a96bd3 100644 --- a/collector/netdev_freebsd.go +++ b/collector/netdev_freebsd.go @@ -81,7 +81,7 @@ func getNetDevStats() (map[string]map[string]map[string]string, error) { var ifap, ifa *C.struct_ifaddrs if C.getifaddrs(&ifap) == -1 { - return nil, errors.New("getifaddrs() failed!") + return nil, errors.New("getifaddrs() failed") } defer C.freeifaddrs(ifap) From 8c4a5b0f65be9da25560f7469ec4be10fe075409 Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Tue, 14 Jul 2015 17:27:20 +0430 Subject: [PATCH 28/28] stats: Fix formatting. --- collector/stat_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/stat_linux.go b/collector/stat_linux.go index 4f7241e5..80ceb3d8 100644 --- a/collector/stat_linux.go +++ b/collector/stat_linux.go @@ -98,11 +98,11 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { // Only some of these may be present, depending on kernel version. cpuFields := []string{"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest"} // OpenVZ guests lack the "guest" CPU field, which needs to be ignored. - expectedFieldNum := len(cpuFields)+1 + expectedFieldNum := len(cpuFields) + 1 if expectedFieldNum > len(parts) { expectedFieldNum = len(parts) } - for i, v := range parts[1 : expectedFieldNum] { + for i, v := range parts[1:expectedFieldNum] { value, err := strconv.ParseFloat(v, 64) if err != nil { return err