cpu: implement int32 counter for PDH calls as well. (#1715)

This commit is contained in:
Jan-Otto Kröpke
2024-11-03 19:24:36 +01:00
committed by GitHub
parent bf233ad3e3
commit be67d853aa
4 changed files with 88 additions and 51 deletions

View File

@@ -27,8 +27,8 @@ type Collector struct {
perfDataCollector perfdata.Collector perfDataCollector perfdata.Collector
processorRTCValues map[string]cpuCounter processorRTCValues map[string]utils.Counter
processorMPerfValues map[string]cpuCounter processorMPerfValues map[string]utils.Counter
logicalProcessors *prometheus.Desc logicalProcessors *prometheus.Desc
cStateSecondsTotal *prometheus.Desc cStateSecondsTotal *prometheus.Desc
@@ -46,11 +46,6 @@ type Collector struct {
processorPrivilegedUtility *prometheus.Desc processorPrivilegedUtility *prometheus.Desc
} }
type cpuCounter struct {
lastValue uint32
totalValue float64
}
func New(config *Config) *Collector { func New(config *Config) *Collector {
if config == nil { if config == nil {
config = &ConfigDefaults config = &ConfigDefaults
@@ -229,8 +224,8 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
nil, nil,
) )
c.processorRTCValues = map[string]cpuCounter{} c.processorRTCValues = map[string]utils.Counter{}
c.processorMPerfValues = map[string]cpuCounter{} c.processorMPerfValues = map[string]utils.Counter{}
return nil return nil
} }
@@ -262,30 +257,28 @@ func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, c
core := cpu.Name core := cpu.Name
if val, ok := c.processorRTCValues[core]; ok { var (
c.processorRTCValues[core] = cpuCounter{ counterProcessorRTCValues utils.Counter
uint32(cpu.ProcessorRTC), counterProcessorMPerfValues utils.Counter
val.totalValue + float64(uint32(cpu.ProcessorRTC)-val.lastValue), ok bool
} )
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
counterProcessorRTCValues.AddValue(uint32(cpu.ProcessorRTC))
} else { } else {
c.processorRTCValues[core] = cpuCounter{ counterProcessorRTCValues = utils.NewCounter(uint32(cpu.ProcessorRTC))
uint32(cpu.ProcessorRTC),
0,
}
} }
if val, ok := c.processorMPerfValues[core]; ok { c.processorRTCValues[core] = counterProcessorRTCValues
c.processorMPerfValues[core] = cpuCounter{
uint32(cpu.ProcessorMPerf), if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
val.totalValue + float64(uint32(cpu.ProcessorMPerf)-val.lastValue), counterProcessorMPerfValues.AddValue(uint32(cpu.ProcessorMPerf))
}
} else { } else {
c.processorMPerfValues[core] = cpuCounter{ counterProcessorMPerfValues = utils.NewCounter(uint32(cpu.ProcessorMPerf))
uint32(cpu.ProcessorMPerf),
0,
}
} }
c.processorMPerfValues[core] = counterProcessorMPerfValues
coreCount++ coreCount++
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
@@ -385,13 +378,13 @@ func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, c
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.processorMPerf, c.processorMPerf,
prometheus.CounterValue, prometheus.CounterValue,
c.processorMPerfValues[core].totalValue, counterProcessorMPerfValues.Value(),
core, core,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.processorRTC, c.processorRTC,
prometheus.CounterValue, prometheus.CounterValue,
c.processorRTCValues[core].totalValue, counterProcessorRTCValues.Value(),
core, core,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
@@ -428,30 +421,28 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
for core, coreData := range data { for core, coreData := range data {
coreCount++ coreCount++
if val, ok := c.processorRTCValues[core]; ok { var (
c.processorRTCValues[core] = cpuCounter{ counterProcessorRTCValues utils.Counter
uint32(coreData[privilegedUtilitySeconds].SecondValue), counterProcessorMPerfValues utils.Counter
val.totalValue + float64(uint32(coreData[privilegedUtilitySeconds].SecondValue)-val.lastValue), ok bool
} )
if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
counterProcessorRTCValues.AddValue(uint32(coreData[processorUtilityRate].SecondValue))
} else { } else {
c.processorRTCValues[core] = cpuCounter{ counterProcessorRTCValues = utils.NewCounter(uint32(coreData[privilegedUtilitySeconds].SecondValue))
uint32(coreData[privilegedUtilitySeconds].SecondValue),
0,
}
} }
if val, ok := c.processorMPerfValues[core]; ok { c.processorRTCValues[core] = counterProcessorRTCValues
c.processorMPerfValues[core] = cpuCounter{
uint32(coreData[processorPerformance].SecondValue), if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
val.totalValue + float64(uint32(coreData[processorPerformance].SecondValue)-val.lastValue), counterProcessorMPerfValues.AddValue(uint32(coreData[processorPerformance].SecondValue))
}
} else { } else {
c.processorMPerfValues[core] = cpuCounter{ counterProcessorMPerfValues = utils.NewCounter(uint32(coreData[processorPerformance].SecondValue))
uint32(coreData[processorPerformance].SecondValue),
0,
}
} }
c.processorMPerfValues[core] = counterProcessorMPerfValues
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.cStateSecondsTotal, c.cStateSecondsTotal,
prometheus.CounterValue, prometheus.CounterValue,
@@ -549,13 +540,13 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.processorMPerf, c.processorMPerf,
prometheus.CounterValue, prometheus.CounterValue,
coreData[processorPerformance].SecondValue, counterProcessorMPerfValues.Value(),
core, core,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.processorRTC, c.processorRTC,
prometheus.CounterValue, prometheus.CounterValue,
coreData[processorUtilityRate].SecondValue, counterProcessorRTCValues.Value(),
core, core,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(

View File

@@ -27,8 +27,7 @@ var (
AllInstances = []string{"*"} AllInstances = []string{"*"}
) )
//nolint:ireturn func NewCollector(engine Engine, object string, instances []string, counters []string) (Collector, error) { //nolint:ireturn
func NewCollector(engine Engine, object string, instances []string, counters []string) (Collector, error) {
switch engine { switch engine {
case V1: case V1:
return v1.NewCollector(object, instances, counters) return v1.NewCollector(object, instances, counters)

23
internal/utils/counter.go Normal file
View File

@@ -0,0 +1,23 @@
package utils
type Counter struct {
lastValue uint32
totalValue float64
}
// NewCounter creates a new Counter that accepts uint32 values and returns float64 values.
// It resolve the overflow issue of uint32 by using the difference between the last value and the current value.
func NewCounter(lastValue uint32) Counter {
return Counter{
lastValue: lastValue,
totalValue: 0,
}
}
func (c *Counter) AddValue(value uint32) {
c.totalValue += float64(value - c.lastValue)
}
func (c *Counter) Value() float64 {
return c.totalValue
}

View File

@@ -0,0 +1,24 @@
package utils_test
import (
"math"
"testing"
"github.com/prometheus-community/windows_exporter/internal/utils"
"github.com/stretchr/testify/assert"
)
func TestCounter(t *testing.T) {
t.Parallel()
c := utils.NewCounter(0)
assert.Equal(t, 0.0, c.Value()) //nolint:testifylint
c.AddValue(1)
assert.Equal(t, 1.0, c.Value()) //nolint:testifylint
c.AddValue(math.MaxUint32)
assert.Equal(t, float64(math.MaxUint32)+1.0, c.Value()) //nolint:testifylint
}