Skip to content

Commit

Permalink
Add otlpmetric Temporality Preference env var (#4287)
Browse files Browse the repository at this point in the history
* Add otlp metrics env vars

---------

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
  • Loading branch information
MadVikingGod and MrAlias committed Jul 20, 2023
1 parent e08359f commit a5c82bf
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
- OTLP Metrics Exporter now supports the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287)
- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306)
- Add info and debug logging to the metric SDK. (#4315)

Expand Down
43 changes: 43 additions & 0 deletions exporters/otlp/otlpmetric/internal/oconf/envconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import (
"time"

"go.opentelemetry.io/otel/exporters/otlp/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.
Expand Down Expand Up @@ -96,6 +99,7 @@ func getOptionsFromEnv() []GenericOption {
WithEnvCompression("METRICS_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }),
envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }),
envconfig.WithDuration("METRICS_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }),
withEnvTemporalityPreference("METRICS_TEMPORALITY_PREFERENCE", func(t metric.TemporalitySelector) { opts = append(opts, WithTemporalitySelector(t)) }),
)

return opts
Expand Down Expand Up @@ -148,3 +152,42 @@ 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
}
}

func lowMemory(ik metric.InstrumentKind) metricdata.Temporality {
switch ik {
case metric.InstrumentKindCounter, metric.InstrumentKindHistogram:
return metricdata.DeltaTemporality
default:
return metricdata.CumulativeTemporality
}
}
103 changes: 103 additions & 0 deletions exporters/otlp/otlpmetric/internal/oconf/envconfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package oconf

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
)

func TestWithEnvTemporalityPreference(t *testing.T) {
origReader := DefaultEnvOptionsReader.GetEnv
tests := []struct {
name string
envValue string
want map[metric.InstrumentKind]metricdata.Temporality
}{
{
name: "default do not set the selector",
envValue: "",
},
{
name: "non-normative do not set the selector",
envValue: "non-normative",
},
{
name: "cumulative",
envValue: "cumulative",
want: map[metric.InstrumentKind]metricdata.Temporality{
metric.InstrumentKindCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindHistogram: metricdata.CumulativeTemporality,
metric.InstrumentKindUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableGauge: metricdata.CumulativeTemporality,
},
},
{
name: "delta",
envValue: "delta",
want: map[metric.InstrumentKind]metricdata.Temporality{
metric.InstrumentKindCounter: metricdata.DeltaTemporality,
metric.InstrumentKindHistogram: metricdata.DeltaTemporality,
metric.InstrumentKindUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableCounter: metricdata.DeltaTemporality,
metric.InstrumentKindObservableUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableGauge: metricdata.CumulativeTemporality,
},
},
{
name: "lowmemory",
envValue: "lowmemory",
want: map[metric.InstrumentKind]metricdata.Temporality{
metric.InstrumentKindCounter: metricdata.DeltaTemporality,
metric.InstrumentKindHistogram: metricdata.DeltaTemporality,
metric.InstrumentKindUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableUpDownCounter: metricdata.CumulativeTemporality,
metric.InstrumentKindObservableGauge: metricdata.CumulativeTemporality,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
DefaultEnvOptionsReader.GetEnv = func(key string) string {
if key == "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE" {
return tt.envValue
}
return origReader(key)
}
cfg := Config{}
cfg = ApplyGRPCEnvConfigs(cfg)

if tt.want == nil {
// There is no function set, the SDK's default is used.
assert.Nil(t, cfg.Metrics.TemporalitySelector)
return
}

require.NotNil(t, cfg.Metrics.TemporalitySelector)
for ik, want := range tt.want {
assert.Equal(t, want, cfg.Metrics.TemporalitySelector(ik))
}
})
}
DefaultEnvOptionsReader.GetEnv = origReader
}

0 comments on commit a5c82bf

Please sign in to comment.