From 08386c233a57d5f586faf9a24af43afc8bb47e6d Mon Sep 17 00:00:00 2001 From: Dmitry Anoshin Date: Wed, 7 Jun 2023 15:20:49 -0700 Subject: [PATCH] [pkg/translator/prometheus] Switch `NormalizeName` FG back to alpha Disable `pkg.translator.prometheus.NormalizeName` feature gate by default The feature gate `pkg.translator.prometheus.NormalizeName` was enabled prematurely while translation on the prometheus receiver was incomplete. To address this, the feature gate has been reverted back to alpha status. This will remain the case until the translation on the receiver side aligns with the translation on the exporter side, or until it is replaced with a configuration option or completely removed. To maintain the current behavior, you can enable the feature gate using the `--feature-gates=pkg.translator.prometheus.NormalizeName` command argument. However, please note that the translation in the prometheus receiver is a subject to future changes. --- .../set-prom-feature-gate-back-to-aplpha.yaml | 22 ++++++ exporter/prometheusexporter/collector_test.go | 3 +- .../prometheusexporter/prometheus_test.go | 72 +++++++++--------- pkg/translator/prometheus/README.md | 4 +- pkg/translator/prometheus/normalize_name.go | 2 +- .../prometheus/normalize_name_test.go | 10 +-- .../number_data_points_test.go | 6 +- .../metrics_receiver_helper_test.go | 39 ++++++---- .../metrics_receiver_honor_timestamp_test.go | 22 +++--- ...ics_receiver_metric_name_normalize_test.go | 5 +- .../metrics_receiver_non_numerical_test.go | 14 ++-- .../metrics_receiver_test.go | 73 +++++++++++-------- .../metrics_reciever_metric_rename_test.go | 42 +++++------ 13 files changed, 180 insertions(+), 134 deletions(-) create mode 100644 .chloggen/set-prom-feature-gate-back-to-aplpha.yaml diff --git a/.chloggen/set-prom-feature-gate-back-to-aplpha.yaml b/.chloggen/set-prom-feature-gate-back-to-aplpha.yaml new file mode 100644 index 000000000000..65f641e7bffd --- /dev/null +++ b/.chloggen/set-prom-feature-gate-back-to-aplpha.yaml @@ -0,0 +1,22 @@ +# 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. filelogreceiver) +component: prometheusreceiver, prometheusexporter, prometheusremotewrite + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Disable `pkg.translator.prometheus.NormalizeName` feature gate by default + +# One or more tracking issues related to the change +issues: [23208] + +# (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 feature gate `pkg.translator.prometheus.NormalizeName` was enabled prematurely while translation + on the prometheus receiver was incomplete. To address this, the feature gate has been reverted back to alpha status. + This will remain the case until the translation on the receiver side aligns with the translation on the exporter side, + or until it is replaced with a configuration option or completely removed. To maintain the current behavior, you can + enable the feature gate using the `--feature-gates=pkg.translator.prometheus.NormalizeName` command argument. + However, please note that the translation in the prometheus receiver is a subject to future changes. diff --git a/exporter/prometheusexporter/collector_test.go b/exporter/prometheusexporter/collector_test.go index 6d0d895e2f28..3cabb957e6b0 100644 --- a/exporter/prometheusexporter/collector_test.go +++ b/exporter/prometheusexporter/collector_test.go @@ -448,6 +448,7 @@ func TestCollectMetrics(t *testing.T) { continue } + require.Contains(t, m.Desc().String(), "fqName: \"test_space_test_metric\"") require.Regexp(t, `variableLabels: \[.*label_1.+label_2.+job.+instance.*\]`, m.Desc().String()) pbMetric := io_prometheus_client.Metric{} @@ -466,13 +467,11 @@ func TestCollectMetrics(t *testing.T) { switch tt.metricType { case prometheus.CounterValue: - require.Contains(t, m.Desc().String(), "fqName: \"test_space_test_metric_total\"") require.Equal(t, tt.value, *pbMetric.Counter.Value) require.Nil(t, pbMetric.Gauge) require.Nil(t, pbMetric.Histogram) require.Nil(t, pbMetric.Summary) case prometheus.GaugeValue: - require.Contains(t, m.Desc().String(), "fqName: \"test_space_test_metric\"") require.Equal(t, tt.value, *pbMetric.Gauge.Value) require.Nil(t, pbMetric.Counter) require.Nil(t, pbMetric.Histogram) diff --git a/exporter/prometheusexporter/prometheus_test.go b/exporter/prometheusexporter/prometheus_test.go index 3193bf92259e..c1478d7d2512 100644 --- a/exporter/prometheusexporter/prometheus_test.go +++ b/exporter/prometheusexporter/prometheus_test.go @@ -160,10 +160,10 @@ func TestPrometheusExporter_WithTLS(t *testing.T) { _ = rsp.Body.Close() want := []string{ - `# HELP test_counter_int_total`, - `# TYPE test_counter_int_total counter`, - `test_counter_int_total{code2="one2",foo2="bar2",label_1="label-value-1",resource_attr="resource-attr-val-1"} 123 1581452773000`, - `test_counter_int_total{code2="one2",foo2="bar2",label_2="label-value-2",resource_attr="resource-attr-val-1"} 456 1581452773000`, + `# HELP test_counter_int`, + `# TYPE test_counter_int counter`, + `test_counter_int{code2="one2",foo2="bar2",label_1="label-value-1",resource_attr="resource-attr-val-1"} 123 1581452773000`, + `test_counter_int{code2="one2",foo2="bar2",label_2="label-value-2",resource_attr="resource-attr-val-1"} 456 1581452773000`, } for _, w := range want { @@ -220,18 +220,18 @@ func TestPrometheusExporter_endToEndMultipleTargets(t *testing.T) { blob, _ := io.ReadAll(res.Body) _ = res.Body.Close() want := []string{ - `# HELP test_metric_1_this_one_there_where_total Extra ones`, - `# TYPE test_metric_1_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+128), - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+128), - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="windows"} %v`, 99+128), - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="linux"} %v`, 100+128), - `# HELP test_metric_2_this_one_there_where_total Extra ones`, - `# TYPE test_metric_2_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+delta), - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+delta), - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="windows"} %v`, 99+delta), - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="linux"} %v`, 100+delta), + `# HELP test_metric_1_this_one_there_where Extra ones`, + `# TYPE test_metric_1_this_one_there_where counter`, + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+128), + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+128), + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="windows"} %v`, 99+128), + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="linux"} %v`, 100+128), + `# HELP test_metric_2_this_one_there_where Extra ones`, + `# TYPE test_metric_2_this_one_there_where counter`, + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+delta), + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+delta), + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="windows"} %v`, 99+delta), + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8081",job="cpu-exporter",os="linux"} %v`, 100+delta), } for _, w := range want { @@ -300,14 +300,14 @@ func TestPrometheusExporter_endToEnd(t *testing.T) { blob, _ := io.ReadAll(res.Body) _ = res.Body.Close() want := []string{ - `# HELP test_metric_1_this_one_there_where_total Extra ones`, - `# TYPE test_metric_1_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+128), - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+128), - `# HELP test_metric_2_this_one_there_where_total Extra ones`, - `# TYPE test_metric_2_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+delta), - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+delta), + `# HELP test_metric_1_this_one_there_where Extra ones`, + `# TYPE test_metric_1_this_one_there_where counter`, + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+128), + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+128), + `# HELP test_metric_2_this_one_there_where Extra ones`, + `# TYPE test_metric_2_this_one_there_where counter`, + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="windows"} %v`, 99+delta), + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code1="one1",foo1="bar1",instance="localhost:8080",job="cpu-exporter",os="linux"} %v`, 100+delta), } for _, w := range want { @@ -377,14 +377,14 @@ func TestPrometheusExporter_endToEndWithTimestamps(t *testing.T) { blob, _ := io.ReadAll(res.Body) _ = res.Body.Close() want := []string{ - `# HELP test_metric_1_this_one_there_where_total Extra ones`, - `# TYPE test_metric_1_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="windows"} %v %v`, 99+128, 1543160298100+128000), - fmt.Sprintf(`test_metric_1_this_one_there_where_total{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="linux"} %v %v`, 100+128, 1543160298100), - `# HELP test_metric_2_this_one_there_where_total Extra ones`, - `# TYPE test_metric_2_this_one_there_where_total counter`, - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="windows"} %v %v`, 99+delta, 1543160298100+delta*1000), - fmt.Sprintf(`test_metric_2_this_one_there_where_total{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="linux"} %v %v`, 100+delta, 1543160298100), + `# HELP test_metric_1_this_one_there_where Extra ones`, + `# TYPE test_metric_1_this_one_there_where counter`, + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="windows"} %v %v`, 99+128, 1543160298100+128000), + fmt.Sprintf(`test_metric_1_this_one_there_where{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="linux"} %v %v`, 100+128, 1543160298100), + `# HELP test_metric_2_this_one_there_where Extra ones`, + `# TYPE test_metric_2_this_one_there_where counter`, + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="windows"} %v %v`, 99+delta, 1543160298100+delta*1000), + fmt.Sprintf(`test_metric_2_this_one_there_where{arch="x86",code2="one2",foo2="bar2",instance="localhost:8080",job="node-exporter",os="linux"} %v %v`, 100+delta, 1543160298100), } for _, w := range want { @@ -457,10 +457,10 @@ func TestPrometheusExporter_endToEndWithResource(t *testing.T) { _ = rsp.Body.Close() want := []string{ - `# HELP test_counter_int_total`, - `# TYPE test_counter_int_total counter`, - `test_counter_int_total{code2="one2",foo2="bar2",label_1="label-value-1",resource_attr="resource-attr-val-1"} 123 1581452773000`, - `test_counter_int_total{code2="one2",foo2="bar2",label_2="label-value-2",resource_attr="resource-attr-val-1"} 456 1581452773000`, + `# HELP test_counter_int`, + `# TYPE test_counter_int counter`, + `test_counter_int{code2="one2",foo2="bar2",label_1="label-value-1",resource_attr="resource-attr-val-1"} 123 1581452773000`, + `test_counter_int{code2="one2",foo2="bar2",label_2="label-value-2",resource_attr="resource-attr-val-1"} 456 1581452773000`, } for _, w := range want { diff --git a/pkg/translator/prometheus/README.md b/pkg/translator/prometheus/README.md index 700f442b45c3..7c29facac63c 100644 --- a/pkg/translator/prometheus/README.md +++ b/pkg/translator/prometheus/README.md @@ -12,10 +12,10 @@ > **Warning** > -> This feature can be disabled with [feature gate](https://github.com/open-telemetry/opentelemetry-collector/tree/main/featuregate) `pkg.translator.prometheus.NormalizeName`. It is enabled by default (beta stage). +> This feature can be enabled with [feature gate](https://github.com/open-telemetry/opentelemetry-collector/tree/main/featuregate) `pkg.translator.prometheus.NormalizeName`. It is disabled by default (alpha stage). > > ```shell-session -> $ otelcol --config=config.yaml --feature-gates=-pkg.translator.prometheus.NormalizeName +> $ otelcol --config=config.yaml --feature-gates=pkg.translator.prometheus.NormalizeName > ``` #### List of transformations to convert OpenTelemetry metrics to Prometheus metrics diff --git a/pkg/translator/prometheus/normalize_name.go b/pkg/translator/prometheus/normalize_name.go index cc567d0a5153..7c4811e1715f 100644 --- a/pkg/translator/prometheus/normalize_name.go +++ b/pkg/translator/prometheus/normalize_name.go @@ -73,7 +73,7 @@ var perUnitMap = map[string]string{ var normalizeNameGate = featuregate.GlobalRegistry().MustRegister( "pkg.translator.prometheus.NormalizeName", - featuregate.StageBeta, + featuregate.StageAlpha, featuregate.WithRegisterDescription("Controls whether metrics names are automatically normalized to follow Prometheus naming convention"), featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/8950"), ) diff --git a/pkg/translator/prometheus/normalize_name_test.go b/pkg/translator/prometheus/normalize_name_test.go index a51d100c319f..0a41b536f2f4 100644 --- a/pkg/translator/prometheus/normalize_name_test.go +++ b/pkg/translator/prometheus/normalize_name_test.go @@ -139,7 +139,10 @@ func TestOtelReceivers(t *testing.T) { } func TestTrimPromSuffixes(t *testing.T) { - normalizer := NewNormalizer(featuregate.NewRegistry()) + registry := featuregate.NewRegistry() + _, err := registry.Register(normalizeNameGate.ID(), featuregate.StageBeta) + require.NoError(t, err) + normalizer := NewNormalizer(registry) assert.Equal(t, "active_directory_ds_replication_network_io", normalizer.TrimPromSuffixes("active_directory_ds_replication_network_io_bytes_total", pmetric.MetricTypeSum, "bytes")) assert.Equal(t, "active_directory_ds_name_cache_hit_rate", normalizer.TrimPromSuffixes("active_directory_ds_name_cache_hit_rate_percent", pmetric.MetricTypeGauge, "percent")) @@ -172,10 +175,7 @@ func TestTrimPromSuffixes(t *testing.T) { } func TestTrimPromSuffixesWithFeatureGateDisabled(t *testing.T) { - registry := featuregate.NewRegistry() - _, err := registry.Register(normalizeNameGate.ID(), featuregate.StageAlpha) - require.NoError(t, err) - normalizer := NewNormalizer(registry) + normalizer := NewNormalizer(featuregate.NewRegistry()) assert.Equal(t, "apache_current_connections", normalizer.TrimPromSuffixes("apache_current_connections", pmetric.MetricTypeGauge, "connections")) assert.Equal(t, "apache_requests_total", normalizer.TrimPromSuffixes("apache_requests_total", pmetric.MetricTypeSum, "1")) diff --git a/pkg/translator/prometheusremotewrite/number_data_points_test.go b/pkg/translator/prometheusremotewrite/number_data_points_test.go index 897be641a6b2..39b13fcd3d9d 100644 --- a/pkg/translator/prometheusremotewrite/number_data_points_test.go +++ b/pkg/translator/prometheusremotewrite/number_data_points_test.go @@ -147,10 +147,10 @@ func TestAddSingleSumNumberDataPoint(t *testing.T) { }, want: func() map[string]*prompb.TimeSeries { labels := []prompb.Label{ - {Name: model.MetricNameLabel, Value: "test_sum_total"}, + {Name: model.MetricNameLabel, Value: "test_sum"}, } createdLabels := []prompb.Label{ - {Name: model.MetricNameLabel, Value: "test_sum_total" + createdSuffix}, + {Name: model.MetricNameLabel, Value: "test_sum" + createdSuffix}, } return map[string]*prompb.TimeSeries{ timeSeriesSignature(pmetric.MetricTypeSum.String(), &labels): { @@ -183,7 +183,7 @@ func TestAddSingleSumNumberDataPoint(t *testing.T) { }, want: func() map[string]*prompb.TimeSeries { labels := []prompb.Label{ - {Name: model.MetricNameLabel, Value: "test_sum_total"}, + {Name: model.MetricNameLabel, Value: "test_sum"}, } return map[string]*prompb.TimeSeries{ timeSeriesSignature(pmetric.MetricTypeSum.String(), &labels): { diff --git a/receiver/prometheusreceiver/metrics_receiver_helper_test.go b/receiver/prometheusreceiver/metrics_receiver_helper_test.go index cfd04be2e958..1e9ed248d495 100644 --- a/receiver/prometheusreceiver/metrics_receiver_helper_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_helper_test.go @@ -108,6 +108,7 @@ type testData struct { pages []mockPrometheusResponse attributes pcommon.Map validateScrapes bool + normalizedName bool validateFunc func(t *testing.T, td *testData, result []pmetric.ResourceMetrics) } @@ -222,13 +223,13 @@ func metricsCount(resourceMetric pmetric.ResourceMetrics) int { return metricsCount } -func getValidScrapes(t *testing.T, rms []pmetric.ResourceMetrics) []pmetric.ResourceMetrics { +func getValidScrapes(t *testing.T, rms []pmetric.ResourceMetrics, normalizedNames bool) []pmetric.ResourceMetrics { var out []pmetric.ResourceMetrics // rms will include failed scrapes and scrapes that received no metrics but have internal scrape metrics, filter those out for i := 0; i < len(rms); i++ { allMetrics := getMetrics(rms[i]) - if expectedScrapeMetricCount < len(allMetrics) && countScrapeMetrics(allMetrics) == expectedScrapeMetricCount { - if isFirstFailedScrape(allMetrics) { + if expectedScrapeMetricCount < len(allMetrics) && countScrapeMetrics(allMetrics, normalizedNames) == expectedScrapeMetricCount { + if isFirstFailedScrape(allMetrics, normalizedNames) { continue } assertUp(t, 1, allMetrics) @@ -240,7 +241,7 @@ func getValidScrapes(t *testing.T, rms []pmetric.ResourceMetrics) []pmetric.Reso return out } -func isFirstFailedScrape(metrics []pmetric.Metric) bool { +func isFirstFailedScrape(metrics []pmetric.Metric, normalizedNames bool) bool { for _, m := range metrics { if m.Name() == "up" { if m.Gauge().DataPoints().At(0).DoubleValue() == 1 { // assumed up will not have multiple datapoints @@ -250,7 +251,7 @@ func isFirstFailedScrape(metrics []pmetric.Metric) bool { } for _, m := range metrics { - if isDefaultMetrics(m) { + if isDefaultMetrics(m, normalizedNames) { continue } @@ -294,13 +295,13 @@ func assertUp(t *testing.T, expected float64, metrics []pmetric.Metric) { t.Error("No 'up' metric found") } -func countScrapeMetricsRM(got pmetric.ResourceMetrics) int { +func countScrapeMetricsRM(got pmetric.ResourceMetrics, normalizedNames bool) int { n := 0 ilms := got.ScopeMetrics() for j := 0; j < ilms.Len(); j++ { ilm := ilms.At(j) for i := 0; i < ilm.Metrics().Len(); i++ { - if isDefaultMetrics(ilm.Metrics().At(i)) { + if isDefaultMetrics(ilm.Metrics().At(i), normalizedNames) { n++ } } @@ -308,23 +309,29 @@ func countScrapeMetricsRM(got pmetric.ResourceMetrics) int { return n } -func countScrapeMetrics(metrics []pmetric.Metric) int { +func countScrapeMetrics(metrics []pmetric.Metric, normalizedNames bool) int { n := 0 for _, m := range metrics { - if isDefaultMetrics(m) { + if isDefaultMetrics(m, normalizedNames) { n++ } } return n } -func isDefaultMetrics(m pmetric.Metric) bool { +func isDefaultMetrics(m pmetric.Metric, normalizedNames bool) bool { switch m.Name() { - case "up", "scrape_samples_scraped", "scrape_samples_post_metric_relabeling", "scrape_series_added", "scrape_duration": + case "up", "scrape_samples_scraped", "scrape_samples_post_metric_relabeling", "scrape_series_added": return true + + // if normalizedNames is true, we expect unit `_seconds` to be trimmed. + case "scrape_duration_seconds": + return !normalizedNames + case "scrape_duration": + return normalizedNames default: - return false } + return false } type metricTypeComparator func(*testing.T, pmetric.Metric) @@ -341,8 +348,12 @@ type dataPointExpectation struct { type testExpectation func(*testing.T, pmetric.ResourceMetrics) func doCompare(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, expectations []testExpectation) { + doCompareNormalized(t, name, want, got, expectations, false) +} + +func doCompareNormalized(t *testing.T, name string, want pcommon.Map, got pmetric.ResourceMetrics, expectations []testExpectation, normalizedNames bool) { t.Run(name, func(t *testing.T) { - assert.Equal(t, expectedScrapeMetricCount, countScrapeMetricsRM(got)) + assert.Equal(t, expectedScrapeMetricCount, countScrapeMetricsRM(got, normalizedNames)) assert.Equal(t, want.Len(), got.Resource().Attributes().Len()) for k, v := range want.AsRaw() { val, ok := got.Resource().Attributes().Get(k) @@ -617,7 +628,7 @@ func testComponent(t *testing.T, targets []*testData, useStartTimeMetric bool, s } scrapes := pResults[name] if !target.validateScrapes { - scrapes = getValidScrapes(t, pResults[name]) + scrapes = getValidScrapes(t, pResults[name], target.normalizedName) } target.validateFunc(t, target, scrapes) }) diff --git a/receiver/prometheusreceiver/metrics_receiver_honor_timestamp_test.go b/receiver/prometheusreceiver/metrics_receiver_honor_timestamp_test.go index 328720f6ee1c..f14bd9d649bb 100644 --- a/receiver/prometheusreceiver/metrics_receiver_honor_timestamp_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_honor_timestamp_test.go @@ -44,8 +44,8 @@ var honorTimestampsPage1 = ` # TYPE go_thread gauge go_threads 19 %v -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 100 %v http_requests_total{method="post",code="400"} 5 %v @@ -72,8 +72,8 @@ var honorTimestampsPage2 = ` # TYPE go_thread gauge go_threads 18 %v -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 99 %v http_requests_total{method="post",code="400"} 3 %v @@ -102,8 +102,8 @@ var honorTimestampsPage3 = ` # TYPE go_thread gauge go_threads 19 %v -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 100 %v http_requests_total{method="post",code="400"} 5 %v @@ -217,7 +217,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -277,7 +277,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -337,7 +337,7 @@ func verifyHonorTimeStampsTrue(t *testing.T, td *testData, resourceMetrics []pme }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -405,7 +405,7 @@ func verifyHonorTimeStampsFalse(t *testing.T, td *testData, resourceMetrics []pm }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -467,7 +467,7 @@ func verifyHonorTimeStampsFalse(t *testing.T, td *testData, resourceMetrics []pm }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { diff --git a/receiver/prometheusreceiver/metrics_receiver_metric_name_normalize_test.go b/receiver/prometheusreceiver/metrics_receiver_metric_name_normalize_test.go index 2952e7f3d6df..db82c37133e4 100644 --- a/receiver/prometheusreceiver/metrics_receiver_metric_name_normalize_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_metric_name_normalize_test.go @@ -41,7 +41,8 @@ func TestMetricNormalize(t *testing.T) { pages: []mockPrometheusResponse{ {code: 200, data: normalizeMetric, useOpenMetrics: true}, }, - validateFunc: verifyNormalizeMetric, + normalizedName: true, + validateFunc: verifyNormalizeMetric, }, } @@ -137,5 +138,5 @@ func verifyNormalizeMetric(t *testing.T, td *testData, resourceMetrics []pmetric }, }), } - doCompare(t, "scrape-metricNormalize-1", wantAttributes, m1, e1) + doCompareNormalized(t, "scrape-metricNormalize-1", wantAttributes, m1, e1, true) } diff --git a/receiver/prometheusreceiver/metrics_receiver_non_numerical_test.go b/receiver/prometheusreceiver/metrics_receiver_non_numerical_test.go index 6f4dda91bef4..cd3fdf6b8542 100644 --- a/receiver/prometheusreceiver/metrics_receiver_non_numerical_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_non_numerical_test.go @@ -20,8 +20,8 @@ var staleNaNsPage1 = ` # TYPE go_threads gauge go_threads 19 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# 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 @@ -104,7 +104,7 @@ func verifyStaleNaNsSuccessfulScrape(t *testing.T, td *testData, resourceMetric }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -170,7 +170,7 @@ func verifyStaleNaNsFailedScrape(t *testing.T, td *testData, resourceMetric pmet }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -305,8 +305,8 @@ go_threads +Inf # HELP redis_connected_clients Redis connected clients redis_connected_clients{name="rough-snowflake-web",port="6380"} -Inf -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} +Inf # HELP rpc_duration_seconds A summary of the RPC duration in seconds. @@ -365,7 +365,7 @@ func verifyInfValues(t *testing.T, td *testData, resourceMetrics []pmetric.Resou }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { diff --git a/receiver/prometheusreceiver/metrics_receiver_test.go b/receiver/prometheusreceiver/metrics_receiver_test.go index 4968359dc82e..b0b89b781da5 100644 --- a/receiver/prometheusreceiver/metrics_receiver_test.go +++ b/receiver/prometheusreceiver/metrics_receiver_test.go @@ -35,8 +35,8 @@ var target1Page1 = ` # TYPE go_threads gauge go_threads 19 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# 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 @@ -63,8 +63,8 @@ var target1Page2 = ` # TYPE go_threads gauge go_threads 18 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 199 http_requests_total{method="post",code="400"} 12 @@ -93,8 +93,8 @@ var target1Page3 = ` # TYPE go_threads gauge go_threads 16 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 99 http_requests_total{method="post",code="400"} 3 @@ -138,7 +138,7 @@ func verifyTarget1(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -200,7 +200,7 @@ func verifyTarget1(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -263,7 +263,7 @@ func verifyTarget1(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -332,8 +332,8 @@ http_request_duration_seconds_bucket{method="post",code="400",le="+Inf"} 50 http_request_duration_seconds_sum{method="post",code="400"} 25 http_request_duration_seconds_count{method="post",code="400"} 50 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 10 http_requests_total{method="post",code="400"} 50 @@ -367,8 +367,8 @@ http_request_duration_seconds_bucket{method="post",code="400",le="+Inf"} 60 http_request_duration_seconds_sum{method="post",code="400"} 30 http_request_duration_seconds_count{method="post",code="400"} 60 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 50 http_requests_total{method="post",code="300"} 3 http_requests_total{method="post",code="400"} 60 @@ -406,8 +406,8 @@ http_request_duration_seconds_bucket{method="post",code="400",le="+Inf"} 60 http_request_duration_seconds_sum{method="post",code="400"} 30 http_request_duration_seconds_count{method="post",code="400"} 60 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 50 http_requests_total{method="post",code="300"} 5 http_requests_total{method="post",code="400"} 60 @@ -445,8 +445,8 @@ http_request_duration_seconds_bucket{method="post",code="400",le="+Inf"} 59 http_request_duration_seconds_sum{method="post",code="400"} 29 http_request_duration_seconds_count{method="post",code="400"} 59 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 49 http_requests_total{method="post",code="300"} 3 http_requests_total{method="post",code="400"} 59 @@ -484,8 +484,8 @@ http_request_duration_seconds_bucket{method="post",code="400",le="+Inf"} 59 http_request_duration_seconds_sum{method="post",code="400"} 29 http_request_duration_seconds_count{method="post",code="400"} 59 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# HELP http_requests_total The total number of HTTP requests. +# TYPE http_requests_total counter http_requests_total{method="post",code="200"} 50 http_requests_total{method="post",code="300"} 5 http_requests_total{method="post",code="400"} 59 @@ -544,7 +544,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -632,7 +632,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -736,7 +736,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -840,7 +840,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -944,7 +944,7 @@ func verifyTarget2(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc }, }, }), - assertMetricPresent("http_requests", + assertMetricPresent("http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -1079,6 +1079,9 @@ rpc_duration_seconds_count{foo="no_quantile"} 55 var target4Page1 = ` # A simple counter # TYPE foo counter +foo 0 +# Another counter with the same name but also _total suffix +# TYPE foo_total counter foo_total 1 ` @@ -1195,8 +1198,8 @@ func verifyTarget4(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc verifyNumValidScrapeResults(t, td, resourceMetrics) m1 := resourceMetrics[0] - // m1 has 1 metric + 5 internal scraper metrics - assert.Equal(t, 6, metricsCount(m1)) + // m1 has 2 metrics + 5 internal scraper metrics + assert.Equal(t, 7, metricsCount(m1)) wantAttributes := td.attributes @@ -1204,6 +1207,16 @@ func verifyTarget4(t *testing.T, td *testData, resourceMetrics []pmetric.Resourc ts1 := getTS(metrics1) e1 := []testExpectation{ assertMetricPresent("foo", + compareMetricIsMonotonic(true), + []dataPointExpectation{ + { + numberPointComparator: []numberPointComparator{ + compareTimestamp(ts1), + compareDoubleValue(0), + }, + }, + }), + assertMetricPresent("foo_total", compareMetricIsMonotonic(true), []dataPointExpectation{ { @@ -1269,8 +1282,8 @@ var startTimeMetricPage = ` # HELP go_threads Number of OS threads created # TYPE go_threads gauge go_threads 19 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# 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. @@ -1355,8 +1368,8 @@ var startTimeMetricRegexPage = ` # HELP go_threads Number of OS threads created # TYPE go_threads gauge go_threads 19 -# HELP http_requests The total number of HTTP requests. -# TYPE http_requests counter +# 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. diff --git a/receiver/prometheusreceiver/metrics_reciever_metric_rename_test.go b/receiver/prometheusreceiver/metrics_reciever_metric_rename_test.go index f870fad9617b..365d00b5ddb2 100644 --- a/receiver/prometheusreceiver/metrics_reciever_metric_rename_test.go +++ b/receiver/prometheusreceiver/metrics_reciever_metric_rename_test.go @@ -19,17 +19,17 @@ var renameMetric = ` # TYPE http_go_threads gauge http_go_threads 19 -# HELP http_connected connected clients -# TYPE http_connected counter +# HELP http_connected_total connected clients +# TYPE http_connected_total counter http_connected_total{method="post",port="6380"} 15.0 -# HELP redis_http_requests Redis connected clients -# TYPE redis_http_requests counter +# HELP redis_http_requests_total Redis connected clients +# TYPE redis_http_requests_total counter redis_http_requests_total{method="post",port="6380"} 10.0 redis_http_requests_total{method="post",port="6381"} 12.0 -# HELP rpc_duration RPC clients -# TYPE rpc_duration counter +# HELP rpc_duration_total RPC clients +# TYPE rpc_duration_total counter rpc_duration_total{method="post",port="6380"} 100.0 rpc_duration_total{method="post",port="6381"} 120.0 ` @@ -173,7 +173,7 @@ func verifyRenameMetricKeepAction(t *testing.T, td *testData, resourceMetrics [] metrics1 := m1.ScopeMetrics().At(0).Metrics() ts1 := getTS(metrics1) e1 := []testExpectation{ - assertMetricPresent("rpc_duration", + assertMetricPresent("rpc_duration_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -193,8 +193,8 @@ func verifyRenameMetricKeepAction(t *testing.T, td *testData, resourceMetrics [] }, }), assertMetricAbsent("http_go_threads"), - assertMetricAbsent("http_connected"), - assertMetricAbsent("redis_http_requests"), + assertMetricAbsent("http_connected_total"), + assertMetricAbsent("redis_http_requests_total"), } doCompare(t, "scrape-metricRenameKeepAction-1", wantAttributes, m1, e1) } @@ -204,17 +204,17 @@ var renamingLabel = ` # TYPE http_go_threads gauge http_go_threads 19 -# HELP http_connected connected clients -# TYPE http_connected counter +# HELP http_connected_total connected clients +# TYPE http_connected_total counter http_connected_total{url="localhost",status="ok"} 15.0 -# HELP redis_http_requests Redis connected clients -# TYPE redis_http_requests counter +# HELP redis_http_requests_total Redis connected clients +# TYPE redis_http_requests_total counter redis_http_requests_total{method="post",port="6380"} 10.0 redis_http_requests_total{job="sample-app",statusCode="200"} 12.0 -# HELP rpc_duration RPC clients -# TYPE rpc_duration counter +# HELP rpc_duration_total RPC clients +# TYPE rpc_duration_total counter rpc_duration_total{monitor="codeLab",host="local"} 100.0 rpc_duration_total{address="localhost:9090/metrics",contentType="application/json"} 120.0 ` @@ -291,7 +291,7 @@ func verifyRenameLabel(t *testing.T, td *testData, resourceMetrics []pmetric.Res }, }, }), - assertMetricPresent("http_connected", + assertMetricPresent("http_connected_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -302,7 +302,7 @@ func verifyRenameLabel(t *testing.T, td *testData, resourceMetrics []pmetric.Res }, }, }), - assertMetricPresent("redis_http_requests", + assertMetricPresent("redis_http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -322,7 +322,7 @@ func verifyRenameLabel(t *testing.T, td *testData, resourceMetrics []pmetric.Res }, }, }), - assertMetricPresent("rpc_duration", + assertMetricPresent("rpc_duration_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -394,7 +394,7 @@ func verifyRenameLabelKeepAction(t *testing.T, td *testData, resourceMetrics []p }, }, }), - assertMetricPresent("http_connected", + assertMetricPresent("http_connected_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -405,7 +405,7 @@ func verifyRenameLabelKeepAction(t *testing.T, td *testData, resourceMetrics []p }, }, }), - assertMetricPresent("redis_http_requests", + assertMetricPresent("redis_http_requests_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ { @@ -423,7 +423,7 @@ func verifyRenameLabelKeepAction(t *testing.T, td *testData, resourceMetrics []p }, }, }), - assertMetricPresent("rpc_duration", + assertMetricPresent("rpc_duration_total", compareMetricType(pmetric.MetricTypeSum), []dataPointExpectation{ {