diff --git a/.chloggen/stanley.liu_os-type.yaml b/.chloggen/stanley.liu_os-type.yaml new file mode 100644 index 0000000000000..0b16c14e39396 --- /dev/null +++ b/.chloggen/stanley.liu_os-type.yaml @@ -0,0 +1,27 @@ +# 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: extension/datadog + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Set `os.type` resource attribute if not already present for Fleet Automation metadata. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [46896] + +# (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: + +# 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/extension/datadogextension/extension.go b/extension/datadogextension/extension.go index 8fdddff370189..be02d54d7cd78 100644 --- a/extension/datadogextension/extension.go +++ b/extension/datadogextension/extension.go @@ -5,6 +5,7 @@ package datadogextension // import "github.com/open-telemetry/opentelemetry-coll import ( "context" + "runtime" "sync" "time" @@ -20,6 +21,7 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/service" "go.opentelemetry.io/collector/service/hostcapabilities" + conventions "go.opentelemetry.io/otel/semconv/v1.38.0" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/extension/datadogextension/internal/componentchecker" @@ -391,6 +393,10 @@ func newExtension( return true }) } + // Ensure os.type is always present; defer to any value already set by a resource detector + if _, ok := resourceMap[string(conventions.OSTypeKey)]; !ok { + resourceMap[string(conventions.OSTypeKey)] = runtime.GOOS + } // configure payloadSender struct ctxWithCancel, cancel := context.WithCancel(ctx) diff --git a/extension/datadogextension/extension_test.go b/extension/datadogextension/extension_test.go index 171b02b4c7a39..b90099a66ed40 100644 --- a/extension/datadogextension/extension_test.go +++ b/extension/datadogextension/extension_test.go @@ -6,6 +6,7 @@ package datadogextension import ( "context" "errors" + "runtime" "sync" "testing" "time" @@ -227,9 +228,9 @@ func TestCollectorResourceAttributesArePopulated(t *testing.T) { err = ext.NotifyConfig(t.Context(), conf) require.NoError(t, err) - // Expect map with keys and values + // Expect map with keys and values (os.type is always injected as a fallback) require.NotNil(t, ext.otelCollectorMetadata) - expected := map[string]string{"a_key": "1", "b_key": "2"} + expected := map[string]string{"a_key": "1", "b_key": "2", "os.type": runtime.GOOS} assert.Equal(t, expected, ext.otelCollectorMetadata.CollectorResourceAttributes) // Cleanup @@ -274,12 +275,13 @@ func TestCollectorResourceAttributesWithMultipleKeys(t *testing.T) { err = ext.NotifyConfig(t.Context(), conf) require.NoError(t, err) - // Verify all resource attributes are collected + // Verify all resource attributes are collected (os.type is always injected as a fallback) require.NotNil(t, ext.otelCollectorMetadata) expected := map[string]string{ "deployment.environment.name": "prod", "cloud.region": "us-east", "team.name": "backend", + "os.type": runtime.GOOS, } assert.Equal(t, expected, ext.otelCollectorMetadata.CollectorResourceAttributes) diff --git a/extension/datadogextension/go.mod b/extension/datadogextension/go.mod index b7a23285b6f4b..83cb94a2eb61a 100644 --- a/extension/datadogextension/go.mod +++ b/extension/datadogextension/go.mod @@ -27,6 +27,7 @@ require ( go.opentelemetry.io/collector/pdata v1.53.1-0.20260312222452-c212d203a110 go.opentelemetry.io/collector/service v0.147.1-0.20260312222452-c212d203a110 go.opentelemetry.io/collector/service/hostcapabilities v0.147.1-0.20260312222452-c212d203a110 + go.opentelemetry.io/otel v1.42.0 go.uber.org/zap v1.27.1 ) @@ -253,7 +254,6 @@ require ( go.opentelemetry.io/collector/receiver/xreceiver v0.147.1-0.20260312222452-c212d203a110 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect go.opentelemetry.io/contrib/otelconf v0.22.0 // indirect - go.opentelemetry.io/otel v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect diff --git a/extension/datadogextension/internal/httpserver/httpserver_test.go b/extension/datadogextension/internal/httpserver/httpserver_test.go index c6d81ccd85c2b..691ac18191ad1 100644 --- a/extension/datadogextension/internal/httpserver/httpserver_test.go +++ b/extension/datadogextension/internal/httpserver/httpserver_test.go @@ -228,7 +228,6 @@ const successfulInstanceResponse = `{ "collector_resource_attributes": {}, "collector_deployment_type": "unknown", "collector_installation_method": "", - "os": "", "ttl": 900000000000 }, "uuid": "test-uuid" diff --git a/extension/datadogextension/internal/payload/payload.go b/extension/datadogextension/internal/payload/payload.go index d71f3eebd4d92..167386720908e 100644 --- a/extension/datadogextension/internal/payload/payload.go +++ b/extension/datadogextension/internal/payload/payload.go @@ -7,7 +7,6 @@ package payload // import "github.com/open-telemetry/opentelemetry-collector-con import ( "encoding/json" "errors" - "runtime" "github.com/DataDog/datadog-agent/pkg/serializer/marshaler" ) @@ -39,7 +38,6 @@ type OtelCollector struct { CollectorResourceAttributes map[string]string `json:"collector_resource_attributes"` CollectorDeploymentType string `json:"collector_deployment_type"` // deployment type: gateway, daemonset, or unknown CollectorInstallationMethod string `json:"collector_installation_method"` // installation method: kubernetes, bare-metal, docker, ecs-fargate, eks-fargate, or "" - OS string `json:"os"` // runtime operating system (runtime.GOOS) TTL int64 `json:"ttl"` } @@ -110,7 +108,6 @@ func PrepareOtelCollectorMetadata( FullConfiguration: fullConfig, CollectorDeploymentType: deploymentType, CollectorInstallationMethod: installationMethod, - OS: runtime.GOOS, TTL: ttl, } } diff --git a/extension/datadogextension/internal/payload/payload_test.go b/extension/datadogextension/internal/payload/payload_test.go index 16edf2cbf9c24..5487fefea2bf7 100644 --- a/extension/datadogextension/internal/payload/payload_test.go +++ b/extension/datadogextension/internal/payload/payload_test.go @@ -465,28 +465,6 @@ func TestPrepareOtelCollectorMetadata_DeploymentType(t *testing.T) { } } -func TestPrepareOtelCollectorMetadata_OS(t *testing.T) { - buildInfo := CustomBuildInfo{Command: "otelcol", Description: "Test Collector", Version: "1.0.0"} - metadata := PrepareOtelCollectorMetadata( - "test-host", "config", "test-uuid", "1.0.0", "datadoghq.com", "{}", - "unknown", "", buildInfo, int64(5*time.Minute*3), - ) - - assert.NotEmpty(t, metadata.OS) - - payload := &OtelCollectorPayload{Hostname: "test-host", Timestamp: time.Now().UnixNano(), UUID: "test-uuid", Metadata: metadata} - jsonData, err := json.Marshal(payload) - require.NoError(t, err) - - var jsonMap map[string]any - err = json.Unmarshal(jsonData, &jsonMap) - require.NoError(t, err) - - metadataMap, ok := jsonMap["otel_collector"].(map[string]any) - require.True(t, ok) - assert.NotEmpty(t, metadataMap["os"]) -} - func TestPrepareOtelCollectorMetadata_InstallationMethod(t *testing.T) { tests := []struct { name string