diff options
author | Jon Davies <jpds@protonmail.com> | 2019-01-12 12:33:56 +0000 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-01-12 13:33:56 +0100 |
commit | e7664852867694265b093f79a8d8a4dcf27d0e82 (patch) | |
tree | b0addcc6a5192624834d56d5c613475fc2291fbe /collector/cpu_solaris.go | |
parent | a616953b9aa996594459f0ea17e85432365582c2 (diff) | |
download | prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.tar.bz2 prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.tar.xz prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.zip |
Add kstat-based Solaris metrics (#1197)
* collector/loadavg_solaris.go: Use libkstat to gather load averages.
* go.mod: Added go-kstat.
* boot_time_solaris.go: Added.
* cpu_solaris.go: Added.
* README.md: Updated entries for Solaris.
* collector/zfs_solaris.go: Added.
* CHANGELOG.md: Added note about kstat-based Solaris metrics.
Signed-off-by: Jonathan Davies <jpds@protonmail.com>
Diffstat (limited to 'collector/cpu_solaris.go')
-rw-r--r-- | collector/cpu_solaris.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/collector/cpu_solaris.go b/collector/cpu_solaris.go new file mode 100644 index 0000000..f60aeb3 --- /dev/null +++ b/collector/cpu_solaris.go | |||
@@ -0,0 +1,140 @@ | |||
1 | // Copyright 2018 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 solaris | ||
15 | // +build !nocpu | ||
16 | |||
17 | package collector | ||
18 | |||
19 | import ( | ||
20 | "fmt" | ||
21 | "strconv" | ||
22 | |||
23 | "github.com/prometheus/client_golang/prometheus" | ||
24 | "github.com/siebenmann/go-kstat" | ||
25 | ) | ||
26 | |||
27 | // #include <unistd.h> | ||
28 | import "C" | ||
29 | |||
30 | type cpuCollector struct { | ||
31 | cpu typedDesc | ||
32 | cpuFreq *prometheus.Desc | ||
33 | cpuFreqMax *prometheus.Desc | ||
34 | } | ||
35 | |||
36 | func init() { | ||
37 | registerCollector("cpu", defaultEnabled, NewCpuCollector) | ||
38 | } | ||
39 | |||
40 | func NewCpuCollector() (Collector, error) { | ||
41 | return &cpuCollector{ | ||
42 | cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||
43 | cpuFreq: prometheus.NewDesc( | ||
44 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), | ||
45 | "Current cpu thread frequency in hertz.", | ||
46 | []string{"cpu"}, nil, | ||
47 | ), | ||
48 | cpuFreqMax: prometheus.NewDesc( | ||
49 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_max_hertz"), | ||
50 | "Maximum cpu thread frequency in hertz.", | ||
51 | []string{"cpu"}, nil, | ||
52 | ), | ||
53 | }, nil | ||
54 | } | ||
55 | |||
56 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | ||
57 | if err := c.updateCPUstats(ch); err != nil { | ||
58 | return err | ||
59 | } | ||
60 | if err := c.updateCPUfreq(ch); err != nil { | ||
61 | return err | ||
62 | } | ||
63 | return nil | ||
64 | } | ||
65 | |||
66 | func (c *cpuCollector) updateCPUstats(ch chan<- prometheus.Metric) error { | ||
67 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) | ||
68 | |||
69 | tok, err := kstat.Open() | ||
70 | if err != nil { | ||
71 | return err | ||
72 | } | ||
73 | |||
74 | defer tok.Close() | ||
75 | |||
76 | for cpu := 0; cpu < int(ncpus); cpu++ { | ||
77 | ksCPU, err := tok.Lookup("cpu", cpu, "sys") | ||
78 | if err != nil { | ||
79 | return err | ||
80 | } | ||
81 | |||
82 | for k, v := range map[string]string{ | ||
83 | "idle": "cpu_ticks_idle", | ||
84 | "kernel": "cpu_ticks_kernel", | ||
85 | "user": "cpu_ticks_user", | ||
86 | "wait": "cpu_ticks_wait", | ||
87 | } { | ||
88 | kstatValue, err := ksCPU.GetNamed(v) | ||
89 | if err != nil { | ||
90 | return err | ||
91 | } | ||
92 | |||
93 | ch <- c.cpu.mustNewConstMetric(float64(kstatValue.UintVal), strconv.Itoa(cpu), k) | ||
94 | } | ||
95 | } | ||
96 | return nil | ||
97 | } | ||
98 | |||
99 | func (c *cpuCollector) updateCPUfreq(ch chan<- prometheus.Metric) error { | ||
100 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) | ||
101 | |||
102 | tok, err := kstat.Open() | ||
103 | if err != nil { | ||
104 | return err | ||
105 | } | ||
106 | |||
107 | defer tok.Close() | ||
108 | |||
109 | for cpu := 0; cpu < int(ncpus); cpu++ { | ||
110 | ksCPUInfo, err := tok.Lookup("cpu_info", cpu, fmt.Sprintf("cpu_info%d", cpu)) | ||
111 | if err != nil { | ||
112 | return err | ||
113 | } | ||
114 | cpuFreqV, err := ksCPUInfo.GetNamed("current_clock_Hz") | ||
115 | if err != nil { | ||
116 | return err | ||
117 | } | ||
118 | |||
119 | cpuFreqMaxV, err := ksCPUInfo.GetNamed("clock_MHz") | ||
120 | if err != nil { | ||
121 | return err | ||
122 | } | ||
123 | |||
124 | lcpu := strconv.Itoa(cpu) | ||
125 | ch <- prometheus.MustNewConstMetric( | ||
126 | c.cpuFreq, | ||
127 | prometheus.GaugeValue, | ||
128 | float64(cpuFreqV.UintVal), | ||
129 | lcpu, | ||
130 | ) | ||
131 | // Multiply by 1e+6 to convert MHz to Hz. | ||
132 | ch <- prometheus.MustNewConstMetric( | ||
133 | c.cpuFreqMax, | ||
134 | prometheus.GaugeValue, | ||
135 | float64(cpuFreqMaxV.IntVal)*1e+6, | ||
136 | lcpu, | ||
137 | ) | ||
138 | } | ||
139 | return nil | ||
140 | } | ||