diff --git a/.chloggen/remove-prometheus-start-time-metric-config.yaml b/.chloggen/remove-prometheus-start-time-metric-config.yaml new file mode 100644 index 0000000000000..4993705768d53 --- /dev/null +++ b/.chloggen/remove-prometheus-start-time-metric-config.yaml @@ -0,0 +1,31 @@ +# Use this changelog template to create an entry for release notes. + +# 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. receiver/filelog) +component: receiver/prometheus + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Remove deprecated `use_start_time_metric` and `start_time_metric_regex` configuration options. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [44180] + +# (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: | + The `use_start_time_metric` and `start_time_metric_regex` configuration options have been removed after being deprecated in v0.142.0. + Users who have these options set in their configuration will experience collector startup failures after upgrading. + To migrate, remove these configuration options and use the `metricstarttime` processor instead for equivalent functionality. + +# 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: [user] + diff --git a/receiver/prometheusreceiver/README.md b/receiver/prometheusreceiver/README.md index 846098837cdf3..a4b7e86e0ff88 100644 --- a/receiver/prometheusreceiver/README.md +++ b/receiver/prometheusreceiver/README.md @@ -86,8 +86,6 @@ receivers: The prometheus receiver also supports additional top-level options: - **trim_metric_suffixes**: [**Experimental**] When set to true, this enables trimming unit and some counter type suffixes from metric names. For example, it would cause `singing_duration_seconds_total` to be trimmed to `singing_duration`. This can be useful when trying to restore the original metric names used in OpenTelemetry instrumentation. Defaults to false. -- **use_start_time_metric**: When set to true, this enables retrieving the start time of all counter metrics from the process_start_time_seconds metric. This is only correct if all counters on that endpoint started after the process start time, and the process is the only actor exporting the metric after the process started. It should not be used in "exporters" which export counters that may have started before the process itself. Use only if you know what you are doing, as this may result in incorrect rate calculations. Defaults to false. Deprecated; use metricstarttime processor instead. -- **start_time_metric_regex**: The regular expression for the start time metric, and is only applied when use_start_time_metric is enabled. Defaults to process_start_time_seconds. Deprecated; use metricstarttime processor instead. - **report_extra_scrape_metrics**: Extra Prometheus scrape metrics can be reported by setting this parameter to `true`. Deprecated; use the feature gate `receiver.prometheusreceiver.EnableReportExtraScrapeMetrics` instead. Example configuration: @@ -266,28 +264,10 @@ More info about querying `/api/v1/` and the data format that is returned can be "--feature-gates=receiver.prometheusreceiver.RemoveReportExtraScrapeMetricsConfig" ``` -- `receiver.prometheusreceiver.UseCreatedMetric`: Start time for Summary, Histogram - and Sum metrics can be retrieved from `_created` metrics. Currently, this behaviour - is disabled by default. To enable it, use the following feature gate option: - -```shell -"--feature-gates=receiver.prometheusreceiver.UseCreatedMetric" -``` - `receiver.prometheusreceiver.EnableCreatedTimestampZeroIngestion`: Enables the Prometheus feature flag [created-timestamps-zero-injection](https://prometheus.io/docs/prometheus/latest/feature_flags/#created-timestamps-zero-injection). Currently, this behaviour is disabled by default due to worse CPU performance with higher metric volumes. To enable it, use the following feature gate option: ```shell "--feature-gates=receiver.prometheusreceiver.EnableCreatedTimestampZeroIngestion" ``` -- `receiver.prometheusreceiver.UseCollectorStartTimeFallback`: enables using - the collector start time as the metric start time if the - process_start_time_seconds metric yields no result (for example if targets - expose no process_start_time_seconds metric). This is useful when the collector - start time is a good approximation of the process start time - for example in - serverless workloads when the collector is deployed as a sidecar. To enable it, - use the following feature gate option: - -```shell -"--feature-gates=receiver.prometheusreceiver.UseCollectorStartTimeFallback" -``` - `receiver.prometheusreceiver.EnableNativeHistograms` (Stable, enabled by default): Converts scraped native histogram metrics into OpenTelemetry exponential histograms. **Note:** You still need to configure `scrape_native_histograms: true` in your Prometheus scrape config to actually scrape native histograms. For more details consult the [Prometheus native histograms](#prometheus-native-histograms) section. diff --git a/receiver/prometheusreceiver/config.go b/receiver/prometheusreceiver/config.go index cf693a6344bb8..65bb1b9f744f6 100644 --- a/receiver/prometheusreceiver/config.go +++ b/receiver/prometheusreceiver/config.go @@ -29,16 +29,6 @@ import ( type Config struct { PrometheusConfig *PromConfig `mapstructure:"config"` TrimMetricSuffixes bool `mapstructure:"trim_metric_suffixes"` - // UseStartTimeMetric enables retrieving the start time of all counter metrics - // from the process_start_time_seconds metric. This is only correct if all counters on that endpoint - // started after the process start time, and the process is the only actor exporting the metric after - // the process started. It should not be used in "exporters" which export counters that may have - // started before the process itself. Use only if you know what you are doing, as this may result - // in incorrect rate calculations. - // - // Deprecated: use the metricstarttime processor instead. - UseStartTimeMetric bool `mapstructure:"use_start_time_metric"` - StartTimeMetricRegex string `mapstructure:"start_time_metric_regex"` // ReportExtraScrapeMetrics - enables reporting of additional metrics for Prometheus client like scrape_body_size_bytes // diff --git a/receiver/prometheusreceiver/config_test.go b/receiver/prometheusreceiver/config_test.go index 2f0b403d3b7a2..3a01e45aabfc6 100644 --- a/receiver/prometheusreceiver/config_test.go +++ b/receiver/prometheusreceiver/config_test.go @@ -52,9 +52,7 @@ func TestLoadConfig(t *testing.T) { r1 := cfg.(*Config) assert.Equal(t, "demo", r1.PrometheusConfig.ScrapeConfigs[0].JobName) assert.Equal(t, 5*time.Second, time.Duration(r1.PrometheusConfig.ScrapeConfigs[0].ScrapeInterval)) - assert.True(t, r1.UseStartTimeMetric) assert.True(t, r1.TrimMetricSuffixes) - assert.Equal(t, "^(.+_)*process_start_time_seconds$", r1.StartTimeMetricRegex) assert.True(t, r1.ReportExtraScrapeMetrics) ta := r1.TargetAllocator.Get() diff --git a/receiver/prometheusreceiver/go.mod b/receiver/prometheusreceiver/go.mod index 9b4cd648c780c..db75ba2ed9155 100644 --- a/receiver/prometheusreceiver/go.mod +++ b/receiver/prometheusreceiver/go.mod @@ -48,7 +48,6 @@ require ( go.uber.org/zap v1.27.1 go.uber.org/zap/exp v0.3.0 golang.org/x/net v0.48.0 - google.golang.org/protobuf v1.36.11 ) require ( @@ -309,6 +308,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect google.golang.org/grpc v1.78.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/receiver/prometheusreceiver/internal/appendable.go b/receiver/prometheusreceiver/internal/appendable.go index b0a7579b560bc..cf2c1097fde14 100644 --- a/receiver/prometheusreceiver/internal/appendable.go +++ b/receiver/prometheusreceiver/internal/appendable.go @@ -5,7 +5,6 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-co import ( "context" - "regexp" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/storage" @@ -16,12 +15,10 @@ import ( // appendable translates Prometheus scraping diffs into OpenTelemetry format. type appendable struct { - sink consumer.Metrics - useStartTimeMetric bool - useMetadata bool - trimSuffixes bool - startTimeMetricRegex *regexp.Regexp - externalLabels labels.Labels + sink consumer.Metrics + useMetadata bool + trimSuffixes bool + externalLabels labels.Labels settings receiver.Settings obsrecv *receiverhelper.ObsReport @@ -31,8 +28,6 @@ type appendable struct { func NewAppendable( sink consumer.Metrics, set receiver.Settings, - useStartTimeMetric bool, - startTimeMetricRegex *regexp.Regexp, useMetadata bool, externalLabels labels.Labels, trimSuffixes bool, @@ -43,14 +38,12 @@ func NewAppendable( } return &appendable{ - sink: sink, - settings: set, - useStartTimeMetric: useStartTimeMetric, - useMetadata: useMetadata, - startTimeMetricRegex: startTimeMetricRegex, - externalLabels: externalLabels, - obsrecv: obsrecv, - trimSuffixes: trimSuffixes, + sink: sink, + settings: set, + useMetadata: useMetadata, + externalLabels: externalLabels, + obsrecv: obsrecv, + trimSuffixes: trimSuffixes, }, nil } diff --git a/receiver/prometheusreceiver/metrics_receiver.go b/receiver/prometheusreceiver/metrics_receiver.go index ea1f171665897..55e2cdc90780a 100644 --- a/receiver/prometheusreceiver/metrics_receiver.go +++ b/receiver/prometheusreceiver/metrics_receiver.go @@ -12,7 +12,6 @@ import ( "net/url" "os" "reflect" - "regexp" "runtime" "runtime/debug" "strings" @@ -160,19 +159,9 @@ func (r *pReceiver) initPrometheusComponents(ctx context.Context, logger *slog.L } }() - var startTimeMetricRegex *regexp.Regexp - if r.cfg.StartTimeMetricRegex != "" { - startTimeMetricRegex, err = regexp.Compile(r.cfg.StartTimeMetricRegex) - if err != nil { - return err - } - } - store, err := internal.NewAppendable( r.consumer, r.settings, - r.cfg.UseStartTimeMetric, - startTimeMetricRegex, !r.cfg.ignoreMetadata, r.cfg.PrometheusConfig.GlobalConfig.ExternalLabels, r.cfg.TrimMetricSuffixes, diff --git a/receiver/prometheusreceiver/metrics_receiver_helper_test.go b/receiver/prometheusreceiver/metrics_receiver_helper_test.go index 6f16fa422ed80..d4c02bdea1d6c 100644 --- a/receiver/prometheusreceiver/metrics_receiver_helper_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_helper_test.go @@ -776,8 +776,7 @@ func testComponent(t *testing.T, targets []*testData, alterConfig func(*Config), defer mp.Close() config := &Config{ - PrometheusConfig: cfg, - StartTimeMetricRegex: "", + PrometheusConfig: cfg, } if alterConfig != nil { alterConfig(config) diff --git a/receiver/prometheusreceiver/metrics_receiver_report_extra_scrape_metrics_test.go b/receiver/prometheusreceiver/metrics_receiver_report_extra_scrape_metrics_test.go index 5da14dc2f60b9..ee37642fff833 100644 --- a/receiver/prometheusreceiver/metrics_receiver_report_extra_scrape_metrics_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_report_extra_scrape_metrics_test.go @@ -58,9 +58,7 @@ func testScraperMetrics(t *testing.T, targets []*testData, reportExtraScrapeMetr cms := new(consumertest.MetricsSink) receiver, err := newPrometheusReceiver(receivertest.NewNopSettings(metadata.Type), &Config{ - PrometheusConfig: cfg, - UseStartTimeMetric: false, - StartTimeMetricRegex: "", + PrometheusConfig: cfg, }, cms) require.NoError(t, err, "Failed to create Prometheus receiver: %v", err) diff --git a/receiver/prometheusreceiver/metrics_receiver_target_allocator_test.go b/receiver/prometheusreceiver/metrics_receiver_target_allocator_test.go index dee7bcdd6532b..90d09e7f4c195 100644 --- a/receiver/prometheusreceiver/metrics_receiver_target_allocator_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_target_allocator_test.go @@ -65,8 +65,7 @@ func TestTargetAllocatorProvidesEmptyScrapeConfig(t *testing.T) { require.NoError(t, err) config := &Config{ - PrometheusConfig: (*PromConfig)(pCfg), - StartTimeMetricRegex: "", + PrometheusConfig: (*PromConfig)(pCfg), TargetAllocator: configoptional.Some(targetallocator.Config{ ClientConfig: confighttp.ClientConfig{ Endpoint: tas.srv.URL, diff --git a/receiver/prometheusreceiver/metrics_receiver_test.go b/receiver/prometheusreceiver/metrics_receiver_test.go index ce85cb5697d0a..5fb32cc3ef68f 100644 --- a/receiver/prometheusreceiver/metrics_receiver_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_test.go @@ -21,7 +21,6 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver/receivertest" - "google.golang.org/protobuf/types/known/timestamppb" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal/metadata" ) @@ -1469,132 +1468,6 @@ func TestCoreMetricsEndToEnd(t *testing.T) { testComponent(t, targets, nil) } -var startTimeMetricPage = ` -# HELP go_threads Number of OS threads created -# TYPE go_threads gauge -go_threads 19 -# HELP http_requests_total The total number of HTTP requests. -# TYPE http_requests_total counter -http_requests_total{method="post",code="200"} 100 -http_requests_total{method="post",code="400"} 5 -# HELP http_request_duration_seconds A histogram of the request duration. -# TYPE http_request_duration_seconds histogram -http_request_duration_seconds_bucket{le="0.05"} 1000 -http_request_duration_seconds_bucket{le="0.5"} 1500 -http_request_duration_seconds_bucket{le="1"} 2000 -http_request_duration_seconds_bucket{le="+Inf"} 2500 -http_request_duration_seconds_sum 5000 -http_request_duration_seconds_count 2500 -# HELP rpc_duration_seconds A summary of the RPC duration in seconds. -# TYPE rpc_duration_seconds summary -rpc_duration_seconds{quantile="0.01"} 1 -rpc_duration_seconds{quantile="0.9"} 5 -rpc_duration_seconds{quantile="0.99"} 8 -rpc_duration_seconds_sum 5000 -rpc_duration_seconds_count 1000 -# HELP process_start_time_seconds Start time of the process since unix epoch in seconds. -# TYPE process_start_time_seconds gauge -process_start_time_seconds 400.8 -` - -var startTimeMetricPageStartTimestamp = ×tamppb.Timestamp{Seconds: 400, Nanos: 800000000} - -// 6 metrics + 5 internal metrics -const numStartTimeMetricPageTimeseries = 11 - -func verifyStartTimeMetricPage(t *testing.T, td *testData, result []pmetric.ResourceMetrics) { - verifyNumValidScrapeResults(t, td, result) - numTimeseries := 0 - for _, rm := range result { - metrics := getMetrics(rm) - for i := range metrics { - timestamp := startTimeMetricPageStartTimestamp - switch metrics[i].Type() { - case pmetric.MetricTypeGauge: - timestamp = nil - for j := 0; j < metrics[i].Gauge().DataPoints().Len(); j++ { - time := metrics[i].Gauge().DataPoints().At(j).StartTimestamp() - assert.Equal(t, timestamp.AsTime(), time.AsTime()) - numTimeseries++ - } - - case pmetric.MetricTypeSum: - for j := 0; j < metrics[i].Sum().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), metrics[i].Sum().DataPoints().At(j).StartTimestamp().AsTime()) - numTimeseries++ - } - - case pmetric.MetricTypeHistogram: - for j := 0; j < metrics[i].Histogram().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), metrics[i].Histogram().DataPoints().At(j).StartTimestamp().AsTime()) - numTimeseries++ - } - - case pmetric.MetricTypeSummary: - for j := 0; j < metrics[i].Summary().DataPoints().Len(); j++ { - assert.Equal(t, timestamp.AsTime(), metrics[i].Summary().DataPoints().At(j).StartTimestamp().AsTime()) - numTimeseries++ - } - case pmetric.MetricTypeEmpty, pmetric.MetricTypeExponentialHistogram: - } - } - assert.Equal(t, numStartTimeMetricPageTimeseries, numTimeseries) - } -} - -var startTimeMetricRegexPage = ` -# HELP go_threads Number of OS threads created -# TYPE go_threads gauge -go_threads 19 -# HELP http_requests_total The total number of HTTP requests. -# TYPE http_requests_total counter -http_requests_total{method="post",code="200"} 100 -http_requests_total{method="post",code="400"} 5 -# HELP http_request_duration_seconds A histogram of the request duration. -# TYPE http_request_duration_seconds histogram -http_request_duration_seconds_bucket{le="0.05"} 1000 -http_request_duration_seconds_bucket{le="0.5"} 1500 -http_request_duration_seconds_bucket{le="1"} 2000 -http_request_duration_seconds_bucket{le="+Inf"} 2500 -http_request_duration_seconds_sum 5000 -http_request_duration_seconds_count 2500 -# HELP rpc_duration_seconds A summary of the RPC duration in seconds. -# TYPE rpc_duration_seconds summary -rpc_duration_seconds{quantile="0.01"} 1 -rpc_duration_seconds{quantile="0.9"} 5 -rpc_duration_seconds{quantile="0.99"} 8 -rpc_duration_seconds_sum 5000 -rpc_duration_seconds_count 1000 -# HELP example_process_start_time_seconds Start time of the process since unix epoch in seconds. -# TYPE example_process_start_time_seconds gauge -example_process_start_time_seconds 400.8 -` - -// TestStartTimeMetricRegex validates that timeseries have start time regex set to 'process_start_time_seconds' -func TestStartTimeMetricRegex(t *testing.T) { - t.Skip("Skipping test since it is flaky, see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/42684.") - targets := []*testData{ - { - name: "target1", - pages: []mockPrometheusResponse{ - {code: 200, data: startTimeMetricRegexPage}, - }, - validateFunc: verifyStartTimeMetricPage, - }, - { - name: "target2", - pages: []mockPrometheusResponse{ - {code: 200, data: startTimeMetricPage}, - }, - validateFunc: verifyStartTimeMetricPage, - }, - } - testComponent(t, targets, func(c *Config) { - c.StartTimeMetricRegex = "^(.+_)*process_start_time_seconds$" - c.UseStartTimeMetric = true - }) -} - // metric type is defined as 'untyped' in the first metric // and, type hint is missing in the 2nd metric var untypedMetrics = ` diff --git a/receiver/prometheusreceiver/testdata/config.yaml b/receiver/prometheusreceiver/testdata/config.yaml index 860ceb6e6774b..8a7eea0c2b970 100644 --- a/receiver/prometheusreceiver/testdata/config.yaml +++ b/receiver/prometheusreceiver/testdata/config.yaml @@ -1,8 +1,6 @@ prometheus: prometheus/customname: trim_metric_suffixes: true - use_start_time_metric: true - start_time_metric_regex: '^(.+_)*process_start_time_seconds$' report_extra_scrape_metrics: true target_allocator: endpoint: http://my-targetallocator-service diff --git a/receiver/prometheusreceiver/testdata/config_scrape_config_files.yaml b/receiver/prometheusreceiver/testdata/config_scrape_config_files.yaml index 271a289334625..f11ddcc75e5c6 100644 --- a/receiver/prometheusreceiver/testdata/config_scrape_config_files.yaml +++ b/receiver/prometheusreceiver/testdata/config_scrape_config_files.yaml @@ -1,7 +1,5 @@ prometheus: trim_metric_suffixes: true - use_start_time_metric: true - start_time_metric_regex: '^(.+_)*process_start_time_seconds$' report_extra_scrape_metrics: true config: scrape_config_files: diff --git a/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml b/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml index 4ed0892f10b2c..5ec2c92806338 100644 --- a/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml +++ b/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml @@ -1,6 +1,4 @@ prometheus: - use_start_time_metric: true - start_time_metric_regex: '^(.+_)*process_start_time_seconds$' config: scrape_configs: - job_name: 'demo'