diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go index b54a173b6ea..db538e2e6f4 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/envconfig.go @@ -18,7 +18,6 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envconfig" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" ) // DefaultEnvOptionsReader is the default environments reader. @@ -163,43 +162,18 @@ func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOpt func withEnvTemporalityPreference(n string, fn func(metric.TemporalitySelector)) func(e *envconfig.EnvOptionsReader) { return func(e *envconfig.EnvOptionsReader) { if s, ok := e.GetEnvValue(n); ok { - switch strings.ToLower(s) { - case "cumulative": - fn(cumulativeTemporality) - case "delta": - fn(deltaTemporality) - case "lowmemory": - fn(lowMemory) - default: - global.Warn( - "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", - "value", - s, - ) - } - } - } -} - -func cumulativeTemporality(metric.InstrumentKind) metricdata.Temporality { - return metricdata.CumulativeTemporality -} -func deltaTemporality(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram, metric.InstrumentKindObservableCounter: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality - } -} + if pref := metric.TemporalityPreference(s); pref.IsValid() { + fn(metric.TemporalitySelectorForPreference(pref)) + return + } -func lowMemory(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality + global.Warn( + "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", + "value", + s, + ) + } } } diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go index 758d1ea32da..9238853fcca 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf/options.go @@ -361,6 +361,13 @@ func WithTemporalitySelector(selector metric.TemporalitySelector) GenericOption }) } +func WithTemporalityPreference(pref metric.TemporalityPreference) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Metrics.TemporalitySelector = metric.TemporalitySelectorForPreference(pref) + return cfg + }) +} + func WithAggregationSelector(selector metric.AggregationSelector) GenericOption { return newGenericOption(func(cfg Config) Config { cfg.Metrics.AggregationSelector = selector diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go index ef318ac676c..ec28b54495b 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/envconfig.go @@ -18,7 +18,6 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/envconfig" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" ) // DefaultEnvOptionsReader is the default environments reader. @@ -163,43 +162,18 @@ func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOpt func withEnvTemporalityPreference(n string, fn func(metric.TemporalitySelector)) func(e *envconfig.EnvOptionsReader) { return func(e *envconfig.EnvOptionsReader) { if s, ok := e.GetEnvValue(n); ok { - switch strings.ToLower(s) { - case "cumulative": - fn(cumulativeTemporality) - case "delta": - fn(deltaTemporality) - case "lowmemory": - fn(lowMemory) - default: - global.Warn( - "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", - "value", - s, - ) - } - } - } -} - -func cumulativeTemporality(metric.InstrumentKind) metricdata.Temporality { - return metricdata.CumulativeTemporality -} -func deltaTemporality(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram, metric.InstrumentKindObservableCounter: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality - } -} + if pref := metric.TemporalityPreference(s); pref.IsValid() { + fn(metric.TemporalitySelectorForPreference(pref)) + return + } -func lowMemory(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality + global.Warn( + "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", + "value", + s, + ) + } } } diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go index ed66bb0682a..1632383abfc 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf/options.go @@ -361,6 +361,13 @@ func WithTemporalitySelector(selector metric.TemporalitySelector) GenericOption }) } +func WithTemporalityPreference(pref metric.TemporalityPreference) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Metrics.TemporalitySelector = metric.TemporalitySelectorForPreference(pref) + return cfg + }) +} + func WithAggregationSelector(selector metric.AggregationSelector) GenericOption { return newGenericOption(func(cfg Config) Config { cfg.Metrics.AggregationSelector = selector diff --git a/internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl b/internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl index 3c864710351..79e957ca7b3 100644 --- a/internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl +++ b/internal/shared/otlp/otlpmetric/oconf/envconfig.go.tmpl @@ -18,7 +18,6 @@ import ( "{{ .envconfigImportPath }}" "go.opentelemetry.io/otel/internal/global" "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" ) // DefaultEnvOptionsReader is the default environments reader. @@ -163,43 +162,18 @@ func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOpt func withEnvTemporalityPreference(n string, fn func(metric.TemporalitySelector)) func(e *envconfig.EnvOptionsReader) { return func(e *envconfig.EnvOptionsReader) { if s, ok := e.GetEnvValue(n); ok { - switch strings.ToLower(s) { - case "cumulative": - fn(cumulativeTemporality) - case "delta": - fn(deltaTemporality) - case "lowmemory": - fn(lowMemory) - default: - global.Warn( - "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", - "value", - s, - ) - } - } - } -} - -func cumulativeTemporality(metric.InstrumentKind) metricdata.Temporality { - return metricdata.CumulativeTemporality -} -func deltaTemporality(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram, metric.InstrumentKindObservableCounter: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality - } -} + if pref := metric.TemporalityPreference(s); pref.IsValid() { + fn(metric.TemporalitySelectorForPreference(pref)) + return + } -func lowMemory(ik metric.InstrumentKind) metricdata.Temporality { - switch ik { - case metric.InstrumentKindCounter, metric.InstrumentKindHistogram: - return metricdata.DeltaTemporality - default: - return metricdata.CumulativeTemporality + global.Warn( + "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE is set to an invalid value, ignoring.", + "value", + s, + ) + } } } diff --git a/internal/shared/otlp/otlpmetric/oconf/options.go.tmpl b/internal/shared/otlp/otlpmetric/oconf/options.go.tmpl index 3d037311094..74bb9feb700 100644 --- a/internal/shared/otlp/otlpmetric/oconf/options.go.tmpl +++ b/internal/shared/otlp/otlpmetric/oconf/options.go.tmpl @@ -361,6 +361,13 @@ func WithTemporalitySelector(selector metric.TemporalitySelector) GenericOption }) } +func WithTemporalityPreference(pref metric.TemporalityPreference) GenericOption { + return newGenericOption(func(cfg Config) Config { + cfg.Metrics.TemporalitySelector = metric.TemporalitySelectorForPreference(pref) + return cfg + }) +} + func WithAggregationSelector(selector metric.AggregationSelector) GenericOption { return newGenericOption(func(cfg Config) Config { cfg.Metrics.AggregationSelector = selector diff --git a/sdk/metric/reader.go b/sdk/metric/reader.go index 5c1cea8254e..7b205c736c2 100644 --- a/sdk/metric/reader.go +++ b/sdk/metric/reader.go @@ -127,10 +127,40 @@ type TemporalitySelector func(InstrumentKind) metricdata.Temporality // DefaultTemporalitySelector is the default TemporalitySelector used if // WithTemporalitySelector is not provided. CumulativeTemporality will be used // for all instrument kinds if this TemporalitySelector is used. -func DefaultTemporalitySelector(InstrumentKind) metricdata.Temporality { +func DefaultTemporalitySelector(k InstrumentKind) metricdata.Temporality { + return CumulativeTemporalitySelector(k) +} + +// CumulativeTemporalitySelector is the TemporalitySelector that uses +// a cumulative temporality for all instrument kinds. +func CumulativeTemporalitySelector(InstrumentKind) metricdata.Temporality { return metricdata.CumulativeTemporality } +// DeltaTemporalitySelector is the TemporalitySelector that uses +// a delta temporality for instrument kinds: counter, histogram, observable counter +// All other instruments use cumulative temporality. +func DeltaTemporalitySelector(k InstrumentKind) metricdata.Temporality { + switch k { + case InstrumentKindCounter, InstrumentKindHistogram, InstrumentKindObservableCounter: + return metricdata.DeltaTemporality + default: + return metricdata.CumulativeTemporality + } +} + +// LowMemoryTemporalitySelector is the TemporalitySelector that uses +// delta temporality for counters and histograms. All other instruments use +// cumulative temporality. +func LowMemoryTemporalitySelector(k InstrumentKind) metricdata.Temporality { + switch k { + case InstrumentKindCounter, InstrumentKindHistogram: + return metricdata.DeltaTemporality + default: + return metricdata.CumulativeTemporality + } +} + // AggregationSelector selects the aggregation and the parameters to use for // that aggregation based on the InstrumentKind. // diff --git a/sdk/metric/temporality.go b/sdk/metric/temporality.go new file mode 100644 index 00000000000..bb6a01f4e25 --- /dev/null +++ b/sdk/metric/temporality.go @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package metric // import "go.opentelemetry.io/otel/sdk/metric" + +import "strings" + +// TemporalityPreference defines the user's desired temporality for metrics instruments. +type TemporalityPreference string + +const ( + // TemporalityPreferenceDefault indicates the SDK's default temporality should be used. + TemporalityPreferenceDefault TemporalityPreference = "" + + // TemporalityPreferenceCumulative indicates a cumulative temporality should be used. + TemporalityPreferenceCumulative TemporalityPreference = "cumulative" + + // TemporalityPreferenceDelta indicates a delta temporality should be used. + TemporalityPreferenceDelta TemporalityPreference = "delta" + + // TemporalityPreferenceLowMemory indicates temporality preference that optimizes memory use. + TemporalityPreferenceLowMemory TemporalityPreference = "lowmemory" +) + +// IsValid returns true whether the preference is a valid string constant. +func (t TemporalityPreference) IsValid() bool { + switch t.lowercase() { + case TemporalityPreferenceCumulative, + TemporalityPreferenceDelta, + TemporalityPreferenceLowMemory, + TemporalityPreferenceDefault: + return true + default: + return false + } +} + +func (t TemporalityPreference) lowercase() TemporalityPreference { + return TemporalityPreference(strings.ToLower(string(t))) +} + +// TemporalitySelectorForPreference will return a TemporalitySelector for the given preference. +func TemporalitySelectorForPreference(t TemporalityPreference) TemporalitySelector { + switch t.lowercase() { + case TemporalityPreferenceCumulative: + return CumulativeTemporalitySelector + case TemporalityPreferenceDelta: + return DeltaTemporalitySelector + case TemporalityPreferenceLowMemory: + return LowMemoryTemporalitySelector + default: + return DefaultTemporalitySelector + } +}