diff --git a/CHANGELOG.md b/CHANGELOG.md index baab4d165f4..2e3c3e8d0a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `sdktrace.TraceProvider.Shutdown` and `sdktrace.TraceProvider.ForceFlush` to not return error when no processor register. (#3268) - The `"go.opentelemetry.io/otel/exporters/prometheus".New` now also returns an error indicating the failure to register the exporter with Prometheus. (#3239) +- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now correctly adds _total suffixes to counter metrics. (#3360) ### Fixed diff --git a/exporters/prometheus/exporter.go b/exporters/prometheus/exporter.go index 007dc2f50d9..95f7e4db84c 100644 --- a/exporters/prometheus/exporter.go +++ b/exporters/prometheus/exporter.go @@ -43,6 +43,10 @@ type collector struct { reader metric.Reader } +// prometheus counters MUST have a _total suffix: +// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.14.0/specification/metrics/data-model.md#sums-1 +const counterSuffix = "_total" + // New returns a Prometheus Exporter. func New(opts ...Option) (*Exporter, error) { cfg := newConfig(opts...) @@ -173,7 +177,7 @@ func getSumMetricData[N int64 | float64](sum metricdata.Sum[N], m metricdata.Met dataPoints := make([]*metricData, 0, len(sum.DataPoints)) for _, dp := range sum.DataPoints { keys, values := getAttrs(dp.Attributes) - desc := prometheus.NewDesc(sanitizeName(m.Name), m.Description, keys, nil) + desc := prometheus.NewDesc(sanitizeName(m.Name)+counterSuffix, m.Description, keys, nil) md := &metricData{ name: m.Name, description: desc, diff --git a/exporters/prometheus/testdata/counter.txt b/exporters/prometheus/testdata/counter.txt index 93776d2372b..b434b536fac 100755 --- a/exporters/prometheus/testdata/counter.txt +++ b/exporters/prometheus/testdata/counter.txt @@ -1,3 +1,3 @@ -# HELP foo a simple counter -# TYPE foo counter -foo{A="B",C="D",E="true",F="42"} 24.3 +# HELP foo_total a simple counter +# TYPE foo_total counter +foo_total{A="B",C="D",E="true",F="42"} 24.3 diff --git a/exporters/prometheus/testdata/gauge.txt b/exporters/prometheus/testdata/gauge.txt index 889295d74e1..2bde172e579 100644 --- a/exporters/prometheus/testdata/gauge.txt +++ b/exporters/prometheus/testdata/gauge.txt @@ -1,3 +1,3 @@ -# HELP bar a fun little gauge -# TYPE bar counter -bar{A="B",C="D"} 75 +# HELP bar_total a fun little gauge +# TYPE bar_total counter +bar_total{A="B",C="D"} 75 diff --git a/exporters/prometheus/testdata/sanitized_labels.txt b/exporters/prometheus/testdata/sanitized_labels.txt index cd686cff97e..1a64102c858 100755 --- a/exporters/prometheus/testdata/sanitized_labels.txt +++ b/exporters/prometheus/testdata/sanitized_labels.txt @@ -1,3 +1,3 @@ -# HELP foo a sanitary counter -# TYPE foo counter -foo{A_B="Q",C_D="Y;Z"} 24.3 +# HELP foo_total a sanitary counter +# TYPE foo_total counter +foo_total{A_B="Q",C_D="Y;Z"} 24.3 diff --git a/exporters/prometheus/testdata/sanitized_names.txt b/exporters/prometheus/testdata/sanitized_names.txt index 509055705a3..737cbfa4550 100644 --- a/exporters/prometheus/testdata/sanitized_names.txt +++ b/exporters/prometheus/testdata/sanitized_names.txt @@ -1,12 +1,12 @@ -# HELP bar a fun little gauge -# TYPE bar counter -bar{A="B",C="D"} 75 -# HELP _0invalid_counter_name a counter with an invalid name -# TYPE _0invalid_counter_name counter -_0invalid_counter_name{A="B",C="D"} 100 -# HELP invalid_gauge_name a gauge with an invalid name -# TYPE invalid_gauge_name counter -invalid_gauge_name{A="B",C="D"} 100 +# HELP bar_total a fun little gauge +# TYPE bar_total counter +bar_total{A="B",C="D"} 75 +# HELP _0invalid_counter_name_total a counter with an invalid name +# TYPE _0invalid_counter_name_total counter +_0invalid_counter_name_total{A="B",C="D"} 100 +# HELP invalid_gauge_name_total a gauge with an invalid name +# TYPE invalid_gauge_name_total counter +invalid_gauge_name_total{A="B",C="D"} 100 # HELP invalid_hist_name a histogram with an invalid name # TYPE invalid_hist_name histogram invalid_hist_name_bucket{A="B",C="D",le="0"} 0