diff options
author | Paul Gier <pgier@redhat.com> | 2019-02-19 10:22:54 -0600 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-02-19 17:22:54 +0100 |
commit | cc847f2f44172881d79f40a99f1ad6d90f3e528e (patch) | |
tree | ec1f9268616f7bd7176924f15c08feb5827f7e96 | |
parent | f028b816152f6d5650ca2cd707e45cda7333fdc1 (diff) | |
download | prometheus_node_collector-cc847f2f44172881d79f40a99f1ad6d90f3e528e.tar.bz2 prometheus_node_collector-cc847f2f44172881d79f40a99f1ad6d90f3e528e.tar.xz prometheus_node_collector-cc847f2f44172881d79f40a99f1ad6d90f3e528e.zip |
collector/cpu: split cpu freq metrics into separate collector (#1253)
The cpu frequency information is not always needed and/or available.
This change allows the cpu frequency metrics to be enabled/disabled
separately from the other cpu metrics, and also prevents a frequency
metric failure (such as a parse error) from failing the main cpu
collector.
Fixes #1241
Signed-off-by: Paul Gier <pgier@redhat.com>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | collector/cpu_linux.go | 107 | ||||
-rw-r--r-- | collector/cpu_solaris.go | 70 | ||||
-rw-r--r-- | collector/cpufreq_linux.go | 139 | ||||
-rw-r--r-- | collector/cpufreq_solaris.go | 95 | ||||
-rw-r--r-- | collector/fixtures/e2e-64k-page-output.txt | 1 | ||||
-rw-r--r-- | collector/fixtures/e2e-output.txt | 1 | ||||
-rwxr-xr-x | end-to-end-test.sh | 1 |
9 files changed, 241 insertions, 175 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index cf17e7d..154b4b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -21,6 +21,7 @@ | |||
21 | * [CHANGE] Add separate cpufreq and scaling metrics #1248 | 21 | * [CHANGE] Add separate cpufreq and scaling metrics #1248 |
22 | * [CHANGE] Several systemd metrics have been turned off by default to improve performance #1254 | 22 | * [CHANGE] Several systemd metrics have been turned off by default to improve performance #1254 |
23 | * [CHANGE] Expand systemd collector blacklist #1255 | 23 | * [CHANGE] Expand systemd collector blacklist #1255 |
24 | * [CHANGE] Split cpufreq metrics into a separate collector #1253 | ||
24 | * [ENHANCEMENT] Add Infiniband counters #1120 | 25 | * [ENHANCEMENT] Add Infiniband counters #1120 |
25 | * [ENHANCEMENT] Move network_up labels into new metric network_info #1236 | 26 | * [ENHANCEMENT] Move network_up labels into new metric network_info #1236 |
26 | * [FEATURE] Add a flag to disable exporter metrics #1148 | 27 | * [FEATURE] Add a flag to disable exporter metrics #1148 |
@@ -32,6 +32,7 @@ bonding | Exposes the number of configured and active slaves of Linux bonding in | |||
32 | boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris | 32 | boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris |
33 | conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux | 33 | conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux |
34 | cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris | 34 | cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris |
35 | cpufreq | Exposes CPU frequency statistics | Linux, Solaris | ||
35 | diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD | 36 | diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD |
36 | edac | Exposes error detection and correction statistics. | Linux | 37 | edac | Exposes error detection and correction statistics. | Linux |
37 | entropy | Exposes available entropy. | Linux | 38 | entropy | Exposes available entropy. | Linux |
diff --git a/collector/cpu_linux.go b/collector/cpu_linux.go index 50d8a3b..be63590 100644 --- a/collector/cpu_linux.go +++ b/collector/cpu_linux.go | |||
@@ -23,18 +23,11 @@ import ( | |||
23 | "github.com/prometheus/client_golang/prometheus" | 23 | "github.com/prometheus/client_golang/prometheus" |
24 | "github.com/prometheus/common/log" | 24 | "github.com/prometheus/common/log" |
25 | "github.com/prometheus/procfs" | 25 | "github.com/prometheus/procfs" |
26 | "github.com/prometheus/procfs/sysfs" | ||
27 | ) | 26 | ) |
28 | 27 | ||
29 | type cpuCollector struct { | 28 | type cpuCollector struct { |
30 | cpu *prometheus.Desc | 29 | cpu *prometheus.Desc |
31 | cpuGuest *prometheus.Desc | 30 | cpuGuest *prometheus.Desc |
32 | cpuFreq *prometheus.Desc | ||
33 | cpuFreqMin *prometheus.Desc | ||
34 | cpuFreqMax *prometheus.Desc | ||
35 | scalingFreq *prometheus.Desc | ||
36 | scalingFreqMin *prometheus.Desc | ||
37 | scalingFreqMax *prometheus.Desc | ||
38 | cpuCoreThrottle *prometheus.Desc | 31 | cpuCoreThrottle *prometheus.Desc |
39 | cpuPackageThrottle *prometheus.Desc | 32 | cpuPackageThrottle *prometheus.Desc |
40 | } | 33 | } |
@@ -52,36 +45,6 @@ func NewCPUCollector() (Collector, error) { | |||
52 | "Seconds the cpus spent in guests (VMs) for each mode.", | 45 | "Seconds the cpus spent in guests (VMs) for each mode.", |
53 | []string{"cpu", "mode"}, nil, | 46 | []string{"cpu", "mode"}, nil, |
54 | ), | 47 | ), |
55 | cpuFreq: prometheus.NewDesc( | ||
56 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), | ||
57 | "Current cpu thread frequency in hertz.", | ||
58 | []string{"cpu"}, nil, | ||
59 | ), | ||
60 | cpuFreqMin: prometheus.NewDesc( | ||
61 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_min_hertz"), | ||
62 | "Minimum cpu thread frequency in hertz.", | ||
63 | []string{"cpu"}, nil, | ||
64 | ), | ||
65 | cpuFreqMax: prometheus.NewDesc( | ||
66 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_max_hertz"), | ||
67 | "Maximum cpu thread frequency in hertz.", | ||
68 | []string{"cpu"}, nil, | ||
69 | ), | ||
70 | scalingFreq: prometheus.NewDesc( | ||
71 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_hertz"), | ||
72 | "Current scaled cpu thread frequency in hertz.", | ||
73 | []string{"cpu"}, nil, | ||
74 | ), | ||
75 | scalingFreqMin: prometheus.NewDesc( | ||
76 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_min_hrts"), | ||
77 | "Minimum scaled cpu thread frequency in hertz.", | ||
78 | []string{"cpu"}, nil, | ||
79 | ), | ||
80 | scalingFreqMax: prometheus.NewDesc( | ||
81 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_max_hrts"), | ||
82 | "Maximum scaled cpu thread frequency in hertz.", | ||
83 | []string{"cpu"}, nil, | ||
84 | ), | ||
85 | cpuCoreThrottle: prometheus.NewDesc( | 48 | cpuCoreThrottle: prometheus.NewDesc( |
86 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "core_throttles_total"), | 49 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "core_throttles_total"), |
87 | "Number of times this cpu core has been throttled.", | 50 | "Number of times this cpu core has been throttled.", |
@@ -100,82 +63,12 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | |||
100 | if err := c.updateStat(ch); err != nil { | 63 | if err := c.updateStat(ch); err != nil { |
101 | return err | 64 | return err |
102 | } | 65 | } |
103 | if err := c.updateCPUfreq(ch); err != nil { | ||
104 | return err | ||
105 | } | ||
106 | if err := c.updateThermalThrottle(ch); err != nil { | 66 | if err := c.updateThermalThrottle(ch); err != nil { |
107 | return err | 67 | return err |
108 | } | 68 | } |
109 | return nil | 69 | return nil |
110 | } | 70 | } |
111 | 71 | ||
112 | // updateCPUfreq reads /sys/devices/system/cpu/cpu* and expose cpu frequency statistics. | ||
113 | func (c *cpuCollector) updateCPUfreq(ch chan<- prometheus.Metric) error { | ||
114 | fs, err := sysfs.NewFS(*sysPath) | ||
115 | if err != nil { | ||
116 | return fmt.Errorf("failed to open sysfs: %v", err) | ||
117 | } | ||
118 | |||
119 | cpuFreqs, err := fs.NewSystemCpufreq() | ||
120 | if err != nil { | ||
121 | return err | ||
122 | } | ||
123 | |||
124 | // sysfs cpufreq values are kHz, thus multiply by 1000 to export base units (hz). | ||
125 | // See https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt | ||
126 | for _, stats := range cpuFreqs { | ||
127 | if stats.CpuinfoCurrentFrequency != nil { | ||
128 | ch <- prometheus.MustNewConstMetric( | ||
129 | c.cpuFreq, | ||
130 | prometheus.GaugeValue, | ||
131 | float64(*stats.CpuinfoCurrentFrequency)*1000.0, | ||
132 | stats.Name, | ||
133 | ) | ||
134 | } | ||
135 | if stats.CpuinfoMinimumFrequency != nil { | ||
136 | ch <- prometheus.MustNewConstMetric( | ||
137 | c.cpuFreqMin, | ||
138 | prometheus.GaugeValue, | ||
139 | float64(*stats.CpuinfoMinimumFrequency)*1000.0, | ||
140 | stats.Name, | ||
141 | ) | ||
142 | } | ||
143 | if stats.CpuinfoMaximumFrequency != nil { | ||
144 | ch <- prometheus.MustNewConstMetric( | ||
145 | c.cpuFreqMax, | ||
146 | prometheus.GaugeValue, | ||
147 | float64(*stats.CpuinfoMaximumFrequency)*1000.0, | ||
148 | stats.Name, | ||
149 | ) | ||
150 | } | ||
151 | if stats.ScalingCurrentFrequency != nil { | ||
152 | ch <- prometheus.MustNewConstMetric( | ||
153 | c.scalingFreq, | ||
154 | prometheus.GaugeValue, | ||
155 | float64(*stats.ScalingCurrentFrequency)*1000.0, | ||
156 | stats.Name, | ||
157 | ) | ||
158 | } | ||
159 | if stats.ScalingMinimumFrequency != nil { | ||
160 | ch <- prometheus.MustNewConstMetric( | ||
161 | c.scalingFreqMin, | ||
162 | prometheus.GaugeValue, | ||
163 | float64(*stats.ScalingMinimumFrequency)*1000.0, | ||
164 | stats.Name, | ||
165 | ) | ||
166 | } | ||
167 | if stats.ScalingMaximumFrequency != nil { | ||
168 | ch <- prometheus.MustNewConstMetric( | ||
169 | c.scalingFreqMax, | ||
170 | prometheus.GaugeValue, | ||
171 | float64(*stats.ScalingMaximumFrequency)*1000.0, | ||
172 | stats.Name, | ||
173 | ) | ||
174 | } | ||
175 | } | ||
176 | return nil | ||
177 | } | ||
178 | |||
179 | // updateThermalThrottle reads /sys/devices/system/cpu/cpu* and expose thermal throttle statistics. | 72 | // updateThermalThrottle reads /sys/devices/system/cpu/cpu* and expose thermal throttle statistics. |
180 | func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { | 73 | func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { |
181 | cpus, err := filepath.Glob(sysFilePath("devices/system/cpu/cpu[0-9]*")) | 74 | cpus, err := filepath.Glob(sysFilePath("devices/system/cpu/cpu[0-9]*")) |
diff --git a/collector/cpu_solaris.go b/collector/cpu_solaris.go index f60aeb3..f772765 100644 --- a/collector/cpu_solaris.go +++ b/collector/cpu_solaris.go | |||
@@ -17,20 +17,17 @@ | |||
17 | package collector | 17 | package collector |
18 | 18 | ||
19 | import ( | 19 | import ( |
20 | "fmt" | ||
21 | "strconv" | 20 | "strconv" |
22 | 21 | ||
23 | "github.com/prometheus/client_golang/prometheus" | 22 | "github.com/prometheus/client_golang/prometheus" |
24 | "github.com/siebenmann/go-kstat" | 23 | kstat "github.com/siebenmann/go-kstat" |
25 | ) | 24 | ) |
26 | 25 | ||
27 | // #include <unistd.h> | 26 | // #include <unistd.h> |
28 | import "C" | 27 | import "C" |
29 | 28 | ||
30 | type cpuCollector struct { | 29 | type cpuCollector struct { |
31 | cpu typedDesc | 30 | cpu typedDesc |
32 | cpuFreq *prometheus.Desc | ||
33 | cpuFreqMax *prometheus.Desc | ||
34 | } | 31 | } |
35 | 32 | ||
36 | func init() { | 33 | func init() { |
@@ -40,30 +37,10 @@ func init() { | |||
40 | func NewCpuCollector() (Collector, error) { | 37 | func NewCpuCollector() (Collector, error) { |
41 | return &cpuCollector{ | 38 | return &cpuCollector{ |
42 | cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | 39 | 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 | 40 | }, nil |
54 | } | 41 | } |
55 | 42 | ||
56 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | 43 | 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) | 44 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) |
68 | 45 | ||
69 | tok, err := kstat.Open() | 46 | tok, err := kstat.Open() |
@@ -95,46 +72,3 @@ func (c *cpuCollector) updateCPUstats(ch chan<- prometheus.Metric) error { | |||
95 | } | 72 | } |
96 | return nil | 73 | return nil |
97 | } | 74 | } |
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 | } | ||
diff --git a/collector/cpufreq_linux.go b/collector/cpufreq_linux.go new file mode 100644 index 0000000..11f6f38 --- /dev/null +++ b/collector/cpufreq_linux.go | |||
@@ -0,0 +1,139 @@ | |||
1 | // Copyright 2019 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 !nocpu | ||
15 | |||
16 | package collector | ||
17 | |||
18 | import ( | ||
19 | "fmt" | ||
20 | |||
21 | "github.com/prometheus/client_golang/prometheus" | ||
22 | "github.com/prometheus/procfs/sysfs" | ||
23 | ) | ||
24 | |||
25 | type cpuFreqCollector struct { | ||
26 | cpuFreq *prometheus.Desc | ||
27 | cpuFreqMin *prometheus.Desc | ||
28 | cpuFreqMax *prometheus.Desc | ||
29 | scalingFreq *prometheus.Desc | ||
30 | scalingFreqMin *prometheus.Desc | ||
31 | scalingFreqMax *prometheus.Desc | ||
32 | } | ||
33 | |||
34 | func init() { | ||
35 | registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) | ||
36 | } | ||
37 | |||
38 | // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics. | ||
39 | func NewCPUFreqCollector() (Collector, error) { | ||
40 | return &cpuFreqCollector{ | ||
41 | cpuFreq: prometheus.NewDesc( | ||
42 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), | ||
43 | "Current cpu thread frequency in hertz.", | ||
44 | []string{"cpu"}, nil, | ||
45 | ), | ||
46 | cpuFreqMin: prometheus.NewDesc( | ||
47 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_min_hertz"), | ||
48 | "Minimum cpu thread frequency in hertz.", | ||
49 | []string{"cpu"}, nil, | ||
50 | ), | ||
51 | cpuFreqMax: prometheus.NewDesc( | ||
52 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_max_hertz"), | ||
53 | "Maximum cpu thread frequency in hertz.", | ||
54 | []string{"cpu"}, nil, | ||
55 | ), | ||
56 | scalingFreq: prometheus.NewDesc( | ||
57 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_hertz"), | ||
58 | "Current scaled cpu thread frequency in hertz.", | ||
59 | []string{"cpu"}, nil, | ||
60 | ), | ||
61 | scalingFreqMin: prometheus.NewDesc( | ||
62 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_min_hrts"), | ||
63 | "Minimum scaled cpu thread frequency in hertz.", | ||
64 | []string{"cpu"}, nil, | ||
65 | ), | ||
66 | scalingFreqMax: prometheus.NewDesc( | ||
67 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "scaling_frequency_max_hrts"), | ||
68 | "Maximum scaled cpu thread frequency in hertz.", | ||
69 | []string{"cpu"}, nil, | ||
70 | ), | ||
71 | }, nil | ||
72 | } | ||
73 | |||
74 | // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/. | ||
75 | func (c *cpuFreqCollector) Update(ch chan<- prometheus.Metric) error { | ||
76 | fs, err := sysfs.NewFS(*sysPath) | ||
77 | if err != nil { | ||
78 | return fmt.Errorf("failed to open sysfs: %v", err) | ||
79 | } | ||
80 | |||
81 | cpuFreqs, err := fs.NewSystemCpufreq() | ||
82 | if err != nil { | ||
83 | return err | ||
84 | } | ||
85 | |||
86 | // sysfs cpufreq values are kHz, thus multiply by 1000 to export base units (hz). | ||
87 | // See https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt | ||
88 | for _, stats := range cpuFreqs { | ||
89 | if stats.CpuinfoCurrentFrequency != nil { | ||
90 | ch <- prometheus.MustNewConstMetric( | ||
91 | c.cpuFreq, | ||
92 | prometheus.GaugeValue, | ||
93 | float64(*stats.CpuinfoCurrentFrequency)*1000.0, | ||
94 | stats.Name, | ||
95 | ) | ||
96 | } | ||
97 | if stats.CpuinfoMinimumFrequency != nil { | ||
98 | ch <- prometheus.MustNewConstMetric( | ||
99 | c.cpuFreqMin, | ||
100 | prometheus.GaugeValue, | ||
101 | float64(*stats.CpuinfoMinimumFrequency)*1000.0, | ||
102 | stats.Name, | ||
103 | ) | ||
104 | } | ||
105 | if stats.CpuinfoMaximumFrequency != nil { | ||
106 | ch <- prometheus.MustNewConstMetric( | ||
107 | c.cpuFreqMax, | ||
108 | prometheus.GaugeValue, | ||
109 | float64(*stats.CpuinfoMaximumFrequency)*1000.0, | ||
110 | stats.Name, | ||
111 | ) | ||
112 | } | ||
113 | if stats.ScalingCurrentFrequency != nil { | ||
114 | ch <- prometheus.MustNewConstMetric( | ||
115 | c.scalingFreq, | ||
116 | prometheus.GaugeValue, | ||
117 | float64(*stats.ScalingCurrentFrequency)*1000.0, | ||
118 | stats.Name, | ||
119 | ) | ||
120 | } | ||
121 | if stats.ScalingMinimumFrequency != nil { | ||
122 | ch <- prometheus.MustNewConstMetric( | ||
123 | c.scalingFreqMin, | ||
124 | prometheus.GaugeValue, | ||
125 | float64(*stats.ScalingMinimumFrequency)*1000.0, | ||
126 | stats.Name, | ||
127 | ) | ||
128 | } | ||
129 | if stats.ScalingMaximumFrequency != nil { | ||
130 | ch <- prometheus.MustNewConstMetric( | ||
131 | c.scalingFreqMax, | ||
132 | prometheus.GaugeValue, | ||
133 | float64(*stats.ScalingMaximumFrequency)*1000.0, | ||
134 | stats.Name, | ||
135 | ) | ||
136 | } | ||
137 | } | ||
138 | return nil | ||
139 | } | ||
diff --git a/collector/cpufreq_solaris.go b/collector/cpufreq_solaris.go new file mode 100644 index 0000000..77ac3ab --- /dev/null +++ b/collector/cpufreq_solaris.go | |||
@@ -0,0 +1,95 @@ | |||
1 | // Copyright 2019 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 | kstat "github.com/siebenmann/go-kstat" | ||
25 | ) | ||
26 | |||
27 | // #include <unistd.h> | ||
28 | import "C" | ||
29 | |||
30 | type cpuFreqCollector struct { | ||
31 | cpuFreq *prometheus.Desc | ||
32 | cpuFreqMax *prometheus.Desc | ||
33 | } | ||
34 | |||
35 | func init() { | ||
36 | registerCollector("cpufreq", defaultEnabled, NewCpuFreqCollector) | ||
37 | } | ||
38 | |||
39 | func NewFreqCpuCollector() (Collector, error) { | ||
40 | return &cpuFreqCollector{ | ||
41 | cpuFreq: prometheus.NewDesc( | ||
42 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), | ||
43 | "Current cpu thread frequency in hertz.", | ||
44 | []string{"cpu"}, nil, | ||
45 | ), | ||
46 | cpuFreqMax: prometheus.NewDesc( | ||
47 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_max_hertz"), | ||
48 | "Maximum cpu thread frequency in hertz.", | ||
49 | []string{"cpu"}, nil, | ||
50 | ), | ||
51 | }, nil | ||
52 | } | ||
53 | |||
54 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | ||
55 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) | ||
56 | |||
57 | tok, err := kstat.Open() | ||
58 | if err != nil { | ||
59 | return err | ||
60 | } | ||
61 | |||
62 | defer tok.Close() | ||
63 | |||
64 | for cpu := 0; cpu < int(ncpus); cpu++ { | ||
65 | ksCPUInfo, err := tok.Lookup("cpu_info", cpu, fmt.Sprintf("cpu_info%d", cpu)) | ||
66 | if err != nil { | ||
67 | return err | ||
68 | } | ||
69 | cpuFreqV, err := ksCPUInfo.GetNamed("current_clock_Hz") | ||
70 | if err != nil { | ||
71 | return err | ||
72 | } | ||
73 | |||
74 | cpuFreqMaxV, err := ksCPUInfo.GetNamed("clock_MHz") | ||
75 | if err != nil { | ||
76 | return err | ||
77 | } | ||
78 | |||
79 | lcpu := strconv.Itoa(cpu) | ||
80 | ch <- prometheus.MustNewConstMetric( | ||
81 | c.cpuFreq, | ||
82 | prometheus.GaugeValue, | ||
83 | float64(cpuFreqV.UintVal), | ||
84 | lcpu, | ||
85 | ) | ||
86 | // Multiply by 1e+6 to convert MHz to Hz. | ||
87 | ch <- prometheus.MustNewConstMetric( | ||
88 | c.cpuFreqMax, | ||
89 | prometheus.GaugeValue, | ||
90 | float64(cpuFreqMaxV.IntVal)*1e+6, | ||
91 | lcpu, | ||
92 | ) | ||
93 | } | ||
94 | return nil | ||
95 | } | ||
diff --git a/collector/fixtures/e2e-64k-page-output.txt b/collector/fixtures/e2e-64k-page-output.txt index aa96e91..ea59731 100644 --- a/collector/fixtures/e2e-64k-page-output.txt +++ b/collector/fixtures/e2e-64k-page-output.txt | |||
@@ -2340,6 +2340,7 @@ node_scrape_collector_success{collector="bonding"} 1 | |||
2340 | node_scrape_collector_success{collector="buddyinfo"} 1 | 2340 | node_scrape_collector_success{collector="buddyinfo"} 1 |
2341 | node_scrape_collector_success{collector="conntrack"} 1 | 2341 | node_scrape_collector_success{collector="conntrack"} 1 |
2342 | node_scrape_collector_success{collector="cpu"} 1 | 2342 | node_scrape_collector_success{collector="cpu"} 1 |
2343 | node_scrape_collector_success{collector="cpufreq"} 1 | ||
2343 | node_scrape_collector_success{collector="diskstats"} 1 | 2344 | node_scrape_collector_success{collector="diskstats"} 1 |
2344 | node_scrape_collector_success{collector="drbd"} 1 | 2345 | node_scrape_collector_success{collector="drbd"} 1 |
2345 | node_scrape_collector_success{collector="edac"} 1 | 2346 | node_scrape_collector_success{collector="edac"} 1 |
diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index d278833..f4c6d56 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt | |||
@@ -2340,6 +2340,7 @@ node_scrape_collector_success{collector="bonding"} 1 | |||
2340 | node_scrape_collector_success{collector="buddyinfo"} 1 | 2340 | node_scrape_collector_success{collector="buddyinfo"} 1 |
2341 | node_scrape_collector_success{collector="conntrack"} 1 | 2341 | node_scrape_collector_success{collector="conntrack"} 1 |
2342 | node_scrape_collector_success{collector="cpu"} 1 | 2342 | node_scrape_collector_success{collector="cpu"} 1 |
2343 | node_scrape_collector_success{collector="cpufreq"} 1 | ||
2343 | node_scrape_collector_success{collector="diskstats"} 1 | 2344 | node_scrape_collector_success{collector="diskstats"} 1 |
2344 | node_scrape_collector_success{collector="drbd"} 1 | 2345 | node_scrape_collector_success{collector="drbd"} 1 |
2345 | node_scrape_collector_success{collector="edac"} 1 | 2346 | node_scrape_collector_success{collector="edac"} 1 |
diff --git a/end-to-end-test.sh b/end-to-end-test.sh index 43f8fbf..ea24cf5 100755 --- a/end-to-end-test.sh +++ b/end-to-end-test.sh | |||
@@ -8,6 +8,7 @@ enabled_collectors=$(cat << COLLECTORS | |||
8 | buddyinfo | 8 | buddyinfo |
9 | conntrack | 9 | conntrack |
10 | cpu | 10 | cpu |
11 | cpufreq | ||
11 | diskstats | 12 | diskstats |
12 | drbd | 13 | drbd |
13 | edac | 14 | edac |