From 68f98011a90714f6fec104e46b7d5d63cb4f633c Mon Sep 17 00:00:00 2001 From: odubajDT Date: Tue, 9 Dec 2025 07:11:11 +0100 Subject: [PATCH 1/7] [processor/k8sattributes] introduce new observability metric Signed-off-by: odubajDT --- ...ributesprocessor-stable-observability.yaml | 27 +++++++++++ .../k8sattributesprocessor/documentation.md | 15 ++++++ processor/k8sattributesprocessor/factory.go | 7 +++ .../internal/metadata/generated_telemetry.go | 7 +++ .../metadatatest/generated_telemetrytest.go | 16 +++++++ .../generated_telemetrytest_test.go | 4 ++ .../k8sattributesprocessor/metadata.yaml | 27 +++++++++++ processor/k8sattributesprocessor/processor.go | 47 ++++++++++++++++--- 8 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 .chloggen/k8sattributesprocessor-stable-observability.yaml diff --git a/.chloggen/k8sattributesprocessor-stable-observability.yaml b/.chloggen/k8sattributesprocessor-stable-observability.yaml new file mode 100644 index 0000000000000..c62dd766eedb6 --- /dev/null +++ b/.chloggen/k8sattributesprocessor-stable-observability.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: processor/k8sattributes + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Added processor-specific observability metrics: `otelsvc_k8s_pod_association` with `k8s_telemetry_type` and `status` attributes for signal and type differentiation" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [44587] + +# (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/processor/k8sattributesprocessor/documentation.md b/processor/k8sattributesprocessor/documentation.md index 4f0d52eddb063..1bb0a6eaef55c 100644 --- a/processor/k8sattributesprocessor/documentation.md +++ b/processor/k8sattributesprocessor/documentation.md @@ -105,6 +105,21 @@ Number of pod add events received [Development] | ---- | ----------- | ---------- | --------- | --------- | | 1 | Sum | Int | true | Development | +### otelcol_otelsvc_k8s_pod_association + +Number of pod associations [Development] + +| Unit | Metric Type | Value Type | Monotonic | Stability | +| ---- | ----------- | ---------- | --------- | --------- | +| {resources} | Sum | Int | true | Development | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| k8s_telemetry_type | The type of telemetry data being processed (traces, metrics, logs, profiles) | Str: ``traces``, ``metrics``, ``logs``, ``profiles`` | +| status | The status of the pod association operation | Str: ``success``, ``error`` | + ### otelcol_otelsvc_k8s_pod_deleted Number of pod delete events received [Development] diff --git a/processor/k8sattributesprocessor/factory.go b/processor/k8sattributesprocessor/factory.go index 351f429d1c8c4..d6a9107035bd4 100644 --- a/processor/k8sattributesprocessor/factory.go +++ b/processor/k8sattributesprocessor/factory.go @@ -14,6 +14,7 @@ import ( "go.opentelemetry.io/collector/processor/processorhelper" "go.opentelemetry.io/collector/processor/processorhelper/xprocessorhelper" "go.opentelemetry.io/collector/processor/xprocessor" + "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor/internal/kube" @@ -171,11 +172,17 @@ func createKubernetesProcessor( cfg component.Config, options ...option, ) *kubernetesprocessor { + telemetry, err := metadata.NewTelemetryBuilder(params.TelemetrySettings) + if err != nil { + params.Logger.Error("failed to create telemetry builder", zap.Error(err)) + } + kp := &kubernetesprocessor{ logger: params.Logger, cfg: cfg, options: options, telemetrySettings: params.TelemetrySettings, + telemetry: telemetry, } return kp diff --git a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go index 398c9c2a1c0d7..97f72ae5d2a31 100644 --- a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go +++ b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go @@ -42,6 +42,7 @@ type TelemetryBuilder struct { OtelsvcK8sNodeDeleted metric.Int64Counter OtelsvcK8sNodeUpdated metric.Int64Counter OtelsvcK8sPodAdded metric.Int64Counter + OtelsvcK8sPodAssociation metric.Int64Counter OtelsvcK8sPodDeleted metric.Int64Counter OtelsvcK8sPodTableSize metric.Int64Gauge OtelsvcK8sPodUpdated metric.Int64Counter @@ -184,6 +185,12 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme metric.WithUnit("1"), ) errs = errors.Join(errs, err) + builder.OtelsvcK8sPodAssociation, err = builder.meter.Int64Counter( + "otelcol_otelsvc_k8s_pod_association", + metric.WithDescription("Number of pod associations [Development]"), + metric.WithUnit("{resources}"), + ) + errs = errors.Join(errs, err) builder.OtelsvcK8sPodDeleted, err = builder.meter.Int64Counter( "otelcol_otelsvc_k8s_pod_deleted", metric.WithDescription("Number of pod delete events received [Development]"), diff --git a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go index d24438b42d02f..61839a8850480 100644 --- a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go +++ b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go @@ -293,6 +293,22 @@ func AssertEqualOtelsvcK8sPodAdded(t *testing.T, tt *componenttest.Telemetry, dp metricdatatest.AssertEqual(t, want, got, opts...) } +func AssertEqualOtelsvcK8sPodAssociation(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_otelsvc_k8s_pod_association", + Description: "Number of pod associations [Development]", + Unit: "{resources}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_otelsvc_k8s_pod_association") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualOtelsvcK8sPodDeleted(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_otelsvc_k8s_pod_deleted", diff --git a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go index 76f1d8f01d40c..c1e55399416ed 100644 --- a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go +++ b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go @@ -36,6 +36,7 @@ func TestSetupTelemetry(t *testing.T) { tb.OtelsvcK8sNodeDeleted.Add(context.Background(), 1) tb.OtelsvcK8sNodeUpdated.Add(context.Background(), 1) tb.OtelsvcK8sPodAdded.Add(context.Background(), 1) + tb.OtelsvcK8sPodAssociation.Add(context.Background(), 1) tb.OtelsvcK8sPodDeleted.Add(context.Background(), 1) tb.OtelsvcK8sPodTableSize.Record(context.Background(), 1) tb.OtelsvcK8sPodUpdated.Add(context.Background(), 1) @@ -96,6 +97,9 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualOtelsvcK8sPodAdded(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) + AssertEqualOtelsvcK8sPodAssociation(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualOtelsvcK8sPodDeleted(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index 9be811d8d60b2..aff885fc1ceac 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -148,6 +148,22 @@ tests: goleak: skip: true +attributes: + k8s_telemetry_type: + description: The type of telemetry data being processed (traces, metrics, logs, profiles) + type: string + enum: + - traces + - metrics + - logs + - profiles + status: + description: The status of the pod association operation + type: string + enum: + - success + - error + telemetry: metrics: otelsvc_k8s_daemonset_added: @@ -303,6 +319,16 @@ telemetry: sum: value_type: int monotonic: true + otelsvc_k8s_pod_association: + enabled: true + description: Number of pod associations + stability: + level: development + unit: "{resources}" + attributes: [k8s_telemetry_type, status] + sum: + value_type: int + monotonic: true otelsvc_k8s_pod_deleted: enabled: true description: Number of pod delete events received @@ -383,3 +409,4 @@ telemetry: sum: value_type: int monotonic: true + diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index d505749b01092..f9c2153d4dac5 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -16,11 +16,14 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" conventions "go.opentelemetry.io/otel/semconv/v1.39.0" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor/internal/kube" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor/internal/metadata" ) const ( @@ -31,6 +34,7 @@ type kubernetesprocessor struct { cfg component.Config options []option telemetrySettings component.TelemetrySettings + telemetry *metadata.TelemetryBuilder logger *zap.Logger apiConfig k8sconfig.APIConfig kc kube.Client @@ -88,6 +92,9 @@ func (kp *kubernetesprocessor) Start(_ context.Context, host component.Host) err } func (kp *kubernetesprocessor) Shutdown(context.Context) error { + if kp.telemetry != nil { + kp.telemetry.Shutdown() + } if kp.kc == nil { return nil } @@ -101,7 +108,7 @@ func (kp *kubernetesprocessor) Shutdown(context.Context) error { func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Traces) (ptrace.Traces, error) { rss := td.ResourceSpans() for i := 0; i < rss.Len(); i++ { - kp.processResource(ctx, rss.At(i).Resource()) + kp.processResource(ctx, rss.At(i).Resource(), "traces") } return td, nil @@ -111,7 +118,7 @@ func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Trac func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Metrics) (pmetric.Metrics, error) { rm := md.ResourceMetrics() for i := 0; i < rm.Len(); i++ { - kp.processResource(ctx, rm.At(i).Resource()) + kp.processResource(ctx, rm.At(i).Resource(), "metrics") } return md, nil @@ -121,7 +128,7 @@ func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Me func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (plog.Logs, error) { rl := ld.ResourceLogs() for i := 0; i < rl.Len(); i++ { - kp.processResource(ctx, rl.At(i).Resource()) + kp.processResource(ctx, rl.At(i).Resource(), "logs") } return ld, nil @@ -131,14 +138,14 @@ func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (p func (kp *kubernetesprocessor) processProfiles(ctx context.Context, pd pprofile.Profiles) (pprofile.Profiles, error) { rp := pd.ResourceProfiles() for i := 0; i < rp.Len(); i++ { - kp.processResource(ctx, rp.At(i).Resource()) + kp.processResource(ctx, rp.At(i).Resource(), "profiles") } return pd, nil } // processResource adds Pod metadata tags to resource based on pod association configuration -func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource) { +func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource, signalType string) { podIdentifierValue := extractPodID(ctx, resource.Attributes(), kp.podAssociations) kp.logger.Debug("evaluating pod identifier", zap.Any("value", podIdentifierValue)) @@ -155,17 +162,45 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco } var pod *kube.Pod + var podFound bool if podIdentifierValue.IsNotEmpty() { - var podFound bool if pod, podFound = kp.kc.GetPod(podIdentifierValue); podFound { kp.logger.Debug("getting the pod", zap.Any("pod", pod)) + // Record successful pod association + if kp.telemetry != nil { + successAttr := metric.WithAttributes( + attribute.String("k8s_telemetry_type", signalType), + attribute.String("status", "success"), + ) + kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, successAttr) + } + for key, val := range pod.Attributes { setResourceAttribute(resource.Attributes(), key, val) } kp.addContainerAttributes(resource.Attributes(), pod) } else { kp.logger.Debug("unable to find pod based on identifier", zap.Any("value", podIdentifierValue)) + // Record failed pod association + kp.logger.Debug("pod not found", zap.Any("podIdentifier", podIdentifierValue)) + if kp.telemetry != nil { + errorAttr := metric.WithAttributes( + attribute.String("k8s_telemetry_type", signalType), + attribute.String("status", "error"), + ) + kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, errorAttr) + } + } + } else if !podIdentifierValue.IsNotEmpty() { + // Record failed pod association when no identifier found + kp.logger.Debug("no pod identifier found", zap.String("signal_type", signalType)) + if kp.telemetry != nil { + errorAttr := metric.WithAttributes( + attribute.String("k8s_telemetry_type", signalType), + attribute.String("status", "error"), + ) + kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, errorAttr) } } From eda2c125bc4af6b51c993885434355566a4cadcc Mon Sep 17 00:00:00 2001 From: odubajDT Date: Thu, 11 Dec 2025 06:26:26 +0100 Subject: [PATCH 2/7] rename according to semconv Signed-off-by: odubajDT --- ...ributesprocessor-stable-observability.yaml | 2 +- .../k8sattributesprocessor/documentation.md | 15 --------- .../internal/metadata/generated_telemetry.go | 14 ++++---- .../metadatatest/generated_telemetrytest.go | 32 +++++++++---------- .../generated_telemetrytest_test.go | 8 ++--- .../k8sattributesprocessor/metadata.yaml | 21 ++++++------ processor/k8sattributesprocessor/processor.go | 6 ++-- 7 files changed, 41 insertions(+), 57 deletions(-) diff --git a/.chloggen/k8sattributesprocessor-stable-observability.yaml b/.chloggen/k8sattributesprocessor-stable-observability.yaml index c62dd766eedb6..ac7155be83fa0 100644 --- a/.chloggen/k8sattributesprocessor-stable-observability.yaml +++ b/.chloggen/k8sattributesprocessor-stable-observability.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: processor/k8sattributes # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "Added processor-specific observability metrics: `otelsvc_k8s_pod_association` with `k8s_telemetry_type` and `status` attributes for signal and type differentiation" +note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `k8s_telemetry_type` and `status` attributes for signal and type differentiation" # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [44587] diff --git a/processor/k8sattributesprocessor/documentation.md b/processor/k8sattributesprocessor/documentation.md index 1bb0a6eaef55c..4f0d52eddb063 100644 --- a/processor/k8sattributesprocessor/documentation.md +++ b/processor/k8sattributesprocessor/documentation.md @@ -105,21 +105,6 @@ Number of pod add events received [Development] | ---- | ----------- | ---------- | --------- | --------- | | 1 | Sum | Int | true | Development | -### otelcol_otelsvc_k8s_pod_association - -Number of pod associations [Development] - -| Unit | Metric Type | Value Type | Monotonic | Stability | -| ---- | ----------- | ---------- | --------- | --------- | -| {resources} | Sum | Int | true | Development | - -#### Attributes - -| Name | Description | Values | -| ---- | ----------- | ------ | -| k8s_telemetry_type | The type of telemetry data being processed (traces, metrics, logs, profiles) | Str: ``traces``, ``metrics``, ``logs``, ``profiles`` | -| status | The status of the pod association operation | Str: ``success``, ``error`` | - ### otelcol_otelsvc_k8s_pod_deleted Number of pod delete events received [Development] diff --git a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go index 97f72ae5d2a31..5d85dc0706fe0 100644 --- a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go +++ b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go @@ -25,6 +25,7 @@ type TelemetryBuilder struct { meter metric.Meter mu sync.Mutex registrations []metric.Registration + OtelcolK8sPodAssociation metric.Int64Counter OtelsvcK8sDaemonsetAdded metric.Int64Counter OtelsvcK8sDaemonsetDeleted metric.Int64Counter OtelsvcK8sDaemonsetUpdated metric.Int64Counter @@ -42,7 +43,6 @@ type TelemetryBuilder struct { OtelsvcK8sNodeDeleted metric.Int64Counter OtelsvcK8sNodeUpdated metric.Int64Counter OtelsvcK8sPodAdded metric.Int64Counter - OtelsvcK8sPodAssociation metric.Int64Counter OtelsvcK8sPodDeleted metric.Int64Counter OtelsvcK8sPodTableSize metric.Int64Gauge OtelsvcK8sPodUpdated metric.Int64Counter @@ -83,6 +83,12 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme } builder.meter = Meter(settings) var err, errs error + builder.OtelcolK8sPodAssociation, err = builder.meter.Int64Counter( + "otelcol_otelcol.k8s.pod.association", + metric.WithDescription("Number of pod associations [Development]"), + metric.WithUnit("{resources}"), + ) + errs = errors.Join(errs, err) builder.OtelsvcK8sDaemonsetAdded, err = builder.meter.Int64Counter( "otelcol_otelsvc_k8s_daemonset_added", metric.WithDescription("Number of daemonset add events received [Development]"), @@ -185,12 +191,6 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme metric.WithUnit("1"), ) errs = errors.Join(errs, err) - builder.OtelsvcK8sPodAssociation, err = builder.meter.Int64Counter( - "otelcol_otelsvc_k8s_pod_association", - metric.WithDescription("Number of pod associations [Development]"), - metric.WithUnit("{resources}"), - ) - errs = errors.Join(errs, err) builder.OtelsvcK8sPodDeleted, err = builder.meter.Int64Counter( "otelcol_otelsvc_k8s_pod_deleted", metric.WithDescription("Number of pod delete events received [Development]"), diff --git a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go index 61839a8850480..f70380807af42 100644 --- a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go +++ b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go @@ -21,6 +21,22 @@ func NewSettings(tt *componenttest.Telemetry) processor.Settings { return set } +func AssertEqualOtelcolK8sPodAssociation(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { + want := metricdata.Metrics{ + Name: "otelcol_otelcol.k8s.pod.association", + Description: "Number of pod associations [Development]", + Unit: "{resources}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: dps, + }, + } + got, err := tt.GetMetric("otelcol_otelcol.k8s.pod.association") + require.NoError(t, err) + metricdatatest.AssertEqual(t, want, got, opts...) +} + func AssertEqualOtelsvcK8sDaemonsetAdded(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_otelsvc_k8s_daemonset_added", @@ -293,22 +309,6 @@ func AssertEqualOtelsvcK8sPodAdded(t *testing.T, tt *componenttest.Telemetry, dp metricdatatest.AssertEqual(t, want, got, opts...) } -func AssertEqualOtelsvcK8sPodAssociation(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { - want := metricdata.Metrics{ - Name: "otelcol_otelsvc_k8s_pod_association", - Description: "Number of pod associations [Development]", - Unit: "{resources}", - Data: metricdata.Sum[int64]{ - Temporality: metricdata.CumulativeTemporality, - IsMonotonic: true, - DataPoints: dps, - }, - } - got, err := tt.GetMetric("otelcol_otelsvc_k8s_pod_association") - require.NoError(t, err) - metricdatatest.AssertEqual(t, want, got, opts...) -} - func AssertEqualOtelsvcK8sPodDeleted(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_otelsvc_k8s_pod_deleted", diff --git a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go index c1e55399416ed..42a5b4e10b0b0 100644 --- a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go +++ b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest_test.go @@ -19,6 +19,7 @@ func TestSetupTelemetry(t *testing.T) { tb, err := metadata.NewTelemetryBuilder(testTel.NewTelemetrySettings()) require.NoError(t, err) defer tb.Shutdown() + tb.OtelcolK8sPodAssociation.Add(context.Background(), 1) tb.OtelsvcK8sDaemonsetAdded.Add(context.Background(), 1) tb.OtelsvcK8sDaemonsetDeleted.Add(context.Background(), 1) tb.OtelsvcK8sDaemonsetUpdated.Add(context.Background(), 1) @@ -36,7 +37,6 @@ func TestSetupTelemetry(t *testing.T) { tb.OtelsvcK8sNodeDeleted.Add(context.Background(), 1) tb.OtelsvcK8sNodeUpdated.Add(context.Background(), 1) tb.OtelsvcK8sPodAdded.Add(context.Background(), 1) - tb.OtelsvcK8sPodAssociation.Add(context.Background(), 1) tb.OtelsvcK8sPodDeleted.Add(context.Background(), 1) tb.OtelsvcK8sPodTableSize.Record(context.Background(), 1) tb.OtelsvcK8sPodUpdated.Add(context.Background(), 1) @@ -46,6 +46,9 @@ func TestSetupTelemetry(t *testing.T) { tb.OtelsvcK8sStatefulsetAdded.Add(context.Background(), 1) tb.OtelsvcK8sStatefulsetDeleted.Add(context.Background(), 1) tb.OtelsvcK8sStatefulsetUpdated.Add(context.Background(), 1) + AssertEqualOtelcolK8sPodAssociation(t, testTel, + []metricdata.DataPoint[int64]{{Value: 1}}, + metricdatatest.IgnoreTimestamp()) AssertEqualOtelsvcK8sDaemonsetAdded(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) @@ -97,9 +100,6 @@ func TestSetupTelemetry(t *testing.T) { AssertEqualOtelsvcK8sPodAdded(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) - AssertEqualOtelsvcK8sPodAssociation(t, testTel, - []metricdata.DataPoint[int64]{{Value: 1}}, - metricdatatest.IgnoreTimestamp()) AssertEqualOtelsvcK8sPodDeleted(t, testTel, []metricdata.DataPoint[int64]{{Value: 1}}, metricdatatest.IgnoreTimestamp()) diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index aff885fc1ceac..2a2973f154046 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -166,6 +166,16 @@ attributes: telemetry: metrics: + otelcol.k8s.pod.association: + enabled: false + description: Number of pod associations + stability: + level: development + unit: "{resources}" + attributes: [k8s_telemetry_type, status] + sum: + value_type: int + monotonic: true otelsvc_k8s_daemonset_added: enabled: false description: Number of daemonset add events received @@ -319,16 +329,6 @@ telemetry: sum: value_type: int monotonic: true - otelsvc_k8s_pod_association: - enabled: true - description: Number of pod associations - stability: - level: development - unit: "{resources}" - attributes: [k8s_telemetry_type, status] - sum: - value_type: int - monotonic: true otelsvc_k8s_pod_deleted: enabled: true description: Number of pod delete events received @@ -409,4 +409,3 @@ telemetry: sum: value_type: int monotonic: true - diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index f9c2153d4dac5..e949c0df02902 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -173,7 +173,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "success"), ) - kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, successAttr) + kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, successAttr) } for key, val := range pod.Attributes { @@ -189,7 +189,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "error"), ) - kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, errorAttr) + kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } } } else if !podIdentifierValue.IsNotEmpty() { @@ -200,7 +200,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "error"), ) - kp.telemetry.OtelsvcK8sPodAssociation.Add(ctx, 1, errorAttr) + kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } } From 1a2e69dea31cac8a0d486e3f752e8b0021f5b72e Mon Sep 17 00:00:00 2001 From: odubajDT Date: Thu, 11 Dec 2025 06:41:41 +0100 Subject: [PATCH 3/7] pr review Signed-off-by: odubajDT --- ...ributesprocessor-stable-observability.yaml | 2 +- .../internal/metadata/generated_telemetry.go | 2 +- .../metadatatest/generated_telemetrytest.go | 2 +- .../k8sattributesprocessor/metadata.yaml | 12 ++-------- processor/k8sattributesprocessor/processor.go | 24 +++++++++++++++---- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/.chloggen/k8sattributesprocessor-stable-observability.yaml b/.chloggen/k8sattributesprocessor-stable-observability.yaml index ac7155be83fa0..e95f91be40b5b 100644 --- a/.chloggen/k8sattributesprocessor-stable-observability.yaml +++ b/.chloggen/k8sattributesprocessor-stable-observability.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: processor/k8sattributes # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `k8s_telemetry_type` and `status` attributes for signal and type differentiation" +note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `status` attribute for type differentiation" # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [44587] diff --git a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go index 5d85dc0706fe0..1d28d4a5699ef 100644 --- a/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go +++ b/processor/k8sattributesprocessor/internal/metadata/generated_telemetry.go @@ -85,7 +85,7 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...Teleme var err, errs error builder.OtelcolK8sPodAssociation, err = builder.meter.Int64Counter( "otelcol_otelcol.k8s.pod.association", - metric.WithDescription("Number of pod associations [Development]"), + metric.WithDescription("Number of pod associations' evaluations [Development]"), metric.WithUnit("{resources}"), ) errs = errors.Join(errs, err) diff --git a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go index f70380807af42..0a1a0c056c00d 100644 --- a/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go +++ b/processor/k8sattributesprocessor/internal/metadatatest/generated_telemetrytest.go @@ -24,7 +24,7 @@ func NewSettings(tt *componenttest.Telemetry) processor.Settings { func AssertEqualOtelcolK8sPodAssociation(t *testing.T, tt *componenttest.Telemetry, dps []metricdata.DataPoint[int64], opts ...metricdatatest.Option) { want := metricdata.Metrics{ Name: "otelcol_otelcol.k8s.pod.association", - Description: "Number of pod associations [Development]", + Description: "Number of pod associations' evaluations [Development]", Unit: "{resources}", Data: metricdata.Sum[int64]{ Temporality: metricdata.CumulativeTemporality, diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index 2a2973f154046..b42fa39d93da8 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -149,14 +149,6 @@ tests: skip: true attributes: - k8s_telemetry_type: - description: The type of telemetry data being processed (traces, metrics, logs, profiles) - type: string - enum: - - traces - - metrics - - logs - - profiles status: description: The status of the pod association operation type: string @@ -168,11 +160,11 @@ telemetry: metrics: otelcol.k8s.pod.association: enabled: false - description: Number of pod associations + description: Number of pod associations' evaluations stability: level: development unit: "{resources}" - attributes: [k8s_telemetry_type, status] + attributes: [status] sum: value_type: int monotonic: true diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index e949c0df02902..6cc3a5260685e 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "strconv" + "strings" "time" "go.opentelemetry.io/collector/component" @@ -163,6 +164,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco var pod *kube.Pod var podFound bool + podIdentifierStr := buildPodIdentifierString(podIdentifierValue) if podIdentifierValue.IsNotEmpty() { if pod, podFound = kp.kc.GetPod(podIdentifierValue); podFound { kp.logger.Debug("getting the pod", zap.Any("pod", pod)) @@ -170,8 +172,8 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco // Record successful pod association if kp.telemetry != nil { successAttr := metric.WithAttributes( - attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "success"), + attribute.String("pod_identifier", podIdentifierStr), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, successAttr) } @@ -186,19 +188,19 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco kp.logger.Debug("pod not found", zap.Any("podIdentifier", podIdentifierValue)) if kp.telemetry != nil { errorAttr := metric.WithAttributes( - attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "error"), + attribute.String("pod_identifier", podIdentifierStr), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } } - } else if !podIdentifierValue.IsNotEmpty() { + } else { // Record failed pod association when no identifier found kp.logger.Debug("no pod identifier found", zap.String("signal_type", signalType)) if kp.telemetry != nil { errorAttr := metric.WithAttributes( - attribute.String("k8s_telemetry_type", signalType), attribute.String("status", "error"), + attribute.String("pod_identifier", podIdentifierStr), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } @@ -442,6 +444,20 @@ func (kp *kubernetesprocessor) getUIDForPodsNode(nodeName string) string { return node.NodeUID } +// buildPodIdentifierString combines all identifier values into a comma-separated string +func buildPodIdentifierString(podIdentifierValue kube.PodIdentifier) string { + var identifiers []string + for i := range podIdentifierValue { + if podIdentifierValue[i].Value != "" { + identifiers = append(identifiers, podIdentifierValue[i].Value) + } + } + if len(identifiers) > 0 { + return strings.Join(identifiers, ",") + } + return "unknown" +} + // intFromAttribute extracts int value from an attribute stored as string or int func intFromAttribute(val pcommon.Value) (int, error) { switch val.Type() { From 848b555cb506e6fcae81e493b2b195aa3af596bd Mon Sep 17 00:00:00 2001 From: odubajDT Date: Thu, 11 Dec 2025 06:44:27 +0100 Subject: [PATCH 4/7] polish Signed-off-by: odubajDT --- processor/k8sattributesprocessor/processor.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index 6cc3a5260685e..533577ca12237 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -109,7 +109,7 @@ func (kp *kubernetesprocessor) Shutdown(context.Context) error { func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Traces) (ptrace.Traces, error) { rss := td.ResourceSpans() for i := 0; i < rss.Len(); i++ { - kp.processResource(ctx, rss.At(i).Resource(), "traces") + kp.processResource(ctx, rss.At(i).Resource()) } return td, nil @@ -119,7 +119,7 @@ func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Trac func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Metrics) (pmetric.Metrics, error) { rm := md.ResourceMetrics() for i := 0; i < rm.Len(); i++ { - kp.processResource(ctx, rm.At(i).Resource(), "metrics") + kp.processResource(ctx, rm.At(i).Resource()) } return md, nil @@ -129,7 +129,7 @@ func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Me func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (plog.Logs, error) { rl := ld.ResourceLogs() for i := 0; i < rl.Len(); i++ { - kp.processResource(ctx, rl.At(i).Resource(), "logs") + kp.processResource(ctx, rl.At(i).Resource()) } return ld, nil @@ -139,14 +139,14 @@ func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (p func (kp *kubernetesprocessor) processProfiles(ctx context.Context, pd pprofile.Profiles) (pprofile.Profiles, error) { rp := pd.ResourceProfiles() for i := 0; i < rp.Len(); i++ { - kp.processResource(ctx, rp.At(i).Resource(), "profiles") + kp.processResource(ctx, rp.At(i).Resource()) } return pd, nil } // processResource adds Pod metadata tags to resource based on pod association configuration -func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource, signalType string) { +func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource) { podIdentifierValue := extractPodID(ctx, resource.Attributes(), kp.podAssociations) kp.logger.Debug("evaluating pod identifier", zap.Any("value", podIdentifierValue)) @@ -196,7 +196,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco } } else { // Record failed pod association when no identifier found - kp.logger.Debug("no pod identifier found", zap.String("signal_type", signalType)) + kp.logger.Debug("no pod identifier found") if kp.telemetry != nil { errorAttr := metric.WithAttributes( attribute.String("status", "error"), From 3f54fcb9cb2170a4513feed43ab394877bd52b43 Mon Sep 17 00:00:00 2001 From: odubajDT Date: Thu, 11 Dec 2025 06:52:25 +0100 Subject: [PATCH 5/7] add pod_identifier attribute Signed-off-by: odubajDT --- .chloggen/k8sattributesprocessor-stable-observability.yaml | 2 +- processor/k8sattributesprocessor/metadata.yaml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.chloggen/k8sattributesprocessor-stable-observability.yaml b/.chloggen/k8sattributesprocessor-stable-observability.yaml index e95f91be40b5b..5c6258c01d4d6 100644 --- a/.chloggen/k8sattributesprocessor-stable-observability.yaml +++ b/.chloggen/k8sattributesprocessor-stable-observability.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: processor/k8sattributes # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `status` attribute for type differentiation" +note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `status` and `pod_identifier` attributes for tracking pod association success/failures" # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [44587] diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index b42fa39d93da8..d73a82785dfff 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -149,6 +149,9 @@ tests: skip: true attributes: + pod_identifier: + description: The pod identifier value(s) used for the association attempt + type: string status: description: The status of the pod association operation type: string @@ -164,7 +167,7 @@ telemetry: stability: level: development unit: "{resources}" - attributes: [status] + attributes: [status, pod_identifier] sum: value_type: int monotonic: true From 41865fd3afaa65be9cdb28701c5f1e6e0ed65456 Mon Sep 17 00:00:00 2001 From: odubajDT Date: Thu, 11 Dec 2025 11:43:54 +0100 Subject: [PATCH 6/7] add signal type attributes Signed-off-by: odubajDT --- ...k8sattributesprocessor-stable-observability.yaml | 2 +- processor/k8sattributesprocessor/metadata.yaml | 10 +++++++++- processor/k8sattributesprocessor/processor.go | 13 ++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.chloggen/k8sattributesprocessor-stable-observability.yaml b/.chloggen/k8sattributesprocessor-stable-observability.yaml index 5c6258c01d4d6..6e20d9c085300 100644 --- a/.chloggen/k8sattributesprocessor-stable-observability.yaml +++ b/.chloggen/k8sattributesprocessor-stable-observability.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: processor/k8sattributes # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `status` and `pod_identifier` attributes for tracking pod association success/failures" +note: "Added processor-specific observability metrics: `otelcol.k8s.pod.association` with `status`, `pod_identifier`, and `otelcol.signal` attributes" # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [44587] diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index d73a82785dfff..a6e016e773515 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -149,6 +149,14 @@ tests: skip: true attributes: + otelcol.signal: + description: The signal type the telemetry metric is associated with + type: string + enum: + - metrics + - traces + - logs + - profiles pod_identifier: description: The pod identifier value(s) used for the association attempt type: string @@ -167,7 +175,7 @@ telemetry: stability: level: development unit: "{resources}" - attributes: [status, pod_identifier] + attributes: [status, pod_identifier, otelcol.signal] sum: value_type: int monotonic: true diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index 533577ca12237..ddad984d8a983 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -109,7 +109,7 @@ func (kp *kubernetesprocessor) Shutdown(context.Context) error { func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Traces) (ptrace.Traces, error) { rss := td.ResourceSpans() for i := 0; i < rss.Len(); i++ { - kp.processResource(ctx, rss.At(i).Resource()) + kp.processResource(ctx, rss.At(i).Resource(), "traces") } return td, nil @@ -119,7 +119,7 @@ func (kp *kubernetesprocessor) processTraces(ctx context.Context, td ptrace.Trac func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Metrics) (pmetric.Metrics, error) { rm := md.ResourceMetrics() for i := 0; i < rm.Len(); i++ { - kp.processResource(ctx, rm.At(i).Resource()) + kp.processResource(ctx, rm.At(i).Resource(), "metrics") } return md, nil @@ -129,7 +129,7 @@ func (kp *kubernetesprocessor) processMetrics(ctx context.Context, md pmetric.Me func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (plog.Logs, error) { rl := ld.ResourceLogs() for i := 0; i < rl.Len(); i++ { - kp.processResource(ctx, rl.At(i).Resource()) + kp.processResource(ctx, rl.At(i).Resource(), "logs") } return ld, nil @@ -139,14 +139,14 @@ func (kp *kubernetesprocessor) processLogs(ctx context.Context, ld plog.Logs) (p func (kp *kubernetesprocessor) processProfiles(ctx context.Context, pd pprofile.Profiles) (pprofile.Profiles, error) { rp := pd.ResourceProfiles() for i := 0; i < rp.Len(); i++ { - kp.processResource(ctx, rp.At(i).Resource()) + kp.processResource(ctx, rp.At(i).Resource(), "profiles") } return pd, nil } // processResource adds Pod metadata tags to resource based on pod association configuration -func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource) { +func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pcommon.Resource, signalType string) { podIdentifierValue := extractPodID(ctx, resource.Attributes(), kp.podAssociations) kp.logger.Debug("evaluating pod identifier", zap.Any("value", podIdentifierValue)) @@ -174,6 +174,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco successAttr := metric.WithAttributes( attribute.String("status", "success"), attribute.String("pod_identifier", podIdentifierStr), + attribute.String("otelcol.signal", signalType), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, successAttr) } @@ -190,6 +191,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco errorAttr := metric.WithAttributes( attribute.String("status", "error"), attribute.String("pod_identifier", podIdentifierStr), + attribute.String("otelcol.signal", signalType), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } @@ -201,6 +203,7 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco errorAttr := metric.WithAttributes( attribute.String("status", "error"), attribute.String("pod_identifier", podIdentifierStr), + attribute.String("otelcol.signal", signalType), ) kp.telemetry.OtelcolK8sPodAssociation.Add(ctx, 1, errorAttr) } From 794725b32f21dbe13e428b3b3882c7e67d9508ee Mon Sep 17 00:00:00 2001 From: odubajDT Date: Tue, 27 Jan 2026 15:43:37 +0100 Subject: [PATCH 7/7] fix after rebase Signed-off-by: odubajDT --- processor/k8sattributesprocessor/processor.go | 1 - 1 file changed, 1 deletion(-) diff --git a/processor/k8sattributesprocessor/processor.go b/processor/k8sattributesprocessor/processor.go index ddad984d8a983..b037f15280a68 100644 --- a/processor/k8sattributesprocessor/processor.go +++ b/processor/k8sattributesprocessor/processor.go @@ -184,7 +184,6 @@ func (kp *kubernetesprocessor) processResource(ctx context.Context, resource pco } kp.addContainerAttributes(resource.Attributes(), pod) } else { - kp.logger.Debug("unable to find pod based on identifier", zap.Any("value", podIdentifierValue)) // Record failed pod association kp.logger.Debug("pod not found", zap.Any("podIdentifier", podIdentifierValue)) if kp.telemetry != nil {