aboutsummaryrefslogtreecommitdiff
path: root/collector
diff options
context:
space:
mode:
authorDaniel Hodges <hodges.daniel.scott@gmail.com>2020-04-17 05:59:07 -0400
committerGitHub <noreply@github.com>2020-04-17 11:59:07 +0200
commit44357ed677f7845ab8d202bfc277f341b63e1fdc (patch)
tree526c621696c45bbddf9f417e2f8574dfc617ccc8 /collector
parent4135c00d33c9788df8c451bf99af37b218fae1e6 (diff)
downloadprometheus_node_collector-44357ed677f7845ab8d202bfc277f341b63e1fdc.tar.bz2
prometheus_node_collector-44357ed677f7845ab8d202bfc277f341b63e1fdc.tar.xz
prometheus_node_collector-44357ed677f7845ab8d202bfc277f341b63e1fdc.zip
Fix initialization in perf collector when using multiple CPUs (#1665)
* Fix initialization in perf collector when using multiple CPUs Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
Diffstat (limited to 'collector')
-rw-r--r--collector/perf_linux.go3
-rw-r--r--collector/perf_linux_test.go65
2 files changed, 66 insertions, 2 deletions
diff --git a/collector/perf_linux.go b/collector/perf_linux.go
index bb8716a..6d19683 100644
--- a/collector/perf_linux.go
+++ b/collector/perf_linux.go
@@ -135,18 +135,21 @@ func NewPerfCollector(logger log.Logger) (Collector, error) {
135 return nil, err 135 return nil, err
136 } 136 }
137 collector.perfHwProfilers[cpu] = &hwProf 137 collector.perfHwProfilers[cpu] = &hwProf
138 collector.hwProfilerCPUMap[&hwProf] = cpu
138 139
139 swProf := perf.NewSoftwareProfiler(-1, cpu) 140 swProf := perf.NewSoftwareProfiler(-1, cpu)
140 if err := swProf.Start(); err != nil { 141 if err := swProf.Start(); err != nil {
141 return nil, err 142 return nil, err
142 } 143 }
143 collector.perfSwProfilers[cpu] = &swProf 144 collector.perfSwProfilers[cpu] = &swProf
145 collector.swProfilerCPUMap[&swProf] = cpu
144 146
145 cacheProf := perf.NewCacheProfiler(-1, cpu) 147 cacheProf := perf.NewCacheProfiler(-1, cpu)
146 if err := cacheProf.Start(); err != nil { 148 if err := cacheProf.Start(); err != nil {
147 return nil, err 149 return nil, err
148 } 150 }
149 collector.perfCacheProfilers[cpu] = &cacheProf 151 collector.perfCacheProfilers[cpu] = &cacheProf
152 collector.cacheProfilerCPUMap[&cacheProf] = cpu
150 } 153 }
151 154
152 collector.desc = map[string]*prometheus.Desc{ 155 collector.desc = map[string]*prometheus.Desc{
diff --git a/collector/perf_linux_test.go b/collector/perf_linux_test.go
index eecfab9..fca5455 100644
--- a/collector/perf_linux_test.go
+++ b/collector/perf_linux_test.go
@@ -16,16 +16,18 @@
16package collector 16package collector
17 17
18import ( 18import (
19 "github.com/go-kit/kit/log"
20 "io/ioutil" 19 "io/ioutil"
20 "runtime"
21 "strconv" 21 "strconv"
22 "strings" 22 "strings"
23 "testing" 23 "testing"
24 24
25 "github.com/go-kit/kit/log"
26
25 "github.com/prometheus/client_golang/prometheus" 27 "github.com/prometheus/client_golang/prometheus"
26) 28)
27 29
28func TestPerfCollector(t *testing.T) { 30func canTestPerf(t *testing.T) {
29 paranoidBytes, err := ioutil.ReadFile("/proc/sys/kernel/perf_event_paranoid") 31 paranoidBytes, err := ioutil.ReadFile("/proc/sys/kernel/perf_event_paranoid")
30 if err != nil { 32 if err != nil {
31 t.Skip("Procfs not mounted, skipping perf tests") 33 t.Skip("Procfs not mounted, skipping perf tests")
@@ -38,6 +40,10 @@ func TestPerfCollector(t *testing.T) {
38 if paranoid >= 1 { 40 if paranoid >= 1 {
39 t.Skip("Skipping perf tests, set perf_event_paranoid to 0") 41 t.Skip("Skipping perf tests, set perf_event_paranoid to 0")
40 } 42 }
43}
44
45func TestPerfCollector(t *testing.T) {
46 canTestPerf(t)
41 collector, err := NewPerfCollector(log.NewNopLogger()) 47 collector, err := NewPerfCollector(log.NewNopLogger())
42 if err != nil { 48 if err != nil {
43 t.Fatal(err) 49 t.Fatal(err)
@@ -55,6 +61,61 @@ func TestPerfCollector(t *testing.T) {
55 } 61 }
56} 62}
57 63
64func TestPerfCollectorStride(t *testing.T) {
65 canTestPerf(t)
66
67 tests := []struct {
68 name string
69 flag string
70 exCpus []int
71 }{
72 {
73 name: "valid single cpu",
74 flag: "1",
75 exCpus: []int{1},
76 },
77 {
78 name: "valid range cpus",
79 flag: "1-5",
80 exCpus: []int{1, 2, 3, 4, 5},
81 },
82 {
83 name: "valid stride",
84 flag: "1-8:2",
85 exCpus: []int{1, 3, 5, 7},
86 },
87 }
88
89 for _, test := range tests {
90 t.Run(test.name, func(t *testing.T) {
91 ncpu := runtime.NumCPU()
92 for _, cpu := range test.exCpus {
93 if cpu > ncpu {
94 t.Skipf("Skipping test because runtime.NumCPU < %d", cpu)
95 }
96 }
97 perfCPUsFlag = &test.flag
98 collector, err := NewPerfCollector(log.NewNopLogger())
99 if err != nil {
100 t.Fatal(err)
101 }
102
103 c := collector.(*perfCollector)
104 for _, cpu := range test.exCpus {
105 if _, ok := c.perfHwProfilers[cpu]; !ok {
106 t.Fatalf("Expected CPU %v in hardware profilers", cpu)
107 }
108 if _, ok := c.perfSwProfilers[cpu]; !ok {
109 t.Fatalf("Expected CPU %v in software profilers", cpu)
110 }
111 if _, ok := c.perfCacheProfilers[cpu]; !ok {
112 t.Fatalf("Expected CPU %v in cache profilers", cpu)
113 }
114 }
115 })
116 }
117}
118
58func TestPerfCPUFlagToCPUs(t *testing.T) { 119func TestPerfCPUFlagToCPUs(t *testing.T) {
59 tests := []struct { 120 tests := []struct {
60 name string 121 name string