diff --git a/collector/meminfo_bsd.go b/collector/meminfo_bsd.go index be17d7a9..890077c0 100644 --- a/collector/meminfo_bsd.go +++ b/collector/meminfo_bsd.go @@ -22,30 +22,63 @@ import ( "golang.org/x/sys/unix" ) +type sysctlType uint8 + +const ( + sysctlTypeUint32 sysctlType = iota + sysctlTypeUint64 +) + +type meminfoSysctl struct { + name string + dataType sysctlType + conversion func(uint64) uint64 +} + func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { info := make(map[string]float64) - size, err := unix.SysctlUint32("vm.stats.vm.v_page_size") + tmp32, err := unix.SysctlUint32("vm.stats.vm.v_page_size") if err != nil { return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err) } + size := uint64(tmp32) + fromPage := func(v uint64) uint64 { + return v * size + } - for key, v := range map[string]string{ - "active": "vm.stats.vm.v_active_count", - "inactive": "vm.stats.vm.v_inactive_count", - "wire": "vm.stats.vm.v_wire_count", - "cache": "vm.stats.vm.v_cache_count", - "free": "vm.stats.vm.v_free_count", - "swappgsin": "vm.stats.vm.v_swappgsin", - "swappgsout": "vm.stats.vm.v_swappgsout", - "total": "vm.stats.vm.v_page_count", + for key, v := range map[string]meminfoSysctl{ + "active_bytes": {"vm.stats.vm.v_active_count", sysctlTypeUint32, fromPage}, + "inactive_bytes": {"vm.stats.vm.v_inactive_count", sysctlTypeUint32, fromPage}, + "wired_bytes": {"vm.stats.vm.v_wire_count", sysctlTypeUint32, fromPage}, + "cache_bytes": {"vm.stats.vm.v_cache_count", sysctlTypeUint32, fromPage}, + "buffer_bytes": {"vfs.bufspace", sysctlTypeUint32, nil}, + "free_bytes": {"vm.stats.vm.v_free_count", sysctlTypeUint32, fromPage}, + "size_bytes": {"vm.stats.vm.v_page_count", sysctlTypeUint32, fromPage}, + "swap_in_bytes_total": {"vm.stats.vm.v_swappgsin", sysctlTypeUint32, fromPage}, + "swap_out_bytes_total": {"vm.stats.vm.v_swappgsout", sysctlTypeUint32, fromPage}, + "swap_size_bytes": {"vm.swap_total", sysctlTypeUint64, nil}, } { - value, err := unix.SysctlUint32(v) + var tmp64 uint64 + switch v.dataType { + case sysctlTypeUint32: + tmp32, err = unix.SysctlUint32(v.name) + tmp64 = uint64(tmp32) + case sysctlTypeUint64: + tmp64, err = unix.SysctlUint64(v.name) + } if err != nil { return nil, err } - // Convert metrics to kB (same as Linux meminfo). - info[key] = float64(value) * float64(size) + + if v.conversion != nil { + // Convert to bytes. + info[key] = float64(v.conversion(tmp64)) + continue + } + + info[key] = float64(tmp64) } + return info, nil }