@ -18,6 +18,7 @@ package collector
import (
"fmt"
"path/filepath"
"regexp"
"strconv"
"sync"
@ -32,16 +33,23 @@ type cpuCollector struct {
fs procfs . FS
cpu * prometheus . Desc
cpuInfo * prometheus . Desc
cpuFlagsInfo * prometheus . Desc
cpuBugsInfo * prometheus . Desc
cpuGuest * prometheus . Desc
cpuCoreThrottle * prometheus . Desc
cpuPackageThrottle * prometheus . Desc
logger log . Logger
cpuStats [ ] procfs . CPUStat
cpuStatsMutex sync . Mutex
cpuFlagsIncludeRegexp * regexp . Regexp
cpuBugsIncludeRegexp * regexp . Regexp
}
var (
enableCPUInfo = kingpin . Flag ( "collector.cpu.info" , "Enables metric cpu_info" ) . Bool ( )
flagsInclude = kingpin . Flag ( "collector.cpu.info.flags-include" , "Filter the `flags` field in cpuInfo with a value that must be a regular expression" ) . String ( )
bugsInclude = kingpin . Flag ( "collector.cpu.info.bugs-include" , "Filter the `bugs` field in cpuInfo with a value that must be a regular expression" ) . String ( )
)
func init ( ) {
@ -54,7 +62,7 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
if err != nil {
return nil , fmt . Errorf ( "failed to open procfs: %w" , err )
}
return & cpuCollector {
c := & cpuCollector {
fs : fs ,
cpu : nodeCPUSecondsDesc ,
cpuInfo : prometheus . NewDesc (
@ -62,6 +70,16 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
"CPU information from /proc/cpuinfo." ,
[ ] string { "package" , "core" , "cpu" , "vendor" , "family" , "model" , "model_name" , "microcode" , "stepping" , "cachesize" } , nil ,
) ,
cpuFlagsInfo : prometheus . NewDesc (
prometheus . BuildFQName ( namespace , cpuCollectorSubsystem , "flag_info" ) ,
"The `flags` field of CPU information from /proc/cpuinfo." ,
[ ] string { "flag" } , nil ,
) ,
cpuBugsInfo : prometheus . NewDesc (
prometheus . BuildFQName ( namespace , cpuCollectorSubsystem , "bug_info" ) ,
"The `bugs` field of CPU information from /proc/cpuinfo." ,
[ ] string { "bug" } , nil ,
) ,
cpuGuest : prometheus . NewDesc (
prometheus . BuildFQName ( namespace , cpuCollectorSubsystem , "guest_seconds_total" ) ,
"Seconds the cpus spent in guests (VMs) for each mode." ,
@ -78,7 +96,34 @@ func NewCPUCollector(logger log.Logger) (Collector, error) {
[ ] string { "package" } , nil ,
) ,
logger : logger ,
} , nil
}
err = c . compileIncludeFlags ( flagsInclude , bugsInclude )
if err != nil {
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 )
}
return c , nil
}
func ( c * cpuCollector ) compileIncludeFlags ( flagsIncludeFlag , bugsIncludeFlag * string ) error {
if ( * flagsIncludeFlag != "" || * bugsIncludeFlag != "" ) && ! * enableCPUInfo {
* enableCPUInfo = true
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" )
}
var err error
if * flagsIncludeFlag != "" {
c . cpuFlagsIncludeRegexp , err = regexp . Compile ( * flagsIncludeFlag )
if err != nil {
return err
}
}
if * bugsIncludeFlag != "" {
c . cpuBugsIncludeRegexp , err = regexp . Compile ( * bugsIncludeFlag )
if err != nil {
return err
}
}
return nil
}
// 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 {
cpu . Microcode ,
cpu . Stepping ,
cpu . CacheSize )
if err := updateFieldInfo ( cpu . Flags , c . cpuFlagsIncludeRegexp , c . cpuFlagsInfo , ch ) ; err != nil {
return err
}
if err := updateFieldInfo ( cpu . Bugs , c . cpuBugsIncludeRegexp , c . cpuBugsInfo , ch ) ; err != nil {
return err
}
}
return nil
}
func updateFieldInfo ( valueList [ ] string , filter * regexp . Regexp , desc * prometheus . Desc , ch chan <- prometheus . Metric ) error {
if filter == nil {
return nil
}
for _ , val := range valueList {
if ! filter . MatchString ( val ) {
continue
}
ch <- prometheus . MustNewConstMetric ( desc ,
prometheus . GaugeValue ,
1 ,
val ,
)
}
return nil
}