Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8fc2d67
[receiver/hostmetrics] Add cputicks reader behind feature gate
salvatore-campagna Apr 23, 2026
2683a31
fix: correct changelog component name to receiver/host_metrics
salvatore-campagna Apr 28, 2026
5e36aca
fix: set rootPath on expected CPU config in TestLoadConfigRootPath
salvatore-campagna Apr 28, 2026
eb795a0
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Apr 28, 2026
f602a7c
fix: run gotidy and fix gci lint error
salvatore-campagna Apr 28, 2026
ac622ab
fix: run gogci to fix import formatting
salvatore-campagna Apr 28, 2026
cdf66ab
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Apr 28, 2026
8c90045
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Apr 28, 2026
a91936e
fix: restore percpu comment in newGopsutilEmitter
salvatore-campagna Apr 29, 2026
2eea837
fix: add USER_HZ comment on defaultTicksPerSecond
salvatore-campagna Apr 29, 2026
1e16338
fix: remove unused context parameter from ReadAll
salvatore-campagna Apr 29, 2026
45f5575
fix: use golden file and pmetrictest in TestCputicksEmitter_Utilization
salvatore-campagna Apr 29, 2026
0b19ebd
fix: exclude Guest and GuestNice from Stat.Total()
salvatore-campagna Apr 29, 2026
ff16d7c
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Apr 29, 2026
bca6855
fix: define UseCPUTicks feature gate in metadata.yaml
salvatore-campagna Apr 30, 2026
136b97e
fix: rename unused ctx parameter to _ in cputicks emitter
salvatore-campagna Apr 30, 2026
6f4f1db
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Apr 30, 2026
e43df82
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna May 6, 2026
487196a
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna May 11, 2026
5219359
Merge upstream/main into fix/hostmetrics-cputicks-package
salvatore-campagna Jun 22, 2026
94e4c61
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Jun 22, 2026
da1aaae
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Jul 2, 2026
cc2b9cf
Merge branch 'main' into fix/hostmetrics-cputicks-package
salvatore-campagna Jul 9, 2026
f2f0d41
run go mod tidy after upstream merge to fix go.sum
salvatore-campagna Jul 11, 2026
8a2f549
Merge upstream/main into fix/hostmetrics-cputicks-package
salvatore-campagna Jul 11, 2026
777d21b
[receiver/hostmetrics] fix feature gate ID validation for UseCPUTicks
salvatore-campagna Jul 11, 2026
a0e0620
[receiver/hostmetrics] fix cputicks tests after cpu attribute opt-in …
salvatore-campagna Jul 11, 2026
11b6da4
[receiver/hostmetrics] fix import ordering in mdatagen-generated files
salvatore-campagna Jul 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .chloggen/fix_hostmetrics-cpu-ticks-package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
component: receiver/host_metrics

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add cputicks package and integrate with CPU scraper behind feature gate

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [46177]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
New internal package that reads raw uint64 CPU ticks directly from /proc/stat
on Linux, avoiding the precision loss from gopsutil's float64 seconds conversion.
Enabled via the receiver.hostmetricsreceiver.UseCPUTicks feature gate (alpha).

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
4 changes: 2 additions & 2 deletions receiver/hostmetricsreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ require (
github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.151.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/gopsutilenv v0.151.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.151.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.151.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.151.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters v0.151.0
github.com/prometheus/procfs v0.20.1
github.com/shirou/gopsutil/v4 v4.26.3
github.com/stretchr/testify v1.11.1
github.com/tilinna/clock v1.1.0
github.com/tklauser/go-sysconf v0.3.16
go.opentelemetry.io/collector/component v1.57.0
go.opentelemetry.io/collector/component/componenttest v0.151.0
go.opentelemetry.io/collector/confmap v1.57.0
Expand Down Expand Up @@ -82,7 +84,6 @@ require (
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.151.0 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
Expand All @@ -91,7 +92,6 @@ require (
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/testcontainers/testcontainers-go v0.42.0 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
Expand Down
1 change: 1 addition & 0 deletions receiver/hostmetricsreceiver/hostmetrics_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestLoadConfigRootPath(t *testing.T) {
expectedConfig.RootPath = "testdata"
f := cpuscraper.NewFactory()
cpuScraperCfg := f.CreateDefaultConfig()
cpuScraperCfg.(*cpuscraper.Config).SetRootPath(expectedConfig.RootPath)
expectedConfig.Scrapers = map[component.Type]component.Config{f.Type(): cpuScraperCfg}
assert.Equal(t, expectedConfig, cfg)
expectedEnvMap := common.EnvMap{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ import (
// Config relating to CPU Metric Scraper.
type Config struct {
metadata.MetricsBuilderConfig `mapstructure:",squash"`
rootPath string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion as it seems the filesystem scraper has a similar approach to use the rootPath, but an alternative would be extracting it from the context: https://github.com/salvatore-campagna/opentelemetry-collector-contrib/blob/fix/hostmetrics-cputicks-package/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go#L132

Any preference @braydonk @dmitryax ?

}

func (cfg *Config) SetRootPath(rootPath string) {
cfg.rootPath = rootPath
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ type cpuScraper struct {
settings scraper.Settings
config *Config
mb *metadata.MetricsBuilder
ucal *ucal.CPUUtilizationCalculator

// for mocking
bootTime func(context.Context) (uint64, error)
times func(context.Context, bool) ([]cpu.TimesStat, error)
now func() time.Time
bootTime func(context.Context) (uint64, error)
emitCPUMetrics func(context.Context, pcommon.Timestamp, *metadata.MetricsBuilder) error
now func() time.Time
}

type cpuInfo struct {
Expand All @@ -45,7 +44,29 @@ type cpuInfo struct {

// newCPUScraper creates a set of CPU related metrics
func newCPUScraper(_ context.Context, settings scraper.Settings, cfg *Config) *cpuScraper {
return &cpuScraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, times: cpu.TimesWithContext, ucal: &ucal.CPUUtilizationCalculator{}, now: time.Now}
return &cpuScraper{
settings: settings,
config: cfg,
bootTime: host.BootTimeWithContext,
emitCPUMetrics: newCPUEmitter(cfg),
now: time.Now,
}
}

func newGopsutilEmitter(times func(context.Context, bool) ([]cpu.TimesStat, error)) func(context.Context, pcommon.Timestamp, *metadata.MetricsBuilder) error {
calc := &ucal.CPUUtilizationCalculator{}
return func(ctx context.Context, now pcommon.Timestamp, mb *metadata.MetricsBuilder) error {
cpuTimes, err := times(ctx, true /*percpu=*/)
if err != nil {
return err
}
for _, cpuTime := range cpuTimes {
recordCPUTimeStateDataPoints(now, cpuTime, mb)
}
return calc.CalculateAndRecord(now, cpuTimes, func(now pcommon.Timestamp, u ucal.CPUUtilization) {
recordCPUUtilization(now, u, mb)
})
}
}

func (s *cpuScraper) start(ctx context.Context, _ component.Host) error {
Expand All @@ -59,17 +80,8 @@ func (s *cpuScraper) start(ctx context.Context, _ component.Host) error {

func (s *cpuScraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
now := pcommon.NewTimestampFromTime(s.now())
cpuTimes, err := s.times(ctx, true /*percpu=*/)
if err != nil {
return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen)
}

for _, cpuTime := range cpuTimes {
s.recordCPUTimeStateDataPoints(now, cpuTime)
}

err = s.ucal.CalculateAndRecord(now, cpuTimes, s.recordCPUUtilization)
if err != nil {
if err := s.emitCPUMetrics(ctx, now, s.mb); err != nil {
return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,152 @@
package cpuscraper // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/cpuscraper"

import (
"context"
"fmt"
"time"

"github.com/prometheus/procfs"
"github.com/shirou/gopsutil/v4/cpu"
"github.com/tklauser/go-sysconf"
"go.opentelemetry.io/collector/featuregate"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/scraper/scrapererror"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/precision"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/cputicks"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/ucal"
)

func (s *cpuScraper) recordCPUTimeStateDataPoints(now pcommon.Timestamp, cpuTime cpu.TimesStat) {
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.User, cpuTime.CPU, metadata.AttributeStateUser)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.System, cpuTime.CPU, metadata.AttributeStateSystem)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Idle, cpuTime.CPU, metadata.AttributeStateIdle)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Irq, cpuTime.CPU, metadata.AttributeStateInterrupt)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Nice, cpuTime.CPU, metadata.AttributeStateNice)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Softirq, cpuTime.CPU, metadata.AttributeStateSoftirq)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Steal, cpuTime.CPU, metadata.AttributeStateSteal)
s.mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Iowait, cpuTime.CPU, metadata.AttributeStateWait)
}

func (s *cpuScraper) recordCPUUtilization(now pcommon.Timestamp, cpuUtilization ucal.CPUUtilization) {
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.User, cpuUtilization.CPU, metadata.AttributeStateUser)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.System, cpuUtilization.CPU, metadata.AttributeStateSystem)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Idle, cpuUtilization.CPU, metadata.AttributeStateIdle)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Irq, cpuUtilization.CPU, metadata.AttributeStateInterrupt)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Nice, cpuUtilization.CPU, metadata.AttributeStateNice)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Softirq, cpuUtilization.CPU, metadata.AttributeStateSoftirq)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Steal, cpuUtilization.CPU, metadata.AttributeStateSteal)
s.mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Iowait, cpuUtilization.CPU, metadata.AttributeStateWait)
var useCPUTicks = featuregate.GlobalRegistry().MustRegister(
Comment thread
salvatore-campagna marked this conversation as resolved.
Outdated
"receiver.hostmetricsreceiver.UseCPUTicks",
featuregate.StageAlpha,
featuregate.WithRegisterDescription("Use raw uint64 CPU tick counts from /proc/stat instead of gopsutil for improved precision in CPU time and utilization metrics."),
featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/46177"),
featuregate.WithRegisterFromVersion("v0.152.0"),
)

// USER_HZ: hardcoded at 100 in the Linux kernel since 2.6 for /proc/stat ABI stability.
const defaultTicksPerSecond = 100
Comment thread
salvatore-campagna marked this conversation as resolved.

// tickReader reads per-CPU tick counts from the operating system.
// Defined at the consumer for testability.
type tickReader interface {
ReadAll() ([]cputicks.Stat, error)
TicksPerSecond() uint64
}

func clockTicksPerSecond() uint64 {
clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK)
if err != nil || clkTck <= 0 {
return defaultTicksPerSecond
}
return uint64(clkTck)
}

func newCPUEmitter(cfg *Config) func(context.Context, pcommon.Timestamp, *metadata.MetricsBuilder) error {
if useCPUTicks.IsEnabled() {
return newCputicksEmitter(cputicks.NewReader(cfg.rootPath, clockTicksPerSecond()))
}
return newGopsutilEmitter(cpu.TimesWithContext)
}

func newCputicksEmitter(reader tickReader) func(context.Context, pcommon.Timestamp, *metadata.MetricsBuilder) error {
tickDuration := time.Second / time.Duration(reader.TicksPerSecond())
var prevTicks map[string]cputicks.Stat
return func(ctx context.Context, now pcommon.Timestamp, mb *metadata.MetricsBuilder) error {

Check failure on line 62 in receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper_linux.go

View workflow job for this annotation

GitHub Actions / lint-matrix (linux, receiver-1)

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
ticks, err := reader.ReadAll()
if err != nil {
return err
}

recordTickTimes(now, ticks, tickDuration, mb)

if prevTicks != nil {
currTicks := make(map[string]cputicks.Stat, len(ticks))
for _, t := range ticks {
currTicks[t.CPU] = t
}
for _, prev := range prevTicks {
curr, ok := currTicks[prev.CPU]
if !ok {
return fmt.Errorf("getting ticks for cpu %s: %w", prev.CPU, ucal.ErrTimeStatNotFound)
}
recordTickUtilization(now, prev, curr, mb)
}
}
prevTicks = make(map[string]cputicks.Stat, len(ticks))
for _, t := range ticks {
prevTicks[t.CPU] = t
}
return nil
}
}

func recordTickTimes(now pcommon.Timestamp, ticks []cputicks.Stat, tickDuration time.Duration, mb *metadata.MetricsBuilder) {
for _, t := range ticks {
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.User, tickDuration), t.CPU, metadata.AttributeStateUser)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.System, tickDuration), t.CPU, metadata.AttributeStateSystem)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Idle, tickDuration), t.CPU, metadata.AttributeStateIdle)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Irq, tickDuration), t.CPU, metadata.AttributeStateInterrupt)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Nice, tickDuration), t.CPU, metadata.AttributeStateNice)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Softirq, tickDuration), t.CPU, metadata.AttributeStateSoftirq)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Steal, tickDuration), t.CPU, metadata.AttributeStateSteal)
mb.RecordSystemCPUTimeDataPoint(now, precision.Scale(t.Iowait, tickDuration), t.CPU, metadata.AttributeStateWait)
}
}

func recordTickUtilization(now pcommon.Timestamp, prev, curr cputicks.Stat, mb *metadata.MetricsBuilder) {
deltaTotal := curr.Total() - prev.Total()
if deltaTotal == 0 {
recordZeroUtilization(now, curr.CPU, mb)
return
}
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.User-prev.User, deltaTotal), curr.CPU, metadata.AttributeStateUser)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.System-prev.System, deltaTotal), curr.CPU, metadata.AttributeStateSystem)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Idle-prev.Idle, deltaTotal), curr.CPU, metadata.AttributeStateIdle)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Irq-prev.Irq, deltaTotal), curr.CPU, metadata.AttributeStateInterrupt)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Nice-prev.Nice, deltaTotal), curr.CPU, metadata.AttributeStateNice)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Softirq-prev.Softirq, deltaTotal), curr.CPU, metadata.AttributeStateSoftirq)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Steal-prev.Steal, deltaTotal), curr.CPU, metadata.AttributeStateSteal)
mb.RecordSystemCPUUtilizationDataPoint(now, precision.Ratio(curr.Iowait-prev.Iowait, deltaTotal), curr.CPU, metadata.AttributeStateWait)
}

func recordZeroUtilization(now pcommon.Timestamp, cpuName string, mb *metadata.MetricsBuilder) {
for _, state := range []metadata.AttributeState{
metadata.AttributeStateUser,
metadata.AttributeStateSystem,
metadata.AttributeStateIdle,
metadata.AttributeStateInterrupt,
metadata.AttributeStateNice,
metadata.AttributeStateSoftirq,
metadata.AttributeStateSteal,
metadata.AttributeStateWait,
} {
mb.RecordSystemCPUUtilizationDataPoint(now, 0, cpuName, state)
}
}

func recordCPUTimeStateDataPoints(now pcommon.Timestamp, cpuTime cpu.TimesStat, mb *metadata.MetricsBuilder) {
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.User, cpuTime.CPU, metadata.AttributeStateUser)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.System, cpuTime.CPU, metadata.AttributeStateSystem)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Idle, cpuTime.CPU, metadata.AttributeStateIdle)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Irq, cpuTime.CPU, metadata.AttributeStateInterrupt)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Nice, cpuTime.CPU, metadata.AttributeStateNice)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Softirq, cpuTime.CPU, metadata.AttributeStateSoftirq)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Steal, cpuTime.CPU, metadata.AttributeStateSteal)
mb.RecordSystemCPUTimeDataPoint(now, cpuTime.Iowait, cpuTime.CPU, metadata.AttributeStateWait)
}

func recordCPUUtilization(now pcommon.Timestamp, cpuUtilization ucal.CPUUtilization, mb *metadata.MetricsBuilder) {
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.User, cpuUtilization.CPU, metadata.AttributeStateUser)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.System, cpuUtilization.CPU, metadata.AttributeStateSystem)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Idle, cpuUtilization.CPU, metadata.AttributeStateIdle)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Irq, cpuUtilization.CPU, metadata.AttributeStateInterrupt)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Nice, cpuUtilization.CPU, metadata.AttributeStateNice)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Softirq, cpuUtilization.CPU, metadata.AttributeStateSoftirq)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Steal, cpuUtilization.CPU, metadata.AttributeStateSteal)
mb.RecordSystemCPUUtilizationDataPoint(now, cpuUtilization.Iowait, cpuUtilization.CPU, metadata.AttributeStateWait)
}

func (*cpuScraper) getCPUInfo() ([]cpuInfo, error) {
Expand Down
Loading
Loading