diff --git a/.chloggen/mx-psi_change-to-string.yaml b/.chloggen/mx-psi_change-to-string.yaml new file mode 100755 index 0000000000000..44736c5f86819 --- /dev/null +++ b/.chloggen/mx-psi_change-to-string.yaml @@ -0,0 +1,28 @@ +# 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. filelogreceiver) +component: processor/resourcedetection + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add `processor.resourcedetection.hostCPUModelAndFamilyAsString` feature gate to change the type of `host.cpu.family` and `host.cpu.model.id` attributes from `int` to `string`. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [29025] + +# (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: | + This feature gate will graduate to beta in the next release. + +# 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: [] diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go index 15cb068bc7200..6f4c3ab83d5af 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go @@ -36,16 +36,16 @@ func (rb *ResourceBuilder) SetHostCPUCacheL2Size(val int64) { } // SetHostCPUFamily sets provided value as "host.cpu.family" attribute. -func (rb *ResourceBuilder) SetHostCPUFamily(val int64) { +func (rb *ResourceBuilder) SetHostCPUFamily(val string) { if rb.config.HostCPUFamily.Enabled { - rb.res.Attributes().PutInt("host.cpu.family", val) + rb.res.Attributes().PutStr("host.cpu.family", val) } } // SetHostCPUModelID sets provided value as "host.cpu.model.id" attribute. -func (rb *ResourceBuilder) SetHostCPUModelID(val int64) { +func (rb *ResourceBuilder) SetHostCPUModelID(val string) { if rb.config.HostCPUModelID.Enabled { - rb.res.Attributes().PutInt("host.cpu.model.id", val) + rb.res.Attributes().PutStr("host.cpu.model.id", val) } } diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go index 77de906301f95..b7a089dc81507 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go @@ -15,8 +15,8 @@ func TestResourceBuilder(t *testing.T) { rb := NewResourceBuilder(cfg) rb.SetHostArch("host.arch-val") rb.SetHostCPUCacheL2Size(22) - rb.SetHostCPUFamily(15) - rb.SetHostCPUModelID(17) + rb.SetHostCPUFamily("host.cpu.family-val") + rb.SetHostCPUModelID("host.cpu.model.id-val") rb.SetHostCPUModelName("host.cpu.model.name-val") rb.SetHostCPUStepping(17) rb.SetHostCPUVendorID("host.cpu.vendor.id-val") @@ -53,12 +53,12 @@ func TestResourceBuilder(t *testing.T) { val, ok = res.Attributes().Get("host.cpu.family") assert.Equal(t, test == "all_set", ok) if ok { - assert.EqualValues(t, 15, val.Int()) + assert.EqualValues(t, "host.cpu.family-val", val.Str()) } val, ok = res.Attributes().Get("host.cpu.model.id") assert.Equal(t, test == "all_set", ok) if ok { - assert.EqualValues(t, 17, val.Int()) + assert.EqualValues(t, "host.cpu.model.id-val", val.Str()) } val, ok = res.Attributes().Get("host.cpu.model.name") assert.Equal(t, test == "all_set", ok) diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/resource_int_version.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/resource_int_version.go new file mode 100644 index 0000000000000..be77f0644186e --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/resource_int_version.go @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/system/internal/metadata" + +// SetHostCPUFamilyAsInt sets provided value as "host.cpu.family" attribute as int. +func (rb *ResourceBuilder) SetHostCPUFamilyAsInt(val int64) { + if rb.config.HostCPUFamily.Enabled { + rb.res.Attributes().PutInt("host.cpu.family", val) + } +} + +// SetHostCPUModelIDAsInt sets provided value as "host.cpu.model.id" attribute as int. +func (rb *ResourceBuilder) SetHostCPUModelIDAsInt(val int64) { + if rb.config.HostCPUModelID.Enabled { + rb.res.Attributes().PutInt("host.cpu.model.id", val) + } +} diff --git a/processor/resourcedetectionprocessor/internal/system/metadata.yaml b/processor/resourcedetectionprocessor/internal/system/metadata.yaml index 8cc1b760097a9..6cf860cebc715 100644 --- a/processor/resourcedetectionprocessor/internal/system/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/system/metadata.yaml @@ -29,11 +29,11 @@ resource_attributes: enabled: false host.cpu.family: description: The host.cpu.family - type: int + type: string enabled: false host.cpu.model.id: description: The host.cpu.model.id - type: int + type: string enabled: false host.cpu.model.name: description: The host.cpu.model.name diff --git a/processor/resourcedetectionprocessor/internal/system/system.go b/processor/resourcedetectionprocessor/internal/system/system.go index 63aec3aaaddb9..cecce5c1a10f1 100644 --- a/processor/resourcedetectionprocessor/internal/system/system.go +++ b/processor/resourcedetectionprocessor/internal/system/system.go @@ -10,6 +10,7 @@ import ( "strconv" "github.com/shirou/gopsutil/v3/cpu" + "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" conventions "go.opentelemetry.io/collector/semconv/v1.6.1" @@ -20,6 +21,17 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/system/internal/metadata" ) +var ( + hostCPUModelAndFamilyAsStringID = "processor.resourcedetection.hostCPUModelAndFamilyAsString" + hostCPUModelAndFamilyAsStringFeatureGate = featuregate.GlobalRegistry().MustRegister( + hostCPUModelAndFamilyAsStringID, + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Change type of host.cpu.model.id and host.cpu.model.family to string."), + featuregate.WithRegisterFromVersion("v0.89.0"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/semantic-conventions/issues/495"), + ) +) + const ( // TypeStr is type of detector. TypeStr = "system" @@ -147,21 +159,39 @@ func reverseLookupHost(d *Detector) (string, error) { func setHostCPUInfo(d *Detector, cpuInfo cpu.InfoStat) error { d.logger.Debug("getting host's cpuinfo", zap.String("coreID", cpuInfo.CoreID)) d.rb.SetHostCPUVendorID(cpuInfo.VendorID) - family, err := strconv.ParseInt(cpuInfo.Family, 10, 64) - if err != nil { - return fmt.Errorf("failed to convert cpuinfo family to integer: %w", err) + if hostCPUModelAndFamilyAsStringFeatureGate.IsEnabled() { + d.rb.SetHostCPUFamily(cpuInfo.Family) + } else { + // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29025 + d.logger.Warn("This attribute will change from int to string. Switch now using the feature gate.", + zap.String("attribute", "host.cpu.family"), + zap.String("feature gate", hostCPUModelAndFamilyAsStringID), + ) + family, err := strconv.ParseInt(cpuInfo.Family, 10, 64) + if err != nil { + return fmt.Errorf("failed to convert cpuinfo family to integer: %w", err) + } + d.rb.SetHostCPUFamilyAsInt(family) } - d.rb.SetHostCPUFamily(family) // For windows, this field is left blank. See https://github.com/shirou/gopsutil/blob/v3.23.9/cpu/cpu_windows.go#L113 // Skip setting modelId if the field is blank. // ISSUE: https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/27675 if cpuInfo.Model != "" { - model, err := strconv.ParseInt(cpuInfo.Model, 10, 64) - if err != nil { - return fmt.Errorf("failed to convert cpuinfo model to integer: %w", err) + if hostCPUModelAndFamilyAsStringFeatureGate.IsEnabled() { + d.rb.SetHostCPUModelID(cpuInfo.Model) + } else { + // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29025 + d.logger.Warn("This attribute will change from int to string. Switch now using the feature gate.", + zap.String("attribute", "host.cpu.model.id"), + zap.String("feature gate", hostCPUModelAndFamilyAsStringID), + ) + model, err := strconv.ParseInt(cpuInfo.Model, 10, 64) + if err != nil { + return fmt.Errorf("failed to convert cpuinfo model to integer: %w", err) + } + d.rb.SetHostCPUModelIDAsInt(model) } - d.rb.SetHostCPUModelID(model) } d.rb.SetHostCPUModelName(cpuInfo.ModelName)