mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-01-10 00:29:12 +02:00
Add WithoutCounterSuffixes option in go.opentelemetry.io/otel/exporters/prometheus to disable addition of _total suffixes (#4306)
This commit is contained in:
parent
55fb2bb57b
commit
03b8c47770
@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
- Add `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)
|
||||
- Add `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272)
|
||||
- Add `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272)
|
||||
- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#TODO)
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -24,12 +24,13 @@ import (
|
||||
|
||||
// config contains options for the exporter.
|
||||
type config struct {
|
||||
registerer prometheus.Registerer
|
||||
disableTargetInfo bool
|
||||
withoutUnits bool
|
||||
aggregation metric.AggregationSelector
|
||||
disableScopeInfo bool
|
||||
namespace string
|
||||
registerer prometheus.Registerer
|
||||
disableTargetInfo bool
|
||||
withoutUnits bool
|
||||
withoutCounterSuffixes bool
|
||||
aggregation metric.AggregationSelector
|
||||
disableScopeInfo bool
|
||||
namespace string
|
||||
}
|
||||
|
||||
// newConfig creates a validated config configured with options.
|
||||
@ -110,6 +111,19 @@ func WithoutUnits() Option {
|
||||
})
|
||||
}
|
||||
|
||||
// WithoutUnits disables exporter's addition _total suffixes on counters.
|
||||
//
|
||||
// By default, metric names include a _total suffix to follow Prometheus naming
|
||||
// conventions. For example, the counter metric happy.people would become
|
||||
// happy_people_total. With this option set, the name would instead be
|
||||
// happy_people.
|
||||
func WithoutCounterSuffixes() Option {
|
||||
return optionFunc(func(cfg config) config {
|
||||
cfg.withoutCounterSuffixes = true
|
||||
return cfg
|
||||
})
|
||||
}
|
||||
|
||||
// WithoutScopeInfo configures the Exporter to not export the otel_scope_info metric.
|
||||
// If not specified, the Exporter will create a otel_scope_info metric containing
|
||||
// the metrics' Instrumentation Scope, and also add labels about Instrumentation Scope to all metric points.
|
||||
|
@ -59,9 +59,10 @@ var _ metric.Reader = &Exporter{}
|
||||
type collector struct {
|
||||
reader metric.Reader
|
||||
|
||||
withoutUnits bool
|
||||
disableScopeInfo bool
|
||||
namespace string
|
||||
withoutUnits bool
|
||||
withoutCounterSuffixes bool
|
||||
disableScopeInfo bool
|
||||
namespace string
|
||||
|
||||
mu sync.Mutex // mu protects all members below from the concurrent access.
|
||||
disableTargetInfo bool
|
||||
@ -70,7 +71,7 @@ type collector struct {
|
||||
metricFamilies map[string]*dto.MetricFamily
|
||||
}
|
||||
|
||||
// prometheus counters MUST have a _total suffix:
|
||||
// prometheus counters MUST have a _total suffix by default:
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/compatibility/prometheus_and_openmetrics.md
|
||||
const counterSuffix = "_total"
|
||||
|
||||
@ -84,13 +85,14 @@ func New(opts ...Option) (*Exporter, error) {
|
||||
reader := metric.NewManualReader(cfg.manualReaderOptions()...)
|
||||
|
||||
collector := &collector{
|
||||
reader: reader,
|
||||
disableTargetInfo: cfg.disableTargetInfo,
|
||||
withoutUnits: cfg.withoutUnits,
|
||||
disableScopeInfo: cfg.disableScopeInfo,
|
||||
scopeInfos: make(map[instrumentation.Scope]prometheus.Metric),
|
||||
metricFamilies: make(map[string]*dto.MetricFamily),
|
||||
namespace: cfg.namespace,
|
||||
reader: reader,
|
||||
disableTargetInfo: cfg.disableTargetInfo,
|
||||
withoutUnits: cfg.withoutUnits,
|
||||
withoutCounterSuffixes: cfg.withoutCounterSuffixes,
|
||||
disableScopeInfo: cfg.disableScopeInfo,
|
||||
scopeInfos: make(map[instrumentation.Scope]prometheus.Metric),
|
||||
metricFamilies: make(map[string]*dto.MetricFamily),
|
||||
namespace: cfg.namespace,
|
||||
}
|
||||
|
||||
if err := cfg.registerer.Register(collector); err != nil {
|
||||
@ -387,12 +389,12 @@ func (c *collector) metricTypeAndName(m metricdata.Metrics) (*dto.MetricType, st
|
||||
case metricdata.Histogram[int64], metricdata.Histogram[float64]:
|
||||
return dto.MetricType_HISTOGRAM.Enum(), name
|
||||
case metricdata.Sum[float64]:
|
||||
if v.IsMonotonic {
|
||||
if v.IsMonotonic && !c.withoutCounterSuffixes {
|
||||
return dto.MetricType_COUNTER.Enum(), name + counterSuffix
|
||||
}
|
||||
return dto.MetricType_GAUGE.Enum(), name
|
||||
case metricdata.Sum[int64]:
|
||||
if v.IsMonotonic {
|
||||
if v.IsMonotonic && !c.withoutCounterSuffixes {
|
||||
return dto.MetricType_COUNTER.Enum(), name + counterSuffix
|
||||
}
|
||||
return dto.MetricType_GAUGE.Enum(), name
|
||||
|
@ -71,6 +71,36 @@ func TestPrometheusExporter(t *testing.T) {
|
||||
counter.Add(ctx, 5, otelmetric.WithAttributeSet(attrs2))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "counter with suffixes disabled",
|
||||
expectedFile: "testdata/counter_disabled_suffix.txt",
|
||||
options: []Option{WithoutCounterSuffixes()},
|
||||
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 without a total suffix"),
|
||||
otelmetric.WithUnit("ms"),
|
||||
)
|
||||
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: "gauge",
|
||||
expectedFile: "testdata/gauge.txt",
|
||||
|
10
exporters/prometheus/testdata/counter_disabled_suffix.txt
vendored
Executable file
10
exporters/prometheus/testdata/counter_disabled_suffix.txt
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
# 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 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
|
||||
# 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
|
Loading…
Reference in New Issue
Block a user