Repository: open-telemetry/opentelemetry-python

Issue:
Prometheus exporter: consider removing the ability to set a global metric prefix
The [current implementation](https://github.com/open-telemetry/opentelemetry-python/blob/main/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py#L120) allows specifying a prefix which is globally applied to all metrics for the exporter.

From the [OpenMetrics spec on target metadata](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#supporting-target-metadata-in-both-push-based-and-pull-based-systems):

> Exposers MUST NOT prefix MetricFamily names or otherwise vary MetricFamily names based on target metadata.
> ...
> The metric names MUST NOT be varied based on target metadata. For example it would be incorrect for all metrics to end up being prefixed with staging_ even if they all originated from targets in a staging environment).

The gist is that name prefixes shouldn't be used to differentiate instances of an application being scraped, which appears to be what we are doing.  It isn't entirely clear to me what the original purpose of the prefix was, but if it is to prevent collisions between instrumentation libraries, we should solve that with https://github.com/open-telemetry/opentelemetry-python/issues/3072 instead.


Discussion:
Hi - I'm amit. Can I work on this issue? @srikanthccv 

Resolving patch:
diff --git a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py
--- a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py
+++ b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py
@@ -114,14 +114,9 @@ def _convert_buckets(
 
 
 class PrometheusMetricReader(MetricReader):
-    """Prometheus metric exporter for OpenTelemetry.
+    """Prometheus metric exporter for OpenTelemetry."""
 
-    Args:
-        prefix: single-word application prefix relevant to the domain
-            the metric belongs to.
-    """
-
-    def __init__(self, prefix: str = "") -> None:
+    def __init__(self) -> None:
 
         super().__init__(
             preferred_temporality={
@@ -133,7 +128,7 @@ def __init__(self, prefix: str = "") -> None:
                 ObservableGauge: AggregationTemporality.CUMULATIVE,
             }
         )
-        self._collector = _CustomCollector(prefix)
+        self._collector = _CustomCollector()
         REGISTRY.register(self._collector)
         self._collector._callback = self.collect
 
@@ -158,8 +153,7 @@ class _CustomCollector:
     https://github.com/prometheus/client_python#custom-collectors
     """
 
-    def __init__(self, prefix: str = ""):
-        self._prefix = prefix
+    def __init__(self):
         self._callback = None
         self._metrics_datas = deque()
         self._non_letters_digits_underscore_re = compile(
@@ -210,8 +204,6 @@ def _translate_to_prometheus(
             pre_metric_family_ids = []
 
             metric_name = ""
-            if self._prefix != "":
-                metric_name = self._prefix + "_"
             metric_name += self._sanitize(metric.name)
 
             metric_description = metric.description or ""


Test patch:
diff --git a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py
--- a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py
+++ b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py
@@ -52,8 +52,7 @@ def setUp(self):
     def test_constructor(self):
         """Test the constructor."""
         with self._registry_register_patch:
-            exporter = PrometheusMetricReader(prefix="testprefix")
-            self.assertEqual(exporter._collector._prefix, "testprefix")
+            _ = PrometheusMetricReader()
             self.assertTrue(self._mock_registry_register.called)
 
     def test_shutdown(self):
@@ -102,7 +101,7 @@ def test_histogram_to_prometheus(self):
             ]
         )
 
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         collector.add_metrics_data(metrics_data)
         result_bytes = generate_latest(collector)
         result = result_bytes.decode("utf-8")
@@ -110,13 +109,13 @@ def test_histogram_to_prometheus(self):
             result,
             dedent(
                 """\
-                # HELP testprefix_test_name_s foo
-                # TYPE testprefix_test_name_s histogram
-                testprefix_test_name_s_bucket{histo="1",le="123.0"} 1.0
-                testprefix_test_name_s_bucket{histo="1",le="456.0"} 4.0
-                testprefix_test_name_s_bucket{histo="1",le="+Inf"} 6.0
-                testprefix_test_name_s_count{histo="1"} 6.0
-                testprefix_test_name_s_sum{histo="1"} 579.0
+                # HELP test_name_s foo
+                # TYPE test_name_s histogram
+                test_name_s_bucket{histo="1",le="123.0"} 1.0
+                test_name_s_bucket{histo="1",le="456.0"} 4.0
+                test_name_s_bucket{histo="1",le="+Inf"} 6.0
+                test_name_s_count{histo="1"} 6.0
+                test_name_s_sum{histo="1"} 579.0
                 """
             ),
         )
@@ -147,14 +146,12 @@ def test_sum_to_prometheus(self):
             ]
         )
 
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         collector.add_metrics_data(metrics_data)
 
         for prometheus_metric in collector.collect():
             self.assertEqual(type(prometheus_metric), CounterMetricFamily)
-            self.assertEqual(
-                prometheus_metric.name, "testprefix_test_sum_testunit"
-            )
+            self.assertEqual(prometheus_metric.name, "test_sum_testunit")
             self.assertEqual(prometheus_metric.documentation, "testdesc")
             self.assertTrue(len(prometheus_metric.samples) == 1)
             self.assertEqual(prometheus_metric.samples[0].value, 123)
@@ -192,14 +189,12 @@ def test_gauge_to_prometheus(self):
             ]
         )
 
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         collector.add_metrics_data(metrics_data)
 
         for prometheus_metric in collector.collect():
             self.assertEqual(type(prometheus_metric), GaugeMetricFamily)
-            self.assertEqual(
-                prometheus_metric.name, "testprefix_test_gauge_testunit"
-            )
+            self.assertEqual(prometheus_metric.name, "test_gauge_testunit")
             self.assertEqual(prometheus_metric.documentation, "testdesc")
             self.assertTrue(len(prometheus_metric.samples) == 1)
             self.assertEqual(prometheus_metric.samples[0].value, 123)
@@ -217,13 +212,13 @@ def test_invalid_metric(self):
             description="testdesc",
             unit="testunit",
         )
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         collector.add_metrics_data([record])
         collector.collect()
         self.assertLogs("opentelemetry.exporter.prometheus", level="WARNING")
 
     def test_sanitize(self):
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         self.assertEqual(
             collector._sanitize("1!2@3#4$5%6^7&8*9(0)_-"),
             "1_2_3_4_5_6_7_8_9_0___",
@@ -256,14 +251,12 @@ def test_list_labels(self):
                 )
             ]
         )
-        collector = _CustomCollector("testprefix")
+        collector = _CustomCollector()
         collector.add_metrics_data(metrics_data)
 
         for prometheus_metric in collector.collect():
             self.assertEqual(type(prometheus_metric), GaugeMetricFamily)
-            self.assertEqual(
-                prometheus_metric.name, "testprefix_test_gauge_testunit"
-            )
+            self.assertEqual(prometheus_metric.name, "test_gauge_testunit")
             self.assertEqual(prometheus_metric.documentation, "testdesc")
             self.assertTrue(len(prometheus_metric.samples) == 1)
             self.assertEqual(prometheus_metric.samples[0].value, 123)
@@ -276,7 +269,7 @@ def test_list_labels(self):
 
     def test_check_value(self):
 
-        collector = _CustomCollector("")
+        collector = _CustomCollector()
 
         self.assertEqual(collector._check_value(1), "1")
         self.assertEqual(collector._check_value(1.0), "1.0")
@@ -290,7 +283,7 @@ def test_check_value(self):
 
     def test_multiple_collection_calls(self):
 
-        metric_reader = PrometheusMetricReader(prefix="prefix")
+        metric_reader = PrometheusMetricReader()
         provider = MeterProvider(metric_readers=[metric_reader])
         meter = provider.get_meter("getting-started", "0.1.2")
         counter = meter.create_counter("counter")