aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gier <pgier@redhat.com>2019-02-19 10:22:54 -0600
committerBen Kochie <superq@gmail.com>2019-02-19 17:22:54 +0100
commitcc847f2f44172881d79f40a99f1ad6d90f3e528e (patch)
treeec1f9268616f7bd7176924f15c08feb5827f7e96
parentf028b816152f6d5650ca2cd707e45cda7333fdc1 (diff)
downloadprometheus_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.md1
-rw-r--r--README.md1
-rw-r--r--collector/cpu_linux.go107
-rw-r--r--collector/cpu_solaris.go70
-rw-r--r--collector/cpufreq_linux.go139
-rw-r--r--collector/cpufreq_solaris.go95
-rw-r--r--collector/fixtures/e2e-64k-page-output.txt1
-rw-r--r--collector/fixtures/e2e-output.txt1
-rwxr-xr-xend-to-end-test.sh1
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
diff --git a/README.md b/README.md
index 3196ab3..8fbb8f1 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ bonding | Exposes the number of configured and active slaves of Linux bonding in
32boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris 32boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris
33conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux 33conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux
34cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris 34cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris
35cpufreq | Exposes CPU frequency statistics | Linux, Solaris
35diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD 36diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD
36edac | Exposes error detection and correction statistics. | Linux 37edac | Exposes error detection and correction statistics. | Linux
37entropy | Exposes available entropy. | Linux 38entropy | 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
29type cpuCollector struct { 28type 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.
113func (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.
180func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { 73func (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 @@
17package collector 17package collector
18 18
19import ( 19import (
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>
28import "C" 27import "C"
29 28
30type cpuCollector struct { 29type cpuCollector struct {
31 cpu typedDesc 30 cpu typedDesc
32 cpuFreq *prometheus.Desc
33 cpuFreqMax *prometheus.Desc
34} 31}
35 32
36func init() { 33func init() {
@@ -40,30 +37,10 @@ func init() {
40func NewCpuCollector() (Collector, error) { 37func 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
56func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { 43func (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
66func (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
99func (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
16package collector
17
18import (
19 "fmt"
20
21 "github.com/prometheus/client_golang/prometheus"
22 "github.com/prometheus/procfs/sysfs"
23)
24
25type 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
34func init() {
35 registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector)
36}
37
38// NewCPUFreqCollector returns a new Collector exposing kernel/system statistics.
39func 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/.
75func (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
17package collector
18
19import (
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>
28import "C"
29
30type cpuFreqCollector struct {
31 cpuFreq *prometheus.Desc
32 cpuFreqMax *prometheus.Desc
33}
34
35func init() {
36 registerCollector("cpufreq", defaultEnabled, NewCpuFreqCollector)
37}
38
39func 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
54func (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
2340node_scrape_collector_success{collector="buddyinfo"} 1 2340node_scrape_collector_success{collector="buddyinfo"} 1
2341node_scrape_collector_success{collector="conntrack"} 1 2341node_scrape_collector_success{collector="conntrack"} 1
2342node_scrape_collector_success{collector="cpu"} 1 2342node_scrape_collector_success{collector="cpu"} 1
2343node_scrape_collector_success{collector="cpufreq"} 1
2343node_scrape_collector_success{collector="diskstats"} 1 2344node_scrape_collector_success{collector="diskstats"} 1
2344node_scrape_collector_success{collector="drbd"} 1 2345node_scrape_collector_success{collector="drbd"} 1
2345node_scrape_collector_success{collector="edac"} 1 2346node_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
2340node_scrape_collector_success{collector="buddyinfo"} 1 2340node_scrape_collector_success{collector="buddyinfo"} 1
2341node_scrape_collector_success{collector="conntrack"} 1 2341node_scrape_collector_success{collector="conntrack"} 1
2342node_scrape_collector_success{collector="cpu"} 1 2342node_scrape_collector_success{collector="cpu"} 1
2343node_scrape_collector_success{collector="cpufreq"} 1
2343node_scrape_collector_success{collector="diskstats"} 1 2344node_scrape_collector_success{collector="diskstats"} 1
2344node_scrape_collector_success{collector="drbd"} 1 2345node_scrape_collector_success{collector="drbd"} 1
2345node_scrape_collector_success{collector="edac"} 1 2346node_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