From bb230cd123b6e3afd697a72330998f14dcb91b5c Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Tue, 18 Oct 2022 16:09:09 +0000 Subject: [PATCH] add _total suffixes to prometheus counters --- CHANGELOG.md | 1 + exporters/prometheus/exporter.go | 10 +++++++++- exporters/prometheus/testdata/counter.txt | 6 +++--- exporters/prometheus/testdata/custom_resource.txt | 6 +++--- exporters/prometheus/testdata/empty_resource.txt | 6 +++--- exporters/prometheus/testdata/sanitized_labels.txt | 7 ++++--- exporters/prometheus/testdata/sanitized_names.txt | 6 +++--- exporters/prometheus/testdata/without_target_info.txt | 6 +++--- 8 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a9af7a3094..d56a2f5f579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - The `"go.opentelemetry.io/otel/exporters/prometheus".New` now also returns an error indicating the failure to register the exporter with Prometheus. (#3239) - The prometheus exporter will no longer try to enumerate the metrics it will send to prometheus on startup. This fixes the `reader is not registered` warning currently emitted on startup. (#3291 #3342) +- 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 b2c6778af95..8135578e42d 100644 --- a/exporters/prometheus/exporter.go +++ b/exporters/prometheus/exporter.go @@ -54,6 +54,10 @@ type collector struct { createTargetInfoOnce sync.Once } +// 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...) @@ -197,8 +201,12 @@ func getSumMetricData[N int64 | float64](sum metricdata.Sum[N], m metricdata.Met } dataPoints := make([]*metricData, 0, len(sum.DataPoints)) for _, dp := range sum.DataPoints { + name := sanitizeName(m.Name) + if sum.IsMonotonic { + name += counterSuffix + } keys, values := getAttrs(dp.Attributes) - desc := prometheus.NewDesc(sanitizeName(m.Name), m.Description, keys, nil) + desc := prometheus.NewDesc(name, 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 1165eb67cd6..7142094afe6 100755 --- a/exporters/prometheus/testdata/counter.txt +++ b/exporters/prometheus/testdata/counter.txt @@ -1,6 +1,6 @@ -# 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 # 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 diff --git a/exporters/prometheus/testdata/custom_resource.txt b/exporters/prometheus/testdata/custom_resource.txt index 4a394fe9fec..581833b56d0 100755 --- a/exporters/prometheus/testdata/custom_resource.txt +++ b/exporters/prometheus/testdata/custom_resource.txt @@ -1,6 +1,6 @@ -# 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 # HELP target_info Target metadata # TYPE target_info gauge target_info{A="B",C="D",service_name="prometheus_test",telemetry_sdk_language="go",telemetry_sdk_name="opentelemetry",telemetry_sdk_version="latest"} 1 diff --git a/exporters/prometheus/testdata/empty_resource.txt b/exporters/prometheus/testdata/empty_resource.txt index ed9d29f3312..02c41c6bac6 100755 --- a/exporters/prometheus/testdata/empty_resource.txt +++ b/exporters/prometheus/testdata/empty_resource.txt @@ -1,6 +1,6 @@ -# 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 # HELP target_info Target metadata # TYPE target_info gauge target_info 1 diff --git a/exporters/prometheus/testdata/sanitized_labels.txt b/exporters/prometheus/testdata/sanitized_labels.txt index 176d437e000..40be2b01aab 100755 --- a/exporters/prometheus/testdata/sanitized_labels.txt +++ b/exporters/prometheus/testdata/sanitized_labels.txt @@ -1,6 +1,7 @@ -# 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 # 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 + diff --git a/exporters/prometheus/testdata/sanitized_names.txt b/exporters/prometheus/testdata/sanitized_names.txt index a599ea26851..0d321b3fae9 100644 --- a/exporters/prometheus/testdata/sanitized_names.txt +++ b/exporters/prometheus/testdata/sanitized_names.txt @@ -1,9 +1,9 @@ # HELP bar a fun little gauge # TYPE bar gauge 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 _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 a gauge with an invalid name # TYPE invalid_gauge_name gauge invalid_gauge_name{A="B",C="D"} 100 diff --git a/exporters/prometheus/testdata/without_target_info.txt b/exporters/prometheus/testdata/without_target_info.txt index 93776d2372b..b434b536fac 100755 --- a/exporters/prometheus/testdata/without_target_info.txt +++ b/exporters/prometheus/testdata/without_target_info.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