Fixes https://github.com/open-telemetry/opentelemetry-go/issues/7039
Fixes https://github.com/open-telemetry/opentelemetry-go/issues/6704
This uses the common prometheus/otlptranslator library to handle name
conversion. It was a little tricky to work around the fact that the
library only lets us configure whether all suffixes are added or not.
But we want to keep supporting WithoutUnit and WithoutCounterSuffixes
for a while longer. Those will eventually be deprecated and replaced
after
https://github.com/open-telemetry/opentelemetry-specification/pull/4533
is released.
We decided to go ahead with the changes despite it being a small
behavioral change when UTF8 is enabled. See:
https://github.com/prometheus/otlptranslator/issues/44 for the
rationale.
This adds a unit test to verify that it properly handles bracketed
units. The test fails on main with:
```
--- FAIL: TestPrometheusExporter (0.01s)
--- FAIL: TestPrometheusExporter/counter_with_bracketed_unit (0.00s)
exporter_test.go:646:
Error Trace: /usr/local/google/home/dashpole/go/src/go.opentelemetry.io/opentelemetry-go/exporters/prometheus/exporter_test.go:646
Error: Received unexpected error:
-# HELP "foo_{spans}_total" a simple counter
-# TYPE "foo_{spans}_total" counter
-{"foo_{spans}_total",A="B",C="D",E="true",F="42",otel_scope_fizz="buzz",otel_scope_name="testmeter",otel_scope_schema_url="",otel_scope_version="v0.1.0"} 24.3
-{"foo_{spans}_total",A="D",C="B",E="true",F="42",otel_scope_fizz="buzz",otel_scope_name="testmeter",otel_scope_schema_url="",otel_scope_version="v0.1.0"} 5
+# HELP foo_total a simple counter
+# TYPE foo_total counter
+foo_total{A="B",C="D",E="true",F="42",otel_scope_fizz="buzz",otel_scope_name="testmeter",otel_scope_schema_url="",otel_scope_version="v0.1.0"} 24.3
+foo_total{A="D",C="B",E="true",F="42",otel_scope_fizz="buzz",otel_scope_name="testmeter",otel_scope_schema_url="",otel_scope_version="v0.1.0"} 5
# HELP target_info Target metadata
# TYPE target_info gauge
target_info{"service.name"="prometheus_test","telemetry.sdk.language"="go","telemetry.sdk.name"="opentelemetry","telemetry.sdk.version"="latest"} 1
Test: TestPrometheusExporter/counter_with_bracketed_unit
2025/07/18 15:07:47 internal_logging.go:50: "msg"="Using existing type definition." "error"="instrument type conflict" "instrument"="foo_total" "existing"="COUNTER" "dropped"="GAUGE"
2025/07/18 15:07:47 internal_logging.go:50: "msg"="Using existing type definition." "error"="instrument type conflict" "instrument"="foo_bytes" "existing"="GAUGE" "dropped"="HISTOGRAM"
FAIL
FAIL go.opentelemetry.io/otel/exporters/prometheus 0.054s
FAIL
```
cc @TylerHelmuth @ywwg @ArthurSens
---------
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
* Deprecate the aggregation pkg
* Decouple the internal/aggregate from aggregation pkg
* Add Aggregation to the metric pkg
* Do not use sdk/metric/aggregation in stdoutmetric exporter
* Update all generated templates
* Update prom exporter
* Fix view example
* Add changes to changelog
* Update CHANGELOG.md
Co-authored-by: Robert Pająk <pellared@hotmail.com>
* Rename Sum to AggregationSum
* Fix comments
* Centralize validation of aggregation in pipeline
* Remove validation of agg in manual_reader selector opt
* Fix merge
---------
Co-authored-by: Robert Pająk <pellared@hotmail.com>
* Replace view usage in sdk/metric
* Replace view use in stdoutmetric
* Replace view use in prometheus exporter
* Replace view use in otlpmetric exporters
* Replace view use in view example