2018-11-30 00:51:12 +00:00
// +build windows
2016-09-17 15:11:35 +00:00
package collector
import (
"strings"
"github.com/prometheus/client_golang/prometheus"
)
func init ( ) {
2020-02-09 20:09:26 +00:00
var deps string
// See below for 6.05 magic value
if getWindowsVersion ( ) > 6.05 {
deps = "Processor Information"
} else {
deps = "Processor"
}
registerCollector ( "cpu" , newCPUCollector , deps )
2016-09-17 15:11:35 +00:00
}
2019-04-05 13:59:40 +00:00
type cpuCollectorBasic struct {
2016-09-17 15:11:35 +00:00
CStateSecondsTotal * prometheus . Desc
TimeTotal * prometheus . Desc
InterruptsTotal * prometheus . Desc
DPCsTotal * prometheus . Desc
2019-04-05 13:59:40 +00:00
}
type cpuCollectorFull struct {
CStateSecondsTotal * prometheus . Desc
TimeTotal * prometheus . Desc
InterruptsTotal * prometheus . Desc
DPCsTotal * prometheus . Desc
ClockInterruptsTotal * prometheus . Desc
IdleBreakEventsTotal * prometheus . Desc
ParkingStatus * prometheus . Desc
ProcessorFrequencyMHz * prometheus . Desc
ProcessorMaxFrequencyMHz * prometheus . Desc
ProcessorPerformance * prometheus . Desc
2016-09-17 15:11:35 +00:00
}
2019-04-05 13:59:40 +00:00
// newCPUCollector constructs a new cpuCollector, appropriate for the running OS
func newCPUCollector ( ) ( Collector , error ) {
2016-09-17 15:11:35 +00:00
const subsystem = "cpu"
2019-04-05 13:59:40 +00:00
version := getWindowsVersion ( )
2019-08-03 11:15:45 +00:00
// For Windows 2008 (version 6.0) or earlier we only have the "Processor"
// class. As of Windows 2008 R2 (version 6.1) the more detailed
2020-02-09 20:09:26 +00:00
// "Processor Information" set is available (although some of the counters
2019-08-03 11:15:45 +00:00
// are added in later versions, so we aren't guaranteed to get all of
// them).
// Value 6.05 was selected to split between Windows versions.
2019-04-05 13:59:40 +00:00
if version < 6.05 {
return & cpuCollectorBasic {
CStateSecondsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "cstate_seconds_total" ) ,
"Time spent in low-power idle state" ,
[ ] string { "core" , "state" } ,
nil ,
) ,
TimeTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "time_total" ) ,
"Time that processor spent in different modes (idle, user, system, ...)" ,
[ ] string { "core" , "mode" } ,
nil ,
) ,
InterruptsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "interrupts_total" ) ,
"Total number of received and serviced hardware interrupts" ,
[ ] string { "core" } ,
nil ,
) ,
DPCsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "dpcs_total" ) ,
"Total number of received and serviced deferred procedure calls (DPCs)" ,
[ ] string { "core" } ,
nil ,
) ,
} , nil
}
return & cpuCollectorFull {
2016-09-17 15:11:35 +00:00
CStateSecondsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "cstate_seconds_total" ) ,
"Time spent in low-power idle state" ,
[ ] string { "core" , "state" } ,
nil ,
) ,
TimeTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "time_total" ) ,
"Time that processor spent in different modes (idle, user, system, ...)" ,
[ ] string { "core" , "mode" } ,
nil ,
) ,
InterruptsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "interrupts_total" ) ,
"Total number of received and serviced hardware interrupts" ,
[ ] string { "core" } ,
nil ,
) ,
DPCsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "dpcs_total" ) ,
"Total number of received and serviced deferred procedure calls (DPCs)" ,
[ ] string { "core" } ,
nil ,
) ,
2019-04-05 13:59:40 +00:00
ClockInterruptsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "clock_interrupts_total" ) ,
"Total number of received and serviced clock tick interrupts" ,
[ ] string { "core" } ,
nil ,
) ,
IdleBreakEventsTotal : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "idle_break_events_total" ) ,
"Total number of time processor was woken from idle" ,
[ ] string { "core" } ,
nil ,
) ,
ParkingStatus : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "parking_status" ) ,
"Parking Status represents whether a processor is parked or not" ,
[ ] string { "core" } ,
nil ,
) ,
ProcessorFrequencyMHz : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "core_frequency_mhz" ) ,
2019-05-03 18:34:34 +00:00
"Core frequency in megahertz" ,
[ ] string { "core" } ,
nil ,
) ,
2019-04-05 13:59:40 +00:00
ProcessorPerformance : prometheus . NewDesc (
prometheus . BuildFQName ( Namespace , subsystem , "processor_performance" ) ,
"Processor Performance is the average performance of the processor while it is executing instructions, as a percentage of the nominal performance of the processor. On some processors, Processor Performance may exceed 100%" ,
[ ] string { "core" } ,
nil ,
) ,
2016-09-17 15:11:35 +00:00
} , nil
}
2019-04-05 13:59:40 +00:00
type perflibProcessor struct {
2016-09-17 15:11:35 +00:00
Name string
2019-04-05 13:59:40 +00:00
C1Transitions float64 ` perflib:"C1 Transitions/sec" `
C2Transitions float64 ` perflib:"C2 Transitions/sec" `
C3Transitions float64 ` perflib:"C3 Transitions/sec" `
DPCRate float64 ` perflib:"DPC Rate" `
DPCsQueued float64 ` perflib:"DPCs Queued/sec" `
Interrupts float64 ` perflib:"Interrupts/sec" `
PercentC2Time float64 ` perflib:"% C1 Time" `
PercentC3Time float64 ` perflib:"% C2 Time" `
PercentC1Time float64 ` perflib:"% C3 Time" `
PercentDPCTime float64 ` perflib:"% DPC Time" `
PercentIdleTime float64 ` perflib:"% Idle Time" `
PercentInterruptTime float64 ` perflib:"% Interrupt Time" `
PercentPrivilegedTime float64 ` perflib:"% Privileged Time" `
PercentProcessorTime float64 ` perflib:"% Processor Time" `
PercentUserTime float64 ` perflib:"% User Time" `
2016-09-17 15:11:35 +00:00
}
2019-04-05 13:59:40 +00:00
func ( c * cpuCollectorBasic ) Collect ( ctx * ScrapeContext , ch chan <- prometheus . Metric ) error {
data := make ( [ ] perflibProcessor , 0 )
err := unmarshalObject ( ctx . perfObjects [ "Processor" ] , & data )
if err != nil {
return err
}
2016-09-17 15:11:35 +00:00
2019-04-05 13:59:40 +00:00
for _ , cpu := range data {
if strings . Contains ( strings . ToLower ( cpu . Name ) , "_total" ) {
continue
2019-05-03 18:34:34 +00:00
}
2019-04-05 13:59:40 +00:00
core := cpu . Name
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
prometheus . CounterValue ,
cpu . PercentC1Time ,
core , "c1" ,
)
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
prometheus . CounterValue ,
cpu . PercentC2Time ,
core , "c2" ,
)
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
prometheus . CounterValue ,
cpu . PercentC3Time ,
core , "c3" ,
)
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
prometheus . CounterValue ,
cpu . PercentIdleTime ,
core , "idle" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
prometheus . CounterValue ,
cpu . PercentInterruptTime ,
core , "interrupt" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
prometheus . CounterValue ,
cpu . PercentDPCTime ,
core , "dpc" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
prometheus . CounterValue ,
cpu . PercentPrivilegedTime ,
core , "privileged" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
prometheus . CounterValue ,
cpu . PercentUserTime ,
core , "user" ,
)
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
ch <- prometheus . MustNewConstMetric (
c . InterruptsTotal ,
prometheus . CounterValue ,
cpu . Interrupts ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . DPCsTotal ,
prometheus . CounterValue ,
cpu . DPCsQueued ,
core ,
)
}
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
return nil
}
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
type perflibProcessorInformation struct {
Name string
C1TimeSeconds float64 ` perflib:"% C1 Time" `
C2TimeSeconds float64 ` perflib:"% C2 Time" `
C3TimeSeconds float64 ` perflib:"% C3 Time" `
C1TransitionsTotal float64 ` perflib:"C1 Transitions/sec" `
C2TransitionsTotal float64 ` perflib:"C2 Transitions/sec" `
C3TransitionsTotal float64 ` perflib:"C3 Transitions/sec" `
ClockInterruptsTotal float64 ` perflib:"Clock Interrupts/sec" `
DPCsQueuedTotal float64 ` perflib:"DPCs Queued/sec" `
DPCTimeSeconds float64 ` perflib:"% DPC Time" `
IdleBreakEventsTotal float64 ` perflib:"Idle Break Events/sec" `
IdleTimeSeconds float64 ` perflib:"% Idle Time" `
InterruptsTotal float64 ` perflib:"Interrupts/sec" `
InterruptTimeSeconds float64 ` perflib:"% Interrupt Time" `
ParkingStatus float64 ` perflib:"Parking Status" `
PerformanceLimitPercent float64 ` perflib:"% Performance Limit" `
PriorityTimeSeconds float64 ` perflib:"% Priority Time" `
PrivilegedTimeSeconds float64 ` perflib:"% Privileged Time" `
PrivilegedUtilitySeconds float64 ` perflib:"% Privileged Utility" `
ProcessorFrequencyMHz float64 ` perflib:"Processor Frequency" `
ProcessorPerformance float64 ` perflib:"% Processor Performance" `
ProcessorTimeSeconds float64 ` perflib:"% Processor Time" `
ProcessorUtilityRate float64 ` perflib:"% Processor Utility" `
UserTimeSeconds float64 ` perflib:"% User Time" `
}
2019-05-03 18:34:34 +00:00
2019-04-05 13:59:40 +00:00
func ( c * cpuCollectorFull ) Collect ( ctx * ScrapeContext , ch chan <- prometheus . Metric ) error {
data := make ( [ ] perflibProcessorInformation , 0 )
err := unmarshalObject ( ctx . perfObjects [ "Processor Information" ] , & data )
if err != nil {
return err
2019-05-03 18:34:34 +00:00
}
2019-04-05 13:59:40 +00:00
for _ , cpu := range data {
if strings . Contains ( strings . ToLower ( cpu . Name ) , "_total" ) {
2016-09-17 15:11:35 +00:00
continue
}
2019-04-05 13:59:40 +00:00
core := cpu . Name
2016-09-17 15:11:35 +00:00
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . C1TimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "c1" ,
)
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . C2TimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "c2" ,
)
ch <- prometheus . MustNewConstMetric (
c . CStateSecondsTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . C3TimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "c3" ,
)
2019-04-05 13:59:40 +00:00
2016-09-17 15:11:35 +00:00
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . IdleTimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "idle" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . InterruptTimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "interrupt" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . DPCTimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "dpc" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . PrivilegedTimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "privileged" ,
)
ch <- prometheus . MustNewConstMetric (
c . TimeTotal ,
2019-04-11 17:38:34 +00:00
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . UserTimeSeconds ,
2016-09-17 15:11:35 +00:00
core , "user" ,
)
2019-04-05 13:59:40 +00:00
2016-09-17 15:11:35 +00:00
ch <- prometheus . MustNewConstMetric (
c . InterruptsTotal ,
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . InterruptsTotal ,
2016-09-17 15:11:35 +00:00
core ,
)
ch <- prometheus . MustNewConstMetric (
c . DPCsTotal ,
prometheus . CounterValue ,
2019-04-05 13:59:40 +00:00
cpu . DPCsQueuedTotal ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . ClockInterruptsTotal ,
prometheus . CounterValue ,
cpu . ClockInterruptsTotal ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . IdleBreakEventsTotal ,
prometheus . CounterValue ,
cpu . IdleBreakEventsTotal ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . ParkingStatus ,
prometheus . GaugeValue ,
cpu . ParkingStatus ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . ProcessorFrequencyMHz ,
prometheus . GaugeValue ,
cpu . ProcessorFrequencyMHz ,
core ,
)
ch <- prometheus . MustNewConstMetric (
c . ProcessorPerformance ,
prometheus . GaugeValue ,
cpu . ProcessorPerformance ,
2016-09-17 15:11:35 +00:00
core ,
)
}
2019-04-05 13:59:40 +00:00
return nil
2016-09-17 15:11:35 +00:00
}