Skip to content
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
17 changes: 17 additions & 0 deletions .chloggen/feat_5075-promote-telemetry-shape-beta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
component: collector

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Promote the operator.collector.usedefaulttelemetryshape feature gate to beta. The operator-injected Prometheus telemetry reader now uses collector defaults by default — metric names from operator-managed collectors no longer carry type suffixes, units, or scope_info.

# One or more tracking issues related to the change
issues: [5075]

# (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: |
Users wanting the pre-v0.154.0 metric name shape can disable the gate via --feature-gates=-operator.collector.usedefaulttelemetryshape, or pin without_type_suffix/without_units/without_scope_info to false explicitly under spec.config.service.telemetry. The gate will be promoted to stable and removed in a future release.
8 changes: 4 additions & 4 deletions internal/otelconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,10 +496,10 @@ func ServiceApplyDefaults(s *v1beta1.Service, logger logr.Logger) ([]v1beta1.Eve
}

// AddPrometheusMetricsEndpoint creates a MetricReader with a Prometheus pull exporter.
// without_type_suffix/without_units/without_scope_info are explicitly set to false to
// preserve the historical metric name shape produced by operator-managed collectors
// before open-telemetry/opentelemetry-collector#15027. Opt into collector defaults via
// the operator.collector.usedefaulttelemetryshape feature gate. See issue #5075.
// By default (operator.collector.usedefaulttelemetryshape beta gate enabled) the
// reader carries no overrides, so the collector's defaults for without_type_suffix,
// without_units, and without_scope_info apply. Disabling the gate explicitly sets
// all three to false to preserve the pre-v0.154.0 metric name shape. See #5075.
func AddPrometheusMetricsEndpoint(host string, port int32) otelConfig.MetricReader {
portInt := int(port)
prom := &otelConfig.Prometheus{
Expand Down
58 changes: 33 additions & 25 deletions internal/otelconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1488,11 +1488,8 @@ func TestTelemetryLogsPreservedWithMetrics(t *testing.T) {
"pull": map[string]any{
"exporter": map[string]any{
"prometheus": map[string]any{
"host": "0.0.0.0",
"port": int32(8888),
"without_type_suffix": false,
"without_units": false,
"without_scope_info": false,
"host": "0.0.0.0",
"port": int32(8888),
},
},
},
Expand Down Expand Up @@ -1551,38 +1548,49 @@ func TestTelemetryIncompleteConfigAppliesDefaults(t *testing.T) {
require.NotNil(t, telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus)
require.Equal(t, "0.0.0.0", *telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.Host)
require.Equal(t, 8888, *telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.Port)
require.Equal(t, false, *telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.Equal(t, false, *telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutUnits)
require.Equal(t, false, *telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutScopeInfo)
require.Nil(t, telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.Nil(t, telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutUnits)
require.Nil(t, telemetry.Metrics.Readers[0].Pull.Exporter.Prometheus.WithoutScopeInfo)
}

func TestAddPrometheusMetricsEndpointPreservesShape(t *testing.T) {
// withTelemetryShapeGate temporarily flips the operator.collector.usedefaulttelemetryshape
// gate to the given value for the duration of the test and restores it on cleanup.
func withTelemetryShapeGate(t *testing.T, enabled bool) {
t.Helper()
registry := colfeaturegate.GlobalRegistry()
original := featuregate.UseCollectorDefaultTelemetryShape.IsEnabled()
require.NoError(t, registry.Set(featuregate.UseCollectorDefaultTelemetryShape.ID(), enabled))
t.Cleanup(func() {
require.NoError(t, registry.Set(featuregate.UseCollectorDefaultTelemetryShape.ID(), original))
})
}

// Default behavior (beta gate enabled): the injected reader carries no shape overrides,
// so the collector's defaults apply.
func TestAddPrometheusMetricsEndpointUsesCollectorDefaultsByDefault(t *testing.T) {
reader := AddPrometheusMetricsEndpoint("0.0.0.0", 8888)
require.NotNil(t, reader.Pull)
require.NotNil(t, reader.Pull.Exporter.Prometheus)
require.Equal(t, "0.0.0.0", *reader.Pull.Exporter.Prometheus.Host)
require.Equal(t, 8888, *reader.Pull.Exporter.Prometheus.Port)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.Equal(t, false, *reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutUnits)
require.Equal(t, false, *reader.Pull.Exporter.Prometheus.WithoutUnits)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
require.Equal(t, false, *reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutUnits)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
}

func TestAddPrometheusMetricsEndpointGateUsesCollectorDefaults(t *testing.T) {
registry := colfeaturegate.GlobalRegistry()
originalVal := featuregate.UseCollectorDefaultTelemetryShape.IsEnabled()
require.NoError(t, registry.Set(featuregate.UseCollectorDefaultTelemetryShape.ID(), true))
t.Cleanup(func() {
require.NoError(t, registry.Set(featuregate.UseCollectorDefaultTelemetryShape.ID(), originalVal))
})
// Opt-out behavior: when the gate is disabled, the operator pins all three
// fields to false to preserve the pre-v0.154.0 metric name shape.
func TestAddPrometheusMetricsEndpointPreservesShapeWhenGateDisabled(t *testing.T) {
withTelemetryShapeGate(t, false)

reader := AddPrometheusMetricsEndpoint("0.0.0.0", 8888)
require.NotNil(t, reader.Pull.Exporter.Prometheus)
require.Equal(t, "0.0.0.0", *reader.Pull.Exporter.Prometheus.Host)
require.Equal(t, 8888, *reader.Pull.Exporter.Prometheus.Port)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutUnits)
require.Nil(t, reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.False(t, *reader.Pull.Exporter.Prometheus.WithoutTypeSuffix)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutUnits)
require.False(t, *reader.Pull.Exporter.Prometheus.WithoutUnits)
require.NotNil(t, reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
require.False(t, *reader.Pull.Exporter.Prometheus.WithoutScopeInfo)
}
2 changes: 1 addition & 1 deletion internal/webhook/collector_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func TestCollectorDefaultingWebhook(t *testing.T) {
Mode: v1beta1.ModeDeployment,
UpgradeStrategy: v1beta1.UpgradeStrategyAutomatic,
Config: func() v1beta1.Config {
const input = `{"receivers":{"otlp":{"protocols":{"grpc":{"endpoint":"0.0.0.0:4317"},"http":{"endpoint":"0.0.0.0:4318"}}}},"exporters":{"debug":null},"service":{"telemetry":{"metrics":{"readers":[{"pull":{"exporter":{"prometheus":{"host":"0.0.0.0","port":8888,"without_scope_info":false,"without_type_suffix":false,"without_units":false}}}}]}},"pipelines":{"traces":{"receivers":["otlp"],"exporters":["debug"]}}}}`
const input = `{"receivers":{"otlp":{"protocols":{"grpc":{"endpoint":"0.0.0.0:4317"},"http":{"endpoint":"0.0.0.0:4318"}}}},"exporters":{"debug":null},"service":{"telemetry":{"metrics":{"readers":[{"pull":{"exporter":{"prometheus":{"host":"0.0.0.0","port":8888}}}}]}},"pipelines":{"traces":{"receivers":["otlp"],"exporters":["debug"]}}}}`
var cfg v1beta1.Config
require.NoError(t, go_yaml.Unmarshal([]byte(input), &cfg))
// This is a workaround to avoid the type mismatch because how go-yaml unmarshals
Expand Down
7 changes: 2 additions & 5 deletions pkg/collector/upgrade/v0_122_0_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,8 @@ func TestUpgrade0_122_0(t *testing.T) {
"pull": map[string]any{
"exporter": map[string]any{
"prometheus": map[string]any{
"host": "0.0.0.0",
"port": int32(8888),
"without_scope_info": false,
"without_type_suffix": false,
"without_units": false,
"host": "0.0.0.0",
"port": int32(8888),
},
},
},
Expand Down
14 changes: 8 additions & 6 deletions pkg/featuregate/featuregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ var (
featuregate.WithRegisterDescription("enables the ClusterObservability controller for managed observability deployment"),
featuregate.WithRegisterFromVersion("v0.134.0"),
)
// UseCollectorDefaultTelemetryShape, when enabled, makes the operator-injected
// Prometheus telemetry reader use collector defaults for without_type_suffix,
// without_units, and without_scope_info. When disabled (default), the operator
// explicitly sets all three to false to preserve historical metric name shape.
// UseCollectorDefaultTelemetryShape, when enabled (default at beta), makes
// the operator-injected Prometheus telemetry reader use collector defaults
// for without_type_suffix, without_units, and without_scope_info — metric
// names emitted by operator-managed collectors no longer carry type
// suffixes, units, or scope_info. When disabled, the operator explicitly
// sets all three to false to preserve the pre-v0.154.0 metric name shape.
// See open-telemetry/opentelemetry-operator#5075.
UseCollectorDefaultTelemetryShape = featuregate.GlobalRegistry().MustRegister(
"operator.collector.usedefaulttelemetryshape",
featuregate.StageAlpha,
featuregate.WithRegisterDescription("when enabled, the operator-injected Prometheus telemetry reader uses collector defaults for without_type_suffix/without_units/without_scope_info. When disabled (default), the operator explicitly sets all three to false to preserve historical metric name shape."),
featuregate.StageBeta,
featuregate.WithRegisterDescription("when enabled (default), the operator-injected Prometheus telemetry reader uses collector defaults for without_type_suffix/without_units/without_scope_info. When disabled, the operator explicitly sets all three to false to preserve the pre-v0.154.0 metric name shape."),
featuregate.WithRegisterFromVersion("v0.152.0"),
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
kind: ConfigMap
metadata:
labels:
Expand All @@ -65,7 +62,7 @@ metadata:
app.kubernetes.io/managed-by: opentelemetry-operator
app.kubernetes.io/name: stateful-collector
app.kubernetes.io/part-of: opentelemetry
name: stateful-collector-cbacb1a5
name: stateful-collector-95bef721
namespace: chainsaw-must-gather
---
apiVersion: v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
kind: ConfigMap
metadata:
(starts_with(name, 'prometheus-cr-collector-')): true
Expand Down
3 changes: 0 additions & 3 deletions tests/e2e-ta-collector-mtls/ta-disabled/00-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
pipelines:
traces:
exporters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
pipelines:
metrics:
exporters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
---
apiVersion: v1
data:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
---
apiVersion: v1
data:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
---
apiVersion: apps/v1
kind: DaemonSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
kind: ConfigMap
metadata:
labels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,4 @@ spec:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
pipelines: {}
3 changes: 0 additions & 3 deletions tests/e2e/managed-reconcile/02-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
pipelines:
traces:
exporters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ spec:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
extensions:
- health_check
pipelines:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ spec:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
extensions:
- health_check
pipelines:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ spec:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
extensions:
- health_check
pipelines:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ data:
prometheus:
host: 0.0.0.0
port: 8888
without_scope_info: false
without_type_suffix: false
without_units: false
kind: ConfigMap
metadata:
(starts_with(name, 'stateful-collector-')): true
4 changes: 2 additions & 2 deletions tests/e2e/versioned-configmaps/00-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ spec:
volumes:
- name: otc-internal
configMap:
name: simple-collector-713de77b
name: simple-collector-5723ff27
status:
readyReplicas: 1
---
apiVersion: v1
kind: ConfigMap
metadata:
name: simple-collector-713de77b
name: simple-collector-5723ff27
6 changes: 3 additions & 3 deletions tests/e2e/versioned-configmaps/01-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ spec:
volumes:
- name: otc-internal
configMap:
name: simple-collector-726b4c75
name: simple-collector-dfcfaead
status:
readyReplicas: 1
---
apiVersion: v1
kind: ConfigMap
metadata:
name: simple-collector-726b4c75
name: simple-collector-dfcfaead
---
apiVersion: v1
kind: ConfigMap
metadata:
name: simple-collector-713de77b
name: simple-collector-5723ff27
8 changes: 4 additions & 4 deletions tests/step-templates/validate-collector-metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ spec:
($error == null): true
- assert:
resource:
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_spans_total'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_spans_total'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_metric_points_total'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_metric_points_total'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_spans'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_spans'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_metric_points'].value | [0] > `1`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_metric_points'].value | [0] > `1`): true
catch:
- podLogs:
selector: ($catchPodLabelSelector)
Expand Down
4 changes: 2 additions & 2 deletions tests/step-templates/validate-collector-spans.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ spec:
($error == null): true
- assert:
resource:
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_spans_total'].value | [0] > `0`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_spans_total'].value | [0] > `0`): true
($metrics[?as_string(metric."__name__") == 'otelcol_exporter_sent_spans'].value | [0] > `0`): true
($metrics[?as_string(metric."__name__") == 'otelcol_receiver_accepted_spans'].value | [0] > `0`): true
catch:
- podLogs:
selector: ($catchPodLabelSelector)
Expand Down
Loading