From 572dbbaf1287492e5f3de535613364bd570ec184 Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Thu, 27 Jul 2023 01:52:27 -0400 Subject: [PATCH] [processor/resourcedetection] Support Cloud Run Jobs (#23681) **Description:** Adds support for Cloud Run Jobs using gcp-specific resource attributes **Documentation:** Semantic conventions updates: https://github.com/open-telemetry/semantic-conventions/blob/2246279243d743c6e073470f4e3551826f3115bc/specification/resource/semantic_conventions/cloud_provider/gcp/cloud_run.md --- .chloggen/gcp-cloud-run-jobs-detector.yaml | 20 +++++++ .../internal/gcp/gcp.go | 9 ++++ .../internal/gcp/gcp_test.go | 38 ++++++++++++++ .../gcp/internal/metadata/generated_config.go | 32 +++++++----- .../metadata/generated_config_test.go | 52 ++++++++++--------- .../internal/metadata/generated_resource.go | 14 +++++ .../metadata/generated_resource_test.go | 16 +++++- .../internal/metadata/testdata/config.yaml | 8 +++ .../internal/gcp/metadata.yaml | 8 +++ .../internal/gcp/types.go | 2 + 10 files changed, 161 insertions(+), 38 deletions(-) create mode 100755 .chloggen/gcp-cloud-run-jobs-detector.yaml diff --git a/.chloggen/gcp-cloud-run-jobs-detector.yaml b/.chloggen/gcp-cloud-run-jobs-detector.yaml new file mode 100755 index 000000000000..d4226c325dcb --- /dev/null +++ b/.chloggen/gcp-cloud-run-jobs-detector.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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: resourcedetectionprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Support GCP Cloud Run Jobs in resource detection processor. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [23681] + +# (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: diff --git a/processor/resourcedetectionprocessor/internal/gcp/gcp.go b/processor/resourcedetectionprocessor/internal/gcp/gcp.go index 0e9a5dc23072..6b9e0ac74eb1 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gcp.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gcp.go @@ -75,6 +75,15 @@ func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.FaaSID), d.rb.SetFromCallable(d.rb.SetCloudRegion, d.detector.FaaSCloudRegion), ) + case gcp.CloudRunJob: + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudRun) + errs = multierr.Combine(errs, + d.rb.SetFromCallable(d.rb.SetFaasName, d.detector.FaaSName), + d.rb.SetFromCallable(d.rb.SetCloudRegion, d.detector.FaaSCloudRegion), + d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.FaaSID), + d.rb.SetFromCallable(d.rb.SetGcpCloudRunJobExecution, d.detector.CloudRunJobExecution), + d.rb.SetFromCallable(d.rb.SetGcpCloudRunJobTaskIndex, d.detector.CloudRunJobTaskIndex), + ) case gcp.CloudFunctions: d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudFunctions) errs = multierr.Combine(errs, diff --git a/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go b/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go index ea52c8c49820..834daed8ca21 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go @@ -128,6 +128,28 @@ func TestDetect(t *testing.T) { conventions.AttributeFaaSID: "1472385723456792345", }, }, + { + desc: "Cloud Run Job", + detector: newTestDetector(&fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.CloudRunJob, + faaSID: "1472385723456792345", + faaSCloudRegion: "us-central1", + faaSName: "my-service", + gcpCloudRunJobExecution: "my-service-ajg89", + gcpCloudRunJobTaskIndex: "2", + }), + expectedResource: map[string]any{ + conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP, + conventions.AttributeCloudAccountID: "my-project", + conventions.AttributeCloudPlatform: conventions.AttributeCloudPlatformGCPCloudRun, + conventions.AttributeCloudRegion: "us-central1", + conventions.AttributeFaaSName: "my-service", + conventions.AttributeFaaSID: "1472385723456792345", + "gcp.cloud_run.job.execution": "my-service-ajg89", + "gcp.cloud_run.job.task_index": "2", + }, + }, { desc: "Cloud Functions", detector: newTestDetector(&fakeGCPDetector{ @@ -259,6 +281,8 @@ type fakeGCPDetector struct { gceHostID string gceHostName string gceHostNameErr error + gcpCloudRunJobExecution string + gcpCloudRunJobTaskIndex string } func (f *fakeGCPDetector) ProjectID() (string, error) { @@ -393,3 +417,17 @@ func (f *fakeGCPDetector) GCEHostName() (string, error) { } return f.gceHostName, f.gceHostNameErr } + +func (f *fakeGCPDetector) CloudRunJobTaskIndex() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gcpCloudRunJobTaskIndex, nil +} + +func (f *fakeGCPDetector) CloudRunJobExecution() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gcpCloudRunJobExecution, nil +} diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config.go b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config.go index 1182790753d5..f87d7deb17b0 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config.go +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config.go @@ -9,18 +9,20 @@ type ResourceAttributeConfig struct { // ResourceAttributesConfig provides config for resourcedetectionprocessor/gcp resource attributes. type ResourceAttributesConfig struct { - CloudAccountID ResourceAttributeConfig `mapstructure:"cloud.account.id"` - CloudAvailabilityZone ResourceAttributeConfig `mapstructure:"cloud.availability_zone"` - CloudPlatform ResourceAttributeConfig `mapstructure:"cloud.platform"` - CloudProvider ResourceAttributeConfig `mapstructure:"cloud.provider"` - CloudRegion ResourceAttributeConfig `mapstructure:"cloud.region"` - FaasID ResourceAttributeConfig `mapstructure:"faas.id"` - FaasName ResourceAttributeConfig `mapstructure:"faas.name"` - FaasVersion ResourceAttributeConfig `mapstructure:"faas.version"` - HostID ResourceAttributeConfig `mapstructure:"host.id"` - HostName ResourceAttributeConfig `mapstructure:"host.name"` - HostType ResourceAttributeConfig `mapstructure:"host.type"` - K8sClusterName ResourceAttributeConfig `mapstructure:"k8s.cluster.name"` + CloudAccountID ResourceAttributeConfig `mapstructure:"cloud.account.id"` + CloudAvailabilityZone ResourceAttributeConfig `mapstructure:"cloud.availability_zone"` + CloudPlatform ResourceAttributeConfig `mapstructure:"cloud.platform"` + CloudProvider ResourceAttributeConfig `mapstructure:"cloud.provider"` + CloudRegion ResourceAttributeConfig `mapstructure:"cloud.region"` + FaasID ResourceAttributeConfig `mapstructure:"faas.id"` + FaasName ResourceAttributeConfig `mapstructure:"faas.name"` + FaasVersion ResourceAttributeConfig `mapstructure:"faas.version"` + GcpCloudRunJobExecution ResourceAttributeConfig `mapstructure:"gcp.cloud_run.job.execution"` + GcpCloudRunJobTaskIndex ResourceAttributeConfig `mapstructure:"gcp.cloud_run.job.task_index"` + HostID ResourceAttributeConfig `mapstructure:"host.id"` + HostName ResourceAttributeConfig `mapstructure:"host.name"` + HostType ResourceAttributeConfig `mapstructure:"host.type"` + K8sClusterName ResourceAttributeConfig `mapstructure:"k8s.cluster.name"` } func DefaultResourceAttributesConfig() ResourceAttributesConfig { @@ -49,6 +51,12 @@ func DefaultResourceAttributesConfig() ResourceAttributesConfig { FaasVersion: ResourceAttributeConfig{ Enabled: true, }, + GcpCloudRunJobExecution: ResourceAttributeConfig{ + Enabled: true, + }, + GcpCloudRunJobTaskIndex: ResourceAttributeConfig{ + Enabled: true, + }, HostID: ResourceAttributeConfig{ Enabled: true, }, diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config_test.go b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config_test.go index 666b356c6f4e..9bf29c75f7c8 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_config_test.go @@ -25,35 +25,39 @@ func TestResourceAttributesConfig(t *testing.T) { { name: "all_set", want: ResourceAttributesConfig{ - CloudAccountID: ResourceAttributeConfig{Enabled: true}, - CloudAvailabilityZone: ResourceAttributeConfig{Enabled: true}, - CloudPlatform: ResourceAttributeConfig{Enabled: true}, - CloudProvider: ResourceAttributeConfig{Enabled: true}, - CloudRegion: ResourceAttributeConfig{Enabled: true}, - FaasID: ResourceAttributeConfig{Enabled: true}, - FaasName: ResourceAttributeConfig{Enabled: true}, - FaasVersion: ResourceAttributeConfig{Enabled: true}, - HostID: ResourceAttributeConfig{Enabled: true}, - HostName: ResourceAttributeConfig{Enabled: true}, - HostType: ResourceAttributeConfig{Enabled: true}, - K8sClusterName: ResourceAttributeConfig{Enabled: true}, + CloudAccountID: ResourceAttributeConfig{Enabled: true}, + CloudAvailabilityZone: ResourceAttributeConfig{Enabled: true}, + CloudPlatform: ResourceAttributeConfig{Enabled: true}, + CloudProvider: ResourceAttributeConfig{Enabled: true}, + CloudRegion: ResourceAttributeConfig{Enabled: true}, + FaasID: ResourceAttributeConfig{Enabled: true}, + FaasName: ResourceAttributeConfig{Enabled: true}, + FaasVersion: ResourceAttributeConfig{Enabled: true}, + GcpCloudRunJobExecution: ResourceAttributeConfig{Enabled: true}, + GcpCloudRunJobTaskIndex: ResourceAttributeConfig{Enabled: true}, + HostID: ResourceAttributeConfig{Enabled: true}, + HostName: ResourceAttributeConfig{Enabled: true}, + HostType: ResourceAttributeConfig{Enabled: true}, + K8sClusterName: ResourceAttributeConfig{Enabled: true}, }, }, { name: "none_set", want: ResourceAttributesConfig{ - CloudAccountID: ResourceAttributeConfig{Enabled: false}, - CloudAvailabilityZone: ResourceAttributeConfig{Enabled: false}, - CloudPlatform: ResourceAttributeConfig{Enabled: false}, - CloudProvider: ResourceAttributeConfig{Enabled: false}, - CloudRegion: ResourceAttributeConfig{Enabled: false}, - FaasID: ResourceAttributeConfig{Enabled: false}, - FaasName: ResourceAttributeConfig{Enabled: false}, - FaasVersion: ResourceAttributeConfig{Enabled: false}, - HostID: ResourceAttributeConfig{Enabled: false}, - HostName: ResourceAttributeConfig{Enabled: false}, - HostType: ResourceAttributeConfig{Enabled: false}, - K8sClusterName: ResourceAttributeConfig{Enabled: false}, + CloudAccountID: ResourceAttributeConfig{Enabled: false}, + CloudAvailabilityZone: ResourceAttributeConfig{Enabled: false}, + CloudPlatform: ResourceAttributeConfig{Enabled: false}, + CloudProvider: ResourceAttributeConfig{Enabled: false}, + CloudRegion: ResourceAttributeConfig{Enabled: false}, + FaasID: ResourceAttributeConfig{Enabled: false}, + FaasName: ResourceAttributeConfig{Enabled: false}, + FaasVersion: ResourceAttributeConfig{Enabled: false}, + GcpCloudRunJobExecution: ResourceAttributeConfig{Enabled: false}, + GcpCloudRunJobTaskIndex: ResourceAttributeConfig{Enabled: false}, + HostID: ResourceAttributeConfig{Enabled: false}, + HostName: ResourceAttributeConfig{Enabled: false}, + HostType: ResourceAttributeConfig{Enabled: false}, + K8sClusterName: ResourceAttributeConfig{Enabled: false}, }, }, } diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go index 45ef70e5e232..a1ebeade5377 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go @@ -77,6 +77,20 @@ func (rb *ResourceBuilder) SetFaasVersion(val string) { } } +// SetGcpCloudRunJobExecution sets provided value as "gcp.cloud_run.job.execution" attribute. +func (rb *ResourceBuilder) SetGcpCloudRunJobExecution(val string) { + if rb.config.GcpCloudRunJobExecution.Enabled { + rb.res.Attributes().PutStr("gcp.cloud_run.job.execution", val) + } +} + +// SetGcpCloudRunJobTaskIndex sets provided value as "gcp.cloud_run.job.task_index" attribute. +func (rb *ResourceBuilder) SetGcpCloudRunJobTaskIndex(val string) { + if rb.config.GcpCloudRunJobTaskIndex.Enabled { + rb.res.Attributes().PutStr("gcp.cloud_run.job.task_index", val) + } +} + // SetHostID sets provided value as "host.id" attribute. func (rb *ResourceBuilder) SetHostID(val string) { if rb.config.HostID.Enabled { diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource_test.go b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource_test.go index 0c4a21397c80..b8ef69d894ed 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource_test.go @@ -21,6 +21,8 @@ func TestResourceBuilder(t *testing.T) { rb.SetFaasID("faas.id-val") rb.SetFaasName("faas.name-val") rb.SetFaasVersion("faas.version-val") + rb.SetGcpCloudRunJobExecution("gcp.cloud_run.job.execution-val") + rb.SetGcpCloudRunJobTaskIndex("gcp.cloud_run.job.task_index-val") rb.SetHostID("host.id-val") rb.SetHostName("host.name-val") rb.SetHostType("host.type-val") @@ -31,9 +33,9 @@ func TestResourceBuilder(t *testing.T) { switch test { case "default": - assert.Equal(t, 12, res.Attributes().Len()) + assert.Equal(t, 14, res.Attributes().Len()) case "all_set": - assert.Equal(t, 12, res.Attributes().Len()) + assert.Equal(t, 14, res.Attributes().Len()) case "none_set": assert.Equal(t, 0, res.Attributes().Len()) return @@ -81,6 +83,16 @@ func TestResourceBuilder(t *testing.T) { if ok { assert.EqualValues(t, "faas.version-val", val.Str()) } + val, ok = res.Attributes().Get("gcp.cloud_run.job.execution") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "gcp.cloud_run.job.execution-val", val.Str()) + } + val, ok = res.Attributes().Get("gcp.cloud_run.job.task_index") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "gcp.cloud_run.job.task_index-val", val.Str()) + } val, ok = res.Attributes().Get("host.id") assert.True(t, ok) if ok { diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/testdata/config.yaml b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/testdata/config.yaml index da1950ccb8d1..20719e3a1d6b 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/testdata/config.yaml +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/testdata/config.yaml @@ -17,6 +17,10 @@ all_set: enabled: true faas.version: enabled: true + gcp.cloud_run.job.execution: + enabled: true + gcp.cloud_run.job.task_index: + enabled: true host.id: enabled: true host.name: @@ -43,6 +47,10 @@ none_set: enabled: false faas.version: enabled: false + gcp.cloud_run.job.execution: + enabled: false + gcp.cloud_run.job.task_index: + enabled: false host.id: enabled: false host.name: diff --git a/processor/resourcedetectionprocessor/internal/gcp/metadata.yaml b/processor/resourcedetectionprocessor/internal/gcp/metadata.yaml index 100feaff9685..7644389329f2 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/gcp/metadata.yaml @@ -50,4 +50,12 @@ resource_attributes: k8s.cluster.name: description: The k8s.cluster.name type: string + enabled: true + gcp.cloud_run.job.execution: + description: The Job execution name + type: string + enabled: true + gcp.cloud_run.job.task_index: + description: The Job execution task index + type: string enabled: true \ No newline at end of file diff --git a/processor/resourcedetectionprocessor/internal/gcp/types.go b/processor/resourcedetectionprocessor/internal/gcp/types.go index 6b57809e037d..5982425c160b 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/types.go +++ b/processor/resourcedetectionprocessor/internal/gcp/types.go @@ -29,4 +29,6 @@ type gcpDetector interface { GCEHostType() (string, error) GCEHostID() (string, error) GCEHostName() (string, error) + CloudRunJobExecution() (string, error) + CloudRunJobTaskIndex() (string, error) }