Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renaming process.cpu.state attribute to cpu.mode #1110

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion pkg/export/attributes/attr_defs.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func getDefinitions(groups AttrGroups) map[Section]AttrReportGroup {
var processAttributes = AttrReportGroup{
SubGroups: []*AttrReportGroup{&appKubeAttributes, &hostAttributes, &promProcessAttributes},
Attributes: map[attr.Name]Default{
attr.ProcCPUState: true,
attr.ProcCPUMode: true,
attr.ProcDiskIODir: true,
attr.ProcNetIODir: true,
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/export/attributes/names/attrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const (
const (
ProcCommand = Name(semconv.ProcessCommandKey)
ProcCommandLine = Name(semconv.ProcessCommandLineKey)
ProcCPUState = Name("process.cpu.state")
ProcCPUMode = Name("cpu.mode")
ProcDiskIODir = Name(semconv2.DiskIoDirectionKey)
ProcNetIODir = Name(semconv2.NetworkIoDirectionKey)
ProcOwner = Name(semconv.ProcessOwnerKey)
Expand Down
2 changes: 1 addition & 1 deletion pkg/export/otel/expirer.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func NewExpirer[Record any, Metric removableMetric[ValType], ValType any](
// ForRecord returns the data point for the given eBPF record. If that record
// is accessed for the first time, a new data point is created.
// If not, a cached copy is returned and the "last access" cache time is updated.
// Extra attributes can be explicitly added (e.g. process_cpu_state="wait")
// Extra attributes can be explicitly added (e.g. cpu_mode="wait")
func (ex *Expirer[Record, Metric, ValType]) ForRecord(r Record, extraAttrs ...attribute.KeyValue) (Metric, attribute.Set) {
// to save resources, metrics expiration is triggered each TTL. This means that an expired
// metric might stay visible after 2*TTL time after not being updated
Expand Down
16 changes: 8 additions & 8 deletions pkg/export/otel/metrics_proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import (
)

var (
stateWaitAttr = attr2.ProcCPUState.OTEL().String("wait")
stateUserAttr = attr2.ProcCPUState.OTEL().String("user")
stateSystemAttr = attr2.ProcCPUState.OTEL().String("system")
stateWaitAttr = attr2.ProcCPUMode.OTEL().String("wait")
stateUserAttr = attr2.ProcCPUMode.OTEL().String("user")
stateSystemAttr = attr2.ProcCPUMode.OTEL().String("system")

diskIODirRead = attr2.ProcDiskIODir.OTEL().String("read")
diskIODirWrite = attr2.ProcDiskIODir.OTEL().String("write")
Expand Down Expand Up @@ -69,7 +69,7 @@ type procMetricsExporter struct {
attrNet []attributes.Field[*process.Status, attribute.KeyValue]

// the observation code for CPU metrics will be different depending on
// the "process.cpu.state" attribute being selected or not
// the "cpu.mode" attribute being selected or not
cpuTimeObserver func(context.Context, *procMetrics, *process.Status)
cpuUtilisationObserver func(context.Context, *procMetrics, *process.Status)

Expand Down Expand Up @@ -149,12 +149,12 @@ func newProcMetricsExporter(
attrDisk: attrDisk,
attrNet: attrNet,
}
if slices.Contains(cpuTimeNames, attr2.ProcCPUState) {
if slices.Contains(cpuTimeNames, attr2.ProcCPUMode) {
mr.cpuTimeObserver = cpuTimeDisaggregatedObserver
} else {
mr.cpuTimeObserver = cpuTimeAggregatedObserver
}
if slices.Contains(cpuUtilNames, attr2.ProcCPUState) {
if slices.Contains(cpuUtilNames, attr2.ProcCPUMode) {
mr.cpuUtilisationObserver = cpuUtilisationDisaggregatedObserver
} else {
mr.cpuUtilisationObserver = cpuUtilisationAggregatedObserver
Expand Down Expand Up @@ -329,7 +329,7 @@ func (me *procMetricsExporter) observeMetric(reporter *procMetrics, s *process.S
}

// aggregated observers report all the CPU metrics in a single data point
// to be triggered when the user disables the "process_cpu_state" metric
// to be triggered when the user disables the "cpu_mode" metric
func cpuTimeAggregatedObserver(ctx context.Context, reporter *procMetrics, record *process.Status) {
cpu, attrs := reporter.cpuTime.ForRecord(record)
cpu.Add(ctx, record.CPUTimeUserDelta+record.CPUTimeSystemDelta+record.CPUTimeWaitDelta,
Expand All @@ -343,7 +343,7 @@ func cpuUtilisationAggregatedObserver(ctx context.Context, reporter *procMetrics
}

// disaggregated observers report three CPU metrics: system, user and wait time
// to be triggered when the user enables the "process_cpu_state" metric
// to be triggered when the user enables the "cpu_mode" metric
func cpuTimeDisaggregatedObserver(ctx context.Context, reporter *procMetrics, record *process.Status) {
cpu, attrs := reporter.cpuTime.ForRecord(record, stateWaitAttr)
cpu.Add(ctx, record.CPUTimeWaitDelta, metric2.WithAttributeSet(attrs))
Expand Down
18 changes: 9 additions & 9 deletions pkg/export/otel/metrics_proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestProcMetrics_Aggregated(t *testing.T) {
otlp, err := collector.Start(ctx)
require.NoError(t, err)

// GIVEN an OTEL Metrics Exporter whose process CPU metrics do not consider the process.cpu.state
// GIVEN an OTEL Metrics Exporter whose process CPU metrics do not consider the cpu.mode
includedAttributes := attributes.InclusionLists{
Exclude: []string{"*"},
}
Expand Down Expand Up @@ -191,9 +191,9 @@ func TestProcMetrics_Disaggregated(t *testing.T) {
otlp, err := collector.Start(ctx)
require.NoError(t, err)

// GIVEN an OTEL Metrics Exporter whose process CPU metrics consider the process.cpu.state
// GIVEN an OTEL Metrics Exporter whose process CPU metrics consider the cpu.mode
includedAttributes := attributes.InclusionLists{
Include: []string{"process_command", "process_cpu_state", "disk_io_direction", "network_io_direction"},
Include: []string{"process_command", "cpu_mode", "disk_io_direction", "network_io_direction"},
}
otelExporter, err := ProcMetricsExporterProvider(
ctx, &global.ContextInfo{}, &ProcMetricsConfig{
Expand Down Expand Up @@ -233,42 +233,42 @@ func TestProcMetrics_Disaggregated(t *testing.T) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.time", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "user"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "user"}, metric.Attributes)
require.EqualValues(t, 30, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.time", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "system"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "system"}, metric.Attributes)
require.EqualValues(t, 10, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.time", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "wait"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "wait"}, metric.Attributes)
require.EqualValues(t, 20, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.utilization", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "user"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "user"}, metric.Attributes)
require.EqualValues(t, 1, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.utilization", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "system"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "system"}, metric.Attributes)
require.EqualValues(t, 2, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
metric := readChan(t, otlp.Records(), timeout)
require.Equal(t, "process.cpu.utilization", metric.Name)
require.Equal(t, "foo", metric.ResourceAttributes["process.command"])
require.Equal(t, map[string]string{"process.cpu.state": "wait"}, metric.Attributes)
require.Equal(t, map[string]string{"cpu.mode": "wait"}, metric.Attributes)
require.EqualValues(t, 3, metric.FloatVal)
})
test.Eventually(t, timeout, func(t require.TestingT) {
Expand Down
14 changes: 7 additions & 7 deletions pkg/export/prom/prom_proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type procMetricsReporter struct {
net *Expirer[prometheus.Counter]

// the observation code for CPU metrics will be different depending on
// the "process.cpu.state" attribute being selected or not
// the "cpu.mode" attribute being selected or not
cpuTimeObserver func(*process.Status)
cpuUtilizationObserver func(*process.Status)

Expand All @@ -108,9 +108,9 @@ func newProcReporter(
}

cpuTimeLblNames, cpuTimeGetters, cpuTimeHasState :=
attributesWithExplicit(provider, attributes.ProcessCPUTime, attr2.ProcCPUState)
attributesWithExplicit(provider, attributes.ProcessCPUTime, attr2.ProcCPUMode)
cpuUtilLblNames, cpuUtilGetters, cpuUtilHasState :=
attributesWithExplicit(provider, attributes.ProcessCPUUtilization, attr2.ProcCPUState)
attributesWithExplicit(provider, attributes.ProcessCPUUtilization, attr2.ProcCPUMode)
diskLblNames, diskGetters, diskHasDirection :=
attributesWithExplicit(provider, attributes.ProcessDiskIO, attr2.ProcDiskIODir)
netLblNames, netGetters, netHasDirection :=
Expand Down Expand Up @@ -225,7 +225,7 @@ func (r *procMetricsReporter) observeMetric(proc *process.Status) {
}

// aggregated observers report all the CPU metrics in a single data point
// to be triggered when the user disables the "process_cpu_state" metric
// to be triggered when the user disables the "cpu_mode" metric
func (r *procMetricsReporter) observeAggregatedCPUTime(proc *process.Status) {
r.cpuTime.WithLabelValues(labelValues(proc, r.cpuTimeAttrs)...).
metric.Add(proc.CPUTimeUserDelta + proc.CPUTimeSystemDelta + proc.CPUTimeWaitDelta)
Expand All @@ -237,7 +237,7 @@ func (r *procMetricsReporter) observeAggregatedCPUUtilization(proc *process.Stat
}

// disaggregated observers report three CPU metrics: system, user and wait time
// to be triggered when the user enables the "process_cpu_state" metric
// to be triggered when the user enables the "cpu_mode" metric
func (r *procMetricsReporter) observeDisaggregatedCPUTime(proc *process.Status) {
commonLabelValues := labelValues(proc, r.cpuTimeAttrs)

Expand Down Expand Up @@ -293,15 +293,15 @@ func (r *procMetricsReporter) observeDisaggregatedNet(proc *process.Status) {
// attributesWithExplicit returns, for a metric name definition,
// which attribute names are defined as well as the getters for
// them. It also returns if the invoker must explicitly add the
// provided explicit attribute name and value (e.g. "process.cpu.state"
// provided explicit attribute name and value (e.g. "cpu.mode"
// or "disk.io.direction")
func attributesWithExplicit(
provider *attributes.AttrSelector, metricName attributes.Name, explicitAttribute attr2.Name,
) (
names []string, getters []attributes.Field[*process.Status, string], containsExplicit bool,
) {
attrNames := provider.For(metricName)
// For example, "process_cpu_state" won't be added by PrometheusGetters, as it's not defined in the *process.Status
// For example, "cpu_mode" won't be added by PrometheusGetters, as it's not defined in the *process.Status
// we need to be aware of the user willing to add it to explicitly choose between
// observeAggregatedCPU and observeDisaggregatedCPU
// Similar for "process_disk_io" or "process_network_io"
Expand Down
30 changes: 15 additions & 15 deletions pkg/export/prom/prom_proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestProcPrometheusEndpoint_AggregatedMetrics(t *testing.T) {
require.NoError(t, err)
promURL := fmt.Sprintf("http://127.0.0.1:%d/metrics", openPort)

// GIVEN a Prometheus Metrics Exporter whose process CPU metrics do not consider the process_cpu_state
// GIVEN a Prometheus Metrics Exporter whose process CPU metrics do not consider the cpu_mode
attribs := attributes.InclusionLists{
Include: []string{"process_command"},
}
Expand Down Expand Up @@ -115,9 +115,9 @@ func TestProcPrometheusEndpoint_DisaggregatedMetrics(t *testing.T) {
require.NoError(t, err)
promURL := fmt.Sprintf("http://127.0.0.1:%d/metrics", openPort)

// GIVEN a Prometheus Metrics Exporter whose process CPU metrics consider the process_cpu_state
// GIVEN a Prometheus Metrics Exporter whose process CPU metrics consider the cpu_mode
attribs := attributes.InclusionLists{
Include: []string{"process_command", "process_cpu_state", "disk_io_direction", "network_io_direction"},
Include: []string{"process_command", "cpu_mode", "disk_io_direction", "network_io_direction"},
}
exporter, err := ProcPrometheusEndpoint(
ctx, &global.ContextInfo{Prometheus: &connector.PrometheusManager{}},
Expand Down Expand Up @@ -152,12 +152,12 @@ func TestProcPrometheusEndpoint_DisaggregatedMetrics(t *testing.T) {
// THEN the metrics are exported aggregated by system/user/wait times
test.Eventually(t, timeout, func(t require.TestingT) {
exported := getMetrics(t, promURL)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="user"} 1`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="system"} 2`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="wait"} 3`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="user"} 30`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="system"} 10`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="wait"} 20`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="user",process_command="foo"} 1`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="system",process_command="foo"} 2`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="wait",process_command="foo"} 3`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="user",process_command="foo"} 30`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="system",process_command="foo"} 10`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="wait",process_command="foo"} 20`)
assert.Contains(t, exported, `process_disk_io_bytes_total{disk_io_direction="read",process_command="foo"} 123`)
assert.Contains(t, exported, `process_disk_io_bytes_total{disk_io_direction="write",process_command="foo"} 456`)
assert.Contains(t, exported, `process_network_io_bytes_total{network_io_direction="transmit",process_command="foo"} 3`)
Expand All @@ -177,12 +177,12 @@ func TestProcPrometheusEndpoint_DisaggregatedMetrics(t *testing.T) {
// THEN the counter is updated by adding values and the gauges change their values
test.Eventually(t, timeout, func(t require.TestingT) {
exported := getMetrics(t, promURL)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="user"} 2`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="system"} 1`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{process_command="foo",process_cpu_state="wait"} 4`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="user"} 33`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="system"} 11`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{process_command="foo",process_cpu_state="wait"} 22`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="user",process_command="foo"} 2`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="system",process_command="foo"} 1`)
assert.Contains(t, exported, `process_cpu_utilization_ratio{cpu_mode="wait",process_command="foo"} 4`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="user",process_command="foo"} 33`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="system",process_command="foo"} 11`)
assert.Contains(t, exported, `process_cpu_time_seconds_total{cpu_mode="wait",process_command="foo"} 22`)
assert.Contains(t, exported, `process_disk_io_bytes_total{disk_io_direction="read",process_command="foo"} 126`)
assert.Contains(t, exported, `process_disk_io_bytes_total{disk_io_direction="write",process_command="foo"} 458`)
assert.Contains(t, exported, `process_network_io_bytes_total{network_io_direction="transmit",process_command="foo"} 33`)
Expand Down
4 changes: 2 additions & 2 deletions pkg/internal/infraolly/process/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func NewStatus(pid int32, svcID *svc.ID) *Status {
func OTELGetters(name attr.Name) (attributes.Getter[*Status, attribute.KeyValue], bool) {
var g attributes.Getter[*Status, attribute.KeyValue]
switch name {
case attr.ProcCPUState, attr.ProcDiskIODir, attr.ProcNetIODir:
case attr.ProcCPUMode, attr.ProcDiskIODir, attr.ProcNetIODir:
// the attributes are handled explicitly by the OTEL exporter, but we need to
// ignore them to avoid that the default case tries to report them from service metadata
}
Expand Down Expand Up @@ -116,7 +116,7 @@ func PromGetters(name attr.Name) (attributes.Getter[*Status, string], bool) {
g = func(s *Status) string { return strconv.Itoa(int(s.ID.ParentProcessID)) }
case attr.ProcPid:
g = func(s *Status) string { return strconv.Itoa(int(s.ID.ProcessID)) }
case attr.ProcCPUState, attr.ProcDiskIODir, attr.ProcNetIODir:
case attr.ProcCPUMode, attr.ProcDiskIODir, attr.ProcNetIODir:
// the attributes are handled explicitly by the prometheus exporter, but we need to
// ignore them to avoid that the default case tries to report them from service metadata
default:
Expand Down
2 changes: 1 addition & 1 deletion test/integration/configs/instrumenter-config-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ attributes:
process_*:
include: ["*"]
process_cpu_*:
exclude: ["process_cpu_state"]
exclude: ["cpu_mode"]
4 changes: 2 additions & 2 deletions test/integration/configs/instrumenter-config-promscrape.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ attributes:
select:
process_cpu_utilization:
include: ["*"]
exclude: ["process_cpu_state"]
exclude: ["cpu_mode"]
process_cpu_time:
include: ["*"]
exclude: ["process_cpu_state"]
exclude: ["cpu_mode"]
process_memory_usage:
include: ["*"]
process_memory_virtual:
Expand Down
Loading