Skip to content

Commit c09b574

Browse files
rubenruizdegaunaCaleb-Hurshman
authored andcommitted
[receiver/hostmetrics] send process.cpu.utilization if enabled (open-telemetry#23451)
Currently `process.cpu.utilization` is not sent when it is enabled if `process.cpu.time` is disabled. It should be sent independently of `process.cpu.time`
1 parent 4fbdf4f commit c09b574

File tree

3 files changed

+111
-2
lines changed

3 files changed

+111
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Use this changelog template to create an entry for release notes.
2+
# If your change doesn't affect end users, such as a test fix or a tooling change,
3+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
4+
5+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
6+
change_type: bug_fix
7+
8+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
9+
component: receiver/hostmetricsreceiver
10+
11+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
12+
note: Fix not sending `process.cpu.utilization` when `process.cpu.time` is disabled.
13+
14+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
15+
issues: [23450]
16+
17+
# (Optional) One or more lines of additional information to render under the primary note.
18+
# These lines will be padded with 2 spaces and then inserted directly into the document.
19+
# Use pipe (|) for multiline entries.
20+
subtext:

receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func (s *scraper) getProcessMetadata() ([]*processMetadata, error) {
237237
}
238238

239239
func (s *scraper) scrapeAndAppendCPUTimeMetric(now pcommon.Timestamp, handle processHandle, pid int32) error {
240-
if !s.config.MetricsBuilderConfig.Metrics.ProcessCPUTime.Enabled {
240+
if !s.config.MetricsBuilderConfig.Metrics.ProcessCPUTime.Enabled && !s.config.MetricsBuilderConfig.Metrics.ProcessCPUUtilization.Enabled {
241241
return nil
242242
}
243243

@@ -246,7 +246,14 @@ func (s *scraper) scrapeAndAppendCPUTimeMetric(now pcommon.Timestamp, handle pro
246246
return err
247247
}
248248

249-
s.recordCPUTimeMetric(now, times)
249+
if s.config.MetricsBuilderConfig.Metrics.ProcessCPUTime.Enabled {
250+
s.recordCPUTimeMetric(now, times)
251+
}
252+
253+
if !s.config.MetricsBuilderConfig.Metrics.ProcessCPUUtilization.Enabled {
254+
return nil
255+
}
256+
250257
if _, ok := s.ucals[pid]; !ok {
251258
s.ucals[pid] = &ucal.CPUUtilizationCalculator{}
252259
}

receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_test.go

+82
Original file line numberDiff line numberDiff line change
@@ -1089,3 +1089,85 @@ func TestScrapeMetrics_DontCheckDisabledMetrics(t *testing.T) {
10891089
assert.Nil(t, err)
10901090
})
10911091
}
1092+
1093+
func TestScrapeMetrics_CpuUtilizationWhenCpuTimesIsDisabled(t *testing.T) {
1094+
skipTestOnUnsupportedOS(t)
1095+
1096+
testCases := []struct {
1097+
name string
1098+
processCPUTimes bool
1099+
processCPUUtilization bool
1100+
expectedMetricCount int
1101+
expectedMetricNames []string
1102+
}{
1103+
{
1104+
name: "process.cpu.time enabled, process.cpu.utilization disabled",
1105+
processCPUTimes: true,
1106+
processCPUUtilization: false,
1107+
expectedMetricCount: 1,
1108+
expectedMetricNames: []string{"process.cpu.time"},
1109+
},
1110+
{
1111+
name: "process.cpu.time disabled, process.cpu.utilization enabled",
1112+
processCPUTimes: false,
1113+
processCPUUtilization: true,
1114+
expectedMetricCount: 1,
1115+
expectedMetricNames: []string{"process.cpu.utilization"},
1116+
},
1117+
{
1118+
name: "process.cpu.time enabled, process.cpu.utilization enabled",
1119+
processCPUTimes: true,
1120+
processCPUUtilization: true,
1121+
expectedMetricCount: 2,
1122+
expectedMetricNames: []string{"process.cpu.time", "process.cpu.utilization"},
1123+
},
1124+
}
1125+
1126+
for i := range testCases {
1127+
testCase := testCases[i]
1128+
t.Run(testCase.name, func(t *testing.T) {
1129+
metricsBuilderConfig := metadata.DefaultMetricsBuilderConfig()
1130+
1131+
metricsBuilderConfig.Metrics.ProcessCPUTime.Enabled = testCase.processCPUTimes
1132+
metricsBuilderConfig.Metrics.ProcessCPUUtilization.Enabled = testCase.processCPUUtilization
1133+
1134+
// disable some default metrics for easy assertion
1135+
metricsBuilderConfig.Metrics.ProcessMemoryUsage.Enabled = false
1136+
metricsBuilderConfig.Metrics.ProcessMemoryVirtual.Enabled = false
1137+
metricsBuilderConfig.Metrics.ProcessDiskIo.Enabled = false
1138+
1139+
config := &Config{MetricsBuilderConfig: metricsBuilderConfig}
1140+
1141+
scraper, err := newProcessScraper(receivertest.NewNopCreateSettings(), config)
1142+
require.NoError(t, err, "Failed to create process scraper: %v", err)
1143+
err = scraper.start(context.Background(), componenttest.NewNopHost())
1144+
require.NoError(t, err, "Failed to initialize process scraper: %v", err)
1145+
1146+
handleMock := newDefaultHandleMock()
1147+
handleMock.On("Name").Return("test", nil)
1148+
handleMock.On("Exe").Return("test", nil)
1149+
handleMock.On("CreateTime").Return(time.Now().UnixMilli(), nil)
1150+
1151+
scraper.getProcessHandles = func() (processHandles, error) {
1152+
return &processHandlesMock{handles: []*processHandleMock{handleMock}}, nil
1153+
}
1154+
1155+
// scrape the first time
1156+
_, err = scraper.scrape(context.Background())
1157+
assert.Nil(t, err)
1158+
1159+
// scrape second time to get utilization
1160+
md, err := scraper.scrape(context.Background())
1161+
assert.Nil(t, err)
1162+
1163+
for k := 0; k < md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().Len(); k++ {
1164+
fmt.Println(md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(k).Name())
1165+
}
1166+
assert.Equal(t, testCase.expectedMetricCount, md.MetricCount())
1167+
for metricIdx, expectedMetricName := range testCase.expectedMetricNames {
1168+
assert.Equal(t, expectedMetricName, md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(metricIdx).Name())
1169+
}
1170+
})
1171+
}
1172+
1173+
}

0 commit comments

Comments
 (0)