Skip to content

Commit db59fa8

Browse files
committed
process metrics on darwin
1 parent afb141d commit db59fa8

File tree

315 files changed

+189172
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

315 files changed

+189172
-1
lines changed

process_metrics_darwin.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//go:build darwin
2+
3+
package metrics
4+
5+
import "C"
6+
import (
7+
"io"
8+
"log"
9+
"os"
10+
"syscall"
11+
"time"
12+
13+
"golang.org/x/sys/unix"
14+
)
15+
16+
func writeProcessMetrics(w io.Writer) {
17+
if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil {
18+
if len(procs) == 1 {
19+
startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9)
20+
WriteGaugeUint64(w, "process_start_time_seconds", uint64(startTime))
21+
} else {
22+
log.Printf("ERROR: metrics: sysctl() returned %d proc structs (expected 1)", len(procs))
23+
}
24+
} else {
25+
log.Printf("ERROR: metrics: %s", err)
26+
}
27+
28+
// The proc structure returned by kern.proc.pid above has an Rusage member,
29+
// but it is not filled in, so it needs to be fetched by getrusage(2). For
30+
// that call, the UTime, STime, and Maxrss members are filled out, but not
31+
// Ixrss, Idrss, or Isrss for the memory usage. Memory stats will require
32+
// access to the C API to call task_info(TASK_BASIC_INFO).
33+
rusage := unix.Rusage{}
34+
35+
if err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil {
36+
cpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds()
37+
WriteGaugeFloat64(w, "process_cpu_seconds_total", cpuTime)
38+
} else {
39+
log.Printf("ERROR: metrics: %s", err)
40+
}
41+
42+
//if rss, vsize, err := getMemory(); err == nil {
43+
// WriteGaugeFloat64(w, "process_resident_memory_bytes", rss)
44+
// WriteGaugeFloat64(w, "process_virtual_memory_bytes", vsize)
45+
//} else {
46+
// log.Printf("ERROR: metrics: %s", err)
47+
//}
48+
49+
if addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil {
50+
WriteGaugeFloat64(w, "process_virtual_memory_max_bytes", float64(addressSpace))
51+
} else {
52+
log.Printf("ERROR: metrics: %s", err)
53+
}
54+
}
55+
56+
func writeFDMetrics(w io.Writer) {
57+
if fds, err := getOpenFileCount(); err == nil {
58+
WriteGaugeFloat64(w, "process_open_fds", fds)
59+
} else {
60+
log.Printf("ERROR: metrics: %s", err)
61+
}
62+
63+
if openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil {
64+
WriteGaugeFloat64(w, "process_max_fds", float64(openFiles))
65+
} else {
66+
log.Printf("ERROR: metrics: %s", err)
67+
}
68+
}
69+
70+
//func getMemory() (float64, float64, error) {
71+
// var rss, vsize C.ulonglong
72+
//
73+
// if err := C.get_memory_info(&rss, &vsize); err != 0 {
74+
// return 0, 0, fmt.Errorf("task_info() failed with 0x%x", int(err))
75+
// }
76+
//
77+
// return float64(vsize), float64(rss), nil
78+
//}
79+
80+
func getOpenFileCount() (float64, error) {
81+
// Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to
82+
// return a list of open fds, but that requires a way to call C APIs. The
83+
// benefits, however, include fewer system calls and not failing when at the
84+
// open file soft limit.
85+
86+
if dir, err := os.Open("/dev/fd"); err != nil {
87+
return 0.0, err
88+
} else {
89+
defer dir.Close()
90+
91+
// Avoid ReadDir(), as it calls stat(2) on each descriptor. Not only is
92+
// that info not used, but KQUEUE descriptors fail stat(2), which causes
93+
// the whole method to fail.
94+
if names, err := dir.Readdirnames(0); err != nil {
95+
return 0.0, err
96+
} else {
97+
// Subtract 1 to ignore the open /dev/fd descriptor above.
98+
return float64(len(names) - 1), nil
99+
}
100+
}
101+
}
102+
103+
func getSoftLimit(which int) (uint64, error) {
104+
rlimit := syscall.Rlimit{}
105+
106+
if err := syscall.Getrlimit(which, &rlimit); err != nil {
107+
return 0, err
108+
}
109+
110+
return rlimit.Cur, nil
111+
}

process_metrics_other.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build !linux && !windows && !solaris
1+
//go:build !linux && !windows && !solaris && !darwin
22

33
package metrics
44

vendor/golang.org/x/sys/unix/.gitignore

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/golang.org/x/sys/unix/README.md

Lines changed: 184 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/golang.org/x/sys/unix/affinity_linux.go

Lines changed: 86 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)