aboutsummaryrefslogtreecommitdiff
path: root/collector/cpu_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'collector/cpu_linux.go')
-rw-r--r--collector/cpu_linux.go74
1 files changed, 72 insertions, 2 deletions
diff --git a/collector/cpu_linux.go b/collector/cpu_linux.go
index dfa4d4a..65476d3 100644
--- a/collector/cpu_linux.go
+++ b/collector/cpu_linux.go
@@ -18,6 +18,7 @@ package collector
18import ( 18import (
19 "fmt" 19 "fmt"
20 "path/filepath" 20 "path/filepath"
21 "regexp"
21 "strconv" 22 "strconv"
22 "sync" 23 "sync"
23 24
@@ -32,16 +33,23 @@ type cpuCollector struct {
32 fs procfs.FS 33 fs procfs.FS
33 cpu *prometheus.Desc 34 cpu *prometheus.Desc
34 cpuInfo *prometheus.Desc 35 cpuInfo *prometheus.Desc
36 cpuFlagsInfo *prometheus.Desc
37 cpuBugsInfo *prometheus.Desc
35 cpuGuest *prometheus.Desc 38 cpuGuest *prometheus.Desc
36 cpuCoreThrottle *prometheus.Desc 39 cpuCoreThrottle *prometheus.Desc
37 cpuPackageThrottle *prometheus.Desc 40 cpuPackageThrottle *prometheus.Desc
38 logger log.Logger 41 logger log.Logger
39 cpuStats []procfs.CPUStat 42 cpuStats []procfs.CPUStat
40 cpuStatsMutex sync.Mutex 43 cpuStatsMutex sync.Mutex
44
45 cpuFlagsIncludeRegexp *regexp.Regexp
46 cpuBugsIncludeRegexp *regexp.Regexp
41} 47}
42 48
43var ( 49var (
44 enableCPUInfo = kingpin.Flag("collector.cpu.info", "Enables metric cpu_info").Bool() 50 enableCPUInfo = kingpin.Flag("collector.cpu.info", "Enables metric cpu_info").Bool()
51 flagsInclude = kingpin.Flag("collector.cpu.info.flags-include", "Filter the `flags` field in cpuInfo with a value that must be a regular expression").String()
52 bugsInclude = kingpin.Flag("collector.cpu.info.bugs-include", "Filter the `bugs` field in cpuInfo with a value that must be a regular expression").String()
45) 53)
46 54
47func init() { 55func init() {
@@ -54,7 +62,7 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
54 if err != nil { 62 if err != nil {
55 return nil, fmt.Errorf("failed to open procfs: %w", err) 63 return nil, fmt.Errorf("failed to open procfs: %w", err)
56 } 64 }
57 return &cpuCollector{ 65 c := &cpuCollector{
58 fs: fs, 66 fs: fs,
59 cpu: nodeCPUSecondsDesc, 67 cpu: nodeCPUSecondsDesc,
60 cpuInfo: prometheus.NewDesc( 68 cpuInfo: prometheus.NewDesc(
@@ -62,6 +70,16 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
62 "CPU information from /proc/cpuinfo.", 70 "CPU information from /proc/cpuinfo.",
63 []string{"package", "core", "cpu", "vendor", "family", "model", "model_name", "microcode", "stepping", "cachesize"}, nil, 71 []string{"package", "core", "cpu", "vendor", "family", "model", "model_name", "microcode", "stepping", "cachesize"}, nil,
64 ), 72 ),
73 cpuFlagsInfo: prometheus.NewDesc(
74 prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "flag_info"),
75 "The `flags` field of CPU information from /proc/cpuinfo.",
76 []string{"flag"}, nil,
77 ),
78 cpuBugsInfo: prometheus.NewDesc(
79 prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "bug_info"),
80 "The `bugs` field of CPU information from /proc/cpuinfo.",
81 []string{"bug"}, nil,
82 ),
65 cpuGuest: prometheus.NewDesc( 83 cpuGuest: prometheus.NewDesc(
66 prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "guest_seconds_total"), 84 prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "guest_seconds_total"),
67 "Seconds the cpus spent in guests (VMs) for each mode.", 85 "Seconds the cpus spent in guests (VMs) for each mode.",
@@ -78,7 +96,34 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
78 []string{"package"}, nil, 96 []string{"package"}, nil,
79 ), 97 ),
80 logger: logger, 98 logger: logger,
81 }, nil 99 }
100 err = c.compileIncludeFlags(flagsInclude, bugsInclude)
101 if err != nil {
102 return nil, fmt.Errorf("fail to compile --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include, the values of them must be regular expressions: %w", err)
103 }
104 return c, nil
105}
106
107func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *string) error {
108 if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*enableCPUInfo {
109 *enableCPUInfo = true
110 level.Info(c.logger).Log("msg", "--collector.cpu.info has been set to `true` because you set the following flags, like --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include")
111 }
112
113 var err error
114 if *flagsIncludeFlag != "" {
115 c.cpuFlagsIncludeRegexp, err = regexp.Compile(*flagsIncludeFlag)
116 if err != nil {
117 return err
118 }
119 }
120 if *bugsIncludeFlag != "" {
121 c.cpuBugsIncludeRegexp, err = regexp.Compile(*bugsIncludeFlag)
122 if err != nil {
123 return err
124 }
125 }
126 return nil
82} 127}
83 128
84// Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/. 129// Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/.
@@ -117,6 +162,31 @@ func (c *cpuCollector) updateInfo(ch chan<- prometheus.Metric) error {
117 cpu.Microcode, 162 cpu.Microcode,
118 cpu.Stepping, 163 cpu.Stepping,
119 cpu.CacheSize) 164 cpu.CacheSize)
165
166 if err := updateFieldInfo(cpu.Flags, c.cpuFlagsIncludeRegexp, c.cpuFlagsInfo, ch); err != nil {
167 return err
168 }
169 if err := updateFieldInfo(cpu.Bugs, c.cpuBugsIncludeRegexp, c.cpuBugsInfo, ch); err != nil {
170 return err
171 }
172 }
173 return nil
174}
175
176func updateFieldInfo(valueList []string, filter *regexp.Regexp, desc *prometheus.Desc, ch chan<- prometheus.Metric) error {
177 if filter == nil {
178 return nil
179 }
180
181 for _, val := range valueList {
182 if !filter.MatchString(val) {
183 continue
184 }
185 ch <- prometheus.MustNewConstMetric(desc,
186 prometheus.GaugeValue,
187 1,
188 val,
189 )
120 } 190 }
121 return nil 191 return nil
122} 192}