Skip to content

Commit

Permalink
expand the set of units supported by the prometheus exporter, and avoid
Browse files Browse the repository at this point in the history
duplicate unit suffixes
  • Loading branch information
dashpole committed Jul 26, 2023
1 parent b4264c5 commit 2ea8f85
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add info and debug logging to the metric SDK. (#4315)
- The `go.opentelemetry.io/otel/semconv/v1.21.0` package.
The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362)
- Expand the set of units supported by the prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374)

### Changed

Expand Down
44 changes: 40 additions & 4 deletions exporters/prometheus/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,45 @@ func sanitizeRune(r rune) rune {
}

var unitSuffixes = map[string]string{
"1": "_ratio",
"By": "_bytes",
"ms": "_milliseconds",
// Time
"d": "_days",
"h": "_hours",
"min": "_minutes",
"s": "_seconds",
"ms": "_milliseconds",
"us": "_microseconds",
"ns": "_nanoseconds",

// Bytes
"By": "_bytes",
"KiBy": "_kibibytes",
"MiBy": "_mebibytes",
"GiBy": "_gibibytes",
"TiBy": "_tibibytes",
"KBy": "_kilobytes",
"MBy": "_megabytes",
"GBy": "_gigabytes",
"TBy": "_terabytes",
"B": "_bytes",
"KB": "_kilobytes",
"MB": "_megabytes",
"GB": "_gigabytes",
"TB": "_terabytes",

// SI
"m": "_meters",
"V": "_volts",
"A": "_amperes",
"J": "_joules",
"W": "_watts",
"g": "_grams",

// Misc
"Cel": "_celsius",
"Hz": "_hertz",
"1": "_ratio",
"%": "_percent",
"$": "_dollars",
}

// getName returns the sanitized name, prefixed with the namespace and suffixed with unit.
Expand All @@ -344,7 +380,7 @@ func (c *collector) getName(m metricdata.Metrics) string {
if c.withoutUnits {
return name
}
if suffix, ok := unitSuffixes[m.Unit]; ok {
if suffix, ok := unitSuffixes[m.Unit]; ok && !strings.HasSuffix(name, suffix) {
name += suffix
}
return name
Expand Down
43 changes: 36 additions & 7 deletions exporters/prometheus/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,36 @@ func TestPrometheusExporter(t *testing.T) {
counter, err := meter.Float64Counter(
"foo",
otelmetric.WithDescription("a simple counter"),
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
)
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 the unit suffix",
expectedFile: "testdata/counter.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.seconds",
otelmetric.WithDescription("a simple counter"),
otelmetric.WithUnit("s"),
)
require.NoError(t, err)
counter.Add(ctx, 5, opt)
Expand Down Expand Up @@ -85,7 +114,7 @@ func TestPrometheusExporter(t *testing.T) {
counter, err := meter.Float64Counter(
"foo",
otelmetric.WithDescription("a simple counter without a total suffix"),
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
)
require.NoError(t, err)
counter.Add(ctx, 5, opt)
Expand Down Expand Up @@ -415,15 +444,15 @@ func TestMultiScopes(t *testing.T) {
fooCounter, err := provider.Meter("meterfoo", otelmetric.WithInstrumentationVersion("v0.1.0")).
Int64Counter(
"foo",
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter foo counter"))
assert.NoError(t, err)
fooCounter.Add(ctx, 100, otelmetric.WithAttributes(attribute.String("type", "foo")))

barCounter, err := provider.Meter("meterbar", otelmetric.WithInstrumentationVersion("v0.1.0")).
Int64Counter(
"bar",
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter bar counter"))
assert.NoError(t, err)
barCounter.Add(ctx, 200, otelmetric.WithAttributes(attribute.String("type", "bar")))
Expand Down Expand Up @@ -571,7 +600,7 @@ func TestDuplicateMetrics(t *testing.T) {
bazA.Add(ctx, 100, withTypeBar)

bazB, err := meterB.Int64Counter("bar",
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter bar"))
assert.NoError(t, err)
bazB.Add(ctx, 100, withTypeBar)
Expand All @@ -589,7 +618,7 @@ func TestDuplicateMetrics(t *testing.T) {
barA.Add(ctx, 100, withTypeBar)

barB, err := meterB.Int64UpDownCounter("bar",
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter gauge bar"))
assert.NoError(t, err)
barB.Add(ctx, 100, withTypeBar)
Expand All @@ -607,7 +636,7 @@ func TestDuplicateMetrics(t *testing.T) {
barA.Record(ctx, 100, withAB)

barB, err := meterB.Int64Histogram("bar",
otelmetric.WithUnit("ms"),
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter histogram bar"))
assert.NoError(t, err)
barB.Record(ctx, 100, withAB)
Expand Down
8 changes: 4 additions & 4 deletions exporters/prometheus/testdata/counter.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# HELP foo_milliseconds_total a simple counter
# TYPE foo_milliseconds_total counter
foo_milliseconds_total{A="B",C="D",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 24.3
foo_milliseconds_total{A="D",C="B",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 5
# HELP foo_seconds_total a simple counter
# TYPE foo_seconds_total counter
foo_seconds_total{A="B",C="D",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 24.3
foo_seconds_total{A="D",C="B",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 5
# HELP otel_scope_info Instrumentation Scope metadata
# TYPE otel_scope_info gauge
otel_scope_info{otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 1
Expand Down
8 changes: 4 additions & 4 deletions exporters/prometheus/testdata/counter_disabled_suffix.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# HELP foo_milliseconds a simple counter without a total suffix
# TYPE foo_milliseconds counter
foo_milliseconds{A="B",C="D",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 24.3
foo_milliseconds{A="D",C="B",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 5
# HELP foo_seconds a simple counter without a total suffix
# TYPE foo_seconds counter
foo_seconds{A="B",C="D",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 24.3
foo_seconds{A="D",C="B",E="true",F="42",otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 5
# HELP otel_scope_info Instrumentation Scope metadata
# TYPE otel_scope_info gauge
otel_scope_info{otel_scope_name="testmeter",otel_scope_version="v0.1.0"} 1
Expand Down
12 changes: 6 additions & 6 deletions exporters/prometheus/testdata/multi_scopes.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# HELP bar_milliseconds_total meter bar counter
# TYPE bar_milliseconds_total counter
bar_milliseconds_total{otel_scope_name="meterbar",otel_scope_version="v0.1.0",type="bar"} 200
# HELP foo_milliseconds_total meter foo counter
# TYPE foo_milliseconds_total counter
foo_milliseconds_total{otel_scope_name="meterfoo",otel_scope_version="v0.1.0",type="foo"} 100
# HELP bar_seconds_total meter bar counter
# TYPE bar_seconds_total counter
bar_seconds_total{otel_scope_name="meterbar",otel_scope_version="v0.1.0",type="bar"} 200
# HELP foo_seconds_total meter foo counter
# TYPE foo_seconds_total counter
foo_seconds_total{otel_scope_name="meterfoo",otel_scope_version="v0.1.0",type="foo"} 100
# HELP otel_scope_info Instrumentation Scope metadata
# TYPE otel_scope_info gauge
otel_scope_info{otel_scope_name="meterfoo",otel_scope_version="v0.1.0"} 1
Expand Down

0 comments on commit 2ea8f85

Please sign in to comment.