diff --git a/CHANGELOG.md b/CHANGELOG.md index a31d79d3f..47075ce77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add metric's scope attributes as `otel_scope_[attribute]` labels in `go.opentelemetry.io/otel/exporters/prometheus`. (#5947) - Add `EventName` to `EnabledParameters` in `go.opentelemetry.io/otel/log`. (#6825) - Add `EventName` to `EnabledParameters` in `go.opentelemetry.io/otel/sdk/log`. (#6825) +- Changed handling of `go.opentelemetry.io/otel/exporters/prometheus` metric renaming to add unit suffixes when it doesn't match one of the pre-defined values in the unit suffix map. (#6839) ### Removed diff --git a/exporters/prometheus/exporter.go b/exporters/prometheus/exporter.go index c2b0aa0d4..1493864e9 100644 --- a/exporters/prometheus/exporter.go +++ b/exporters/prometheus/exporter.go @@ -425,6 +425,13 @@ func createInfoMetric(name, description string, res *resource.Resource) (prometh return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), values...) } +func unitMapGetOrDefault(unit string) string { + if promUnit, ok := unitSuffixes[unit]; ok { + return promUnit + } + return unit +} + var unitSuffixes = map[string]string{ // Time "d": "days", @@ -483,7 +490,7 @@ func (c *collector) getName(m metricdata.Metrics, typ *dto.MetricType) string { if c.namespace != "" { name = c.namespace + name } - if suffix, ok := unitSuffixes[m.Unit]; ok && !c.withoutUnits && !strings.HasSuffix(name, suffix) { + if suffix := unitMapGetOrDefault(m.Unit); suffix != "" && !c.withoutUnits && !strings.HasSuffix(name, suffix) { name += "_" + suffix } if addCounterSuffix { diff --git a/exporters/prometheus/exporter_test.go b/exporters/prometheus/exporter_test.go index 6b606e58f..6cd3e88d5 100644 --- a/exporters/prometheus/exporter_test.go +++ b/exporters/prometheus/exporter_test.go @@ -95,6 +95,35 @@ func TestPrometheusExporter(t *testing.T) { counter.Add(ctx, 5, otelmetric.WithAttributeSet(attrs2)) }, }, + { + name: "counter with custom unit not tracked by ucum standards", + expectedFile: "testdata/counter_with_custom_unit_suffix.txt", + recordMetrics: func(ctx context.Context, meter otelmetric.Meter) { + opt := otelmetric.WithAttributes( + attribute.Key("A").String("B"), + attribute.Key("C").String("D"), + attribute.Key("E").Bool(true), + attribute.Key("F").Int(42), + ) + counter, err := meter.Float64Counter( + "foo", + otelmetric.WithDescription("a simple counter"), + otelmetric.WithUnit("madeup"), + ) + require.NoError(t, err) + counter.Add(ctx, 5, opt) + counter.Add(ctx, 10.3, opt) + counter.Add(ctx, 9, opt) + + attrs2 := attribute.NewSet( + attribute.Key("A").String("D"), + attribute.Key("C").String("B"), + attribute.Key("E").Bool(true), + attribute.Key("F").Int(42), + ) + counter.Add(ctx, 5, otelmetric.WithAttributeSet(attrs2)) + }, + }, { name: "counter that already has a total suffix", expectedFile: "testdata/counter.txt", diff --git a/exporters/prometheus/testdata/counter_with_custom_unit_suffix.txt b/exporters/prometheus/testdata/counter_with_custom_unit_suffix.txt new file mode 100644 index 000000000..75facd31f --- /dev/null +++ b/exporters/prometheus/testdata/counter_with_custom_unit_suffix.txt @@ -0,0 +1,7 @@ +# HELP "foo_madeup_total" a simple counter +# TYPE "foo_madeup_total" counter +{"foo_madeup_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_madeup_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