Skip to content

Commit 9969f93

Browse files
Merge pull request #387 from discordianfish/fish-fix-meminfo-darwin
Refactor meminfo and add darwin metrics
2 parents 26c6182 + c21c59d commit 9969f93

File tree

4 files changed

+140
-79
lines changed

4 files changed

+140
-79
lines changed

collector/meminfo.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2015 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// +build !nomeminfo
15+
16+
package collector
17+
18+
import (
19+
"fmt"
20+
21+
"github.com/prometheus/client_golang/prometheus"
22+
"github.com/prometheus/common/log"
23+
)
24+
25+
const (
26+
memInfoSubsystem = "memory"
27+
)
28+
29+
type meminfoCollector struct{}
30+
31+
func init() {
32+
Factories["meminfo"] = NewMeminfoCollector
33+
}
34+
35+
// NewMeminfoCollector returns a new Collector exposing memory stats.
36+
func NewMeminfoCollector() (Collector, error) {
37+
return &meminfoCollector{}, nil
38+
}
39+
40+
// Update calls (*meminfoCollector).getMemInfo to get the platform specific
41+
// memory metrics.
42+
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
43+
memInfo, err := c.getMemInfo()
44+
if err != nil {
45+
return fmt.Errorf("couldn't get meminfo: %s", err)
46+
}
47+
log.Debugf("Set node_mem: %#v", memInfo)
48+
for k, v := range memInfo {
49+
ch <- prometheus.MustNewConstMetric(
50+
prometheus.NewDesc(
51+
prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
52+
fmt.Sprintf("Memory information field %s.", k),
53+
nil, nil,
54+
),
55+
prometheus.GaugeValue, v,
56+
)
57+
}
58+
return nil
59+
}

collector/meminfo_bsd.go

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,41 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
// +build freebsd darwin,amd64 dragonfly
14+
// +build freebsd dragonfly
1515
// +build !nomeminfo
1616

1717
package collector
1818

1919
import (
2020
"fmt"
2121

22-
"github.com/prometheus/client_golang/prometheus"
2322
"golang.org/x/sys/unix"
2423
)
2524

26-
const (
27-
memInfoSubsystem = "memory"
28-
)
29-
30-
type meminfoCollector struct{}
31-
32-
func init() {
33-
Factories["meminfo"] = NewMeminfoCollector
34-
}
35-
36-
// Takes a prometheus registry and returns a new Collector exposing
37-
// Memory stats.
38-
func NewMeminfoCollector() (Collector, error) {
39-
return &meminfoCollector{}, nil
40-
}
41-
42-
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
43-
pages := make(map[string]uint32)
25+
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
26+
info := make(map[string]float64)
4427

4528
size, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
4629
if err != nil {
47-
return fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err)
30+
return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err)
4831
}
49-
pages["active"], _ = unix.SysctlUint32("vm.stats.vm.v_active_count")
50-
pages["inactive"], _ = unix.SysctlUint32("vm.stats.vm.v_inactive_count")
51-
pages["wire"], _ = unix.SysctlUint32("vm.stats.vm.v_wire_count")
52-
pages["cache"], _ = unix.SysctlUint32("vm.stats.vm.v_cache_count")
53-
pages["free"], _ = unix.SysctlUint32("vm.stats.vm.v_free_count")
54-
pages["swappgsin"], _ = unix.SysctlUint32("vm.stats.vm.v_swappgsin")
55-
pages["swappgsout"], _ = unix.SysctlUint32("vm.stats.vm.v_swappgsout")
56-
pages["total"], _ = unix.SysctlUint32("vm.stats.vm.v_page_count")
5732

58-
for k, v := range pages {
59-
ch <- prometheus.MustNewConstMetric(
60-
prometheus.NewDesc(
61-
prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
62-
k+" from sysctl()",
63-
nil, nil,
64-
),
65-
// Convert metrics to kB (same as Linux meminfo).
66-
prometheus.UntypedValue, float64(v)*float64(size),
67-
)
33+
for key, v := range map[string]string{
34+
"active": "vm.stats.vm.v_active_count",
35+
"inactive": "vm.stats.vm.v_inactive_count",
36+
"wire": "vm.stats.vm.v_wire_count",
37+
"cache": "vm.stats.vm.v_cache_count",
38+
"free": "vm.stats.vm.v_free_count",
39+
"swappgsin": "vm.stats.vm.v_swappgsin",
40+
"swappgsout": "vm.stats.vm.v_swappgsout",
41+
"total": "vm.stats.vm.v_page_count",
42+
} {
43+
value, err := unix.SysctlUint32(v)
44+
if err != nil {
45+
return nil, err
46+
}
47+
// Convert metrics to kB (same as Linux meminfo).
48+
info[key] = float64(value) * float64(size)
6849
}
69-
return err
50+
return info, nil
7051
}

collector/meminfo_darwin.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2015 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// +build !nomeminfo
15+
16+
package collector
17+
18+
// #include <mach/mach_host.h>
19+
import "C"
20+
21+
import (
22+
"encoding/binary"
23+
"fmt"
24+
"syscall"
25+
"unsafe"
26+
27+
"golang.org/x/sys/unix"
28+
)
29+
30+
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
31+
infoCount := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT)
32+
vmstat := C.vm_statistics_data_t{}
33+
ret := C.host_statistics(
34+
C.host_t(C.mach_host_self()),
35+
C.HOST_VM_INFO,
36+
C.host_info_t(unsafe.Pointer(&vmstat)),
37+
&infoCount,
38+
)
39+
if ret != C.KERN_SUCCESS {
40+
return nil, fmt.Errorf("Couldn't get memory statistics, host_statistics returned %d", ret)
41+
}
42+
totalb, err := unix.Sysctl("hw.memsize")
43+
if err != nil {
44+
return nil, err
45+
}
46+
// Syscall removes terminating NUL which we need to cast to uint64
47+
total := binary.LittleEndian.Uint64([]byte(totalb + "\x00"))
48+
49+
ps := C.natural_t(syscall.Getpagesize())
50+
return map[string]float64{
51+
"active_bytes_total": float64(ps * vmstat.active_count),
52+
"inactive_bytes_total": float64(ps * vmstat.inactive_count),
53+
"wired_bytes_total": float64(ps * vmstat.wire_count),
54+
"free_bytes_total": float64(ps * vmstat.free_count),
55+
"swapped_in_pages_total": float64(ps * vmstat.pageins),
56+
"swapped_out_pages_total": float64(ps * vmstat.pageouts),
57+
"bytes_total": float64(total),
58+
}, nil
59+
}

collector/meminfo_linux.go

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,47 +23,9 @@ import (
2323
"regexp"
2424
"strconv"
2525
"strings"
26-
27-
"github.com/prometheus/client_golang/prometheus"
28-
"github.com/prometheus/common/log"
29-
)
30-
31-
const (
32-
memInfoSubsystem = "memory"
3326
)
3427

35-
type meminfoCollector struct{}
36-
37-
func init() {
38-
Factories["meminfo"] = NewMeminfoCollector
39-
}
40-
41-
// Takes a prometheus registry and returns a new Collector exposing
42-
// memory stats.
43-
func NewMeminfoCollector() (Collector, error) {
44-
return &meminfoCollector{}, nil
45-
}
46-
47-
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
48-
memInfo, err := getMemInfo()
49-
if err != nil {
50-
return fmt.Errorf("couldn't get meminfo: %s", err)
51-
}
52-
log.Debugf("Set node_mem: %#v", memInfo)
53-
for k, v := range memInfo {
54-
ch <- prometheus.MustNewConstMetric(
55-
prometheus.NewDesc(
56-
prometheus.BuildFQName(Namespace, memInfoSubsystem, k),
57-
fmt.Sprintf("Memory information field %s.", k),
58-
nil, nil,
59-
),
60-
prometheus.GaugeValue, v,
61-
)
62-
}
63-
return nil
64-
}
65-
66-
func getMemInfo() (map[string]float64, error) {
28+
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
6729
file, err := os.Open(procFilePath("meminfo"))
6830
if err != nil {
6931
return nil, err

0 commit comments

Comments
 (0)