Skip to content

Commit

Permalink
cpu: implement int32 counter for PDH calls as well.
Browse files Browse the repository at this point in the history
Signed-off-by: Jan-Otto Kröpke <[email protected]>
  • Loading branch information
jkroepke committed Nov 3, 2024
1 parent 45d3eab commit 0cffc69
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 49 deletions.
89 changes: 40 additions & 49 deletions internal/collector/cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type Collector struct {

perfDataCollector perfdata.Collector

processorRTCValues map[string]cpuCounter
processorMPerfValues map[string]cpuCounter
processorRTCValues map[string]utils.Counter
processorMPerfValues map[string]utils.Counter

logicalProcessors *prometheus.Desc
cStateSecondsTotal *prometheus.Desc
Expand All @@ -46,11 +46,6 @@ type Collector struct {
processorPrivilegedUtility *prometheus.Desc
}

type cpuCounter struct {
lastValue uint32
totalValue float64
}

func New(config *Config) *Collector {
if config == nil {
config = &ConfigDefaults
Expand Down Expand Up @@ -229,8 +224,8 @@ func (c *Collector) Build(_ *slog.Logger, _ *wmi.Client) error {
nil,
)

c.processorRTCValues = map[string]cpuCounter{}
c.processorMPerfValues = map[string]cpuCounter{}
c.processorRTCValues = map[string]utils.Counter{}
c.processorMPerfValues = map[string]utils.Counter{}

return nil
}
Expand Down Expand Up @@ -262,30 +257,28 @@ func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, c

core := cpu.Name

if val, ok := c.processorRTCValues[core]; ok {
c.processorRTCValues[core] = cpuCounter{
uint32(cpu.ProcessorRTC),
val.totalValue + float64(uint32(cpu.ProcessorRTC)-val.lastValue),
}
var (
counterProcessorRTCValues utils.Counter
counterProcessorMPerfValues utils.Counter
ok bool
)

if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
counterProcessorRTCValues.AddValue(uint32(cpu.ProcessorRTC))
} else {
c.processorRTCValues[core] = cpuCounter{
uint32(cpu.ProcessorRTC),
0,
}
counterProcessorRTCValues = utils.NewCounter(uint32(cpu.ProcessorRTC))
}

if val, ok := c.processorMPerfValues[core]; ok {
c.processorMPerfValues[core] = cpuCounter{
uint32(cpu.ProcessorMPerf),
val.totalValue + float64(uint32(cpu.ProcessorMPerf)-val.lastValue),
}
c.processorRTCValues[core] = counterProcessorRTCValues

if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
counterProcessorMPerfValues.AddValue(uint32(cpu.ProcessorMPerf))
} else {
c.processorMPerfValues[core] = cpuCounter{
uint32(cpu.ProcessorMPerf),
0,
}
counterProcessorMPerfValues = utils.NewCounter(uint32(cpu.ProcessorMPerf))
}

c.processorMPerfValues[core] = counterProcessorMPerfValues

coreCount++

ch <- prometheus.MustNewConstMetric(
Expand Down Expand Up @@ -385,13 +378,13 @@ func (c *Collector) collectFull(ctx *types.ScrapeContext, logger *slog.Logger, c
ch <- prometheus.MustNewConstMetric(
c.processorMPerf,
prometheus.CounterValue,
c.processorMPerfValues[core].totalValue,
counterProcessorMPerfValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorRTC,
prometheus.CounterValue,
c.processorRTCValues[core].totalValue,
counterProcessorRTCValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
Expand Down Expand Up @@ -428,30 +421,28 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
for core, coreData := range data {
coreCount++

if val, ok := c.processorRTCValues[core]; ok {
c.processorRTCValues[core] = cpuCounter{
uint32(coreData[privilegedUtilitySeconds].SecondValue),
val.totalValue + float64(uint32(coreData[privilegedUtilitySeconds].SecondValue)-val.lastValue),
}
var (
counterProcessorRTCValues utils.Counter
counterProcessorMPerfValues utils.Counter
ok bool
)

if counterProcessorRTCValues, ok = c.processorRTCValues[core]; ok {
counterProcessorRTCValues.AddValue(uint32(coreData[processorUtilityRate].SecondValue))
} else {
c.processorRTCValues[core] = cpuCounter{
uint32(coreData[privilegedUtilitySeconds].SecondValue),
0,
}
counterProcessorRTCValues = utils.NewCounter(uint32(coreData[privilegedUtilitySeconds].SecondValue))
}

if val, ok := c.processorMPerfValues[core]; ok {
c.processorMPerfValues[core] = cpuCounter{
uint32(coreData[processorPerformance].SecondValue),
val.totalValue + float64(uint32(coreData[processorPerformance].SecondValue)-val.lastValue),
}
c.processorRTCValues[core] = counterProcessorRTCValues

if counterProcessorMPerfValues, ok = c.processorMPerfValues[core]; ok {
counterProcessorMPerfValues.AddValue(uint32(coreData[processorPerformance].SecondValue))
} else {
c.processorMPerfValues[core] = cpuCounter{
uint32(coreData[processorPerformance].SecondValue),
0,
}
counterProcessorMPerfValues = utils.NewCounter(uint32(coreData[processorPerformance].SecondValue))
}

c.processorMPerfValues[core] = counterProcessorMPerfValues

ch <- prometheus.MustNewConstMetric(
c.cStateSecondsTotal,
prometheus.CounterValue,
Expand Down Expand Up @@ -549,13 +540,13 @@ func (c *Collector) collectPDH(ch chan<- prometheus.Metric) error {
ch <- prometheus.MustNewConstMetric(
c.processorMPerf,
prometheus.CounterValue,
coreData[processorPerformance].SecondValue,
counterProcessorMPerfValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
c.processorRTC,
prometheus.CounterValue,
coreData[processorUtilityRate].SecondValue,
counterProcessorRTCValues.Value(),
core,
)
ch <- prometheus.MustNewConstMetric(
Expand Down
23 changes: 23 additions & 0 deletions internal/utils/counter.go
Original file line number Diff line number Diff line change
@@ -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
}
24 changes: 24 additions & 0 deletions internal/utils/counter_test.go
Original file line number Diff line number Diff line change
@@ -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())

Check failure on line 15 in internal/utils/counter_test.go

View workflow job for this annotation

GitHub Actions / lint

float-compare: use assert.InEpsilon (or InDelta) (testifylint)

c.AddValue(1)

assert.Equal(t, 1.0, c.Value())

Check failure on line 19 in internal/utils/counter_test.go

View workflow job for this annotation

GitHub Actions / lint

float-compare: use assert.InEpsilon (or InDelta) (testifylint)

c.AddValue(math.MaxUint32)

assert.Equal(t, float64(math.MaxUint32)+1.0, c.Value())

Check failure on line 23 in internal/utils/counter_test.go

View workflow job for this annotation

GitHub Actions / lint

float-compare: use assert.InEpsilon (or InDelta) (testifylint)
}

0 comments on commit 0cffc69

Please sign in to comment.