Skip to content

Commit

Permalink
config: add support for temporality configuration (#5860)
Browse files Browse the repository at this point in the history
This adds functionality to set temporality preferences for exporters in
the configuration of metric exporters.

---------

Signed-off-by: Alex Boten <[email protected]>
Co-authored-by: Damien Mathieu <[email protected]>
  • Loading branch information
codeboten and dmathieu authored Oct 9, 2024
1 parent 9393fc0 commit 355fbbd
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 1 deletion.
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
- Move examples from `go.opentelemetry.io/otel` to this repository under `examples` directory. (#6158)
- Support yaml/json struct tags for generated code in `go.opentelemetry.io/contrib/config`. (#5433)
- Add support for parsing YAML configuration via `ParseYAML` in `go.opentelemetry.io/contrib/config`. (#5433)
- Add support for temporality preference configuration in `go.opentelemetry.io/contrib/config`. (#5860)

### Changed

Expand Down
47 changes: 47 additions & 0 deletions config/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"go.opentelemetry.io/otel/metric/noop"
"go.opentelemetry.io/otel/sdk/instrumentation"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/resource"
)

Expand Down Expand Up @@ -167,6 +168,18 @@ func otlpHTTPMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
if len(otlpConfig.Headers) > 0 {
opts = append(opts, otlpmetrichttp.WithHeaders(otlpConfig.Headers))
}
if otlpConfig.TemporalityPreference != nil {
switch *otlpConfig.TemporalityPreference {
case "delta":
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(deltaTemporality))
case "cumulative":
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(cumulativeTemporality))
case "lowmemory":
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(lowMemory))
default:
return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference)
}
}

return otlpmetrichttp.New(ctx, opts...)
}
Expand Down Expand Up @@ -210,10 +223,44 @@ func otlpGRPCMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
if len(otlpConfig.Headers) > 0 {
opts = append(opts, otlpmetricgrpc.WithHeaders(otlpConfig.Headers))
}
if otlpConfig.TemporalityPreference != nil {
switch *otlpConfig.TemporalityPreference {
case "delta":
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(deltaTemporality))
case "cumulative":
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(cumulativeTemporality))
case "lowmemory":
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(lowMemory))
default:
return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference)
}
}

return otlpmetricgrpc.New(ctx, opts...)
}

func cumulativeTemporality(sdkmetric.InstrumentKind) metricdata.Temporality {
return metricdata.CumulativeTemporality
}

func deltaTemporality(ik sdkmetric.InstrumentKind) metricdata.Temporality {
switch ik {
case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindHistogram, sdkmetric.InstrumentKindObservableCounter:
return metricdata.DeltaTemporality
default:
return metricdata.CumulativeTemporality
}
}

func lowMemory(ik sdkmetric.InstrumentKind) metricdata.Temporality {
switch ik {
case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindHistogram:
return metricdata.DeltaTemporality
default:
return metricdata.CumulativeTemporality
}
}

func prometheusReader(ctx context.Context, prometheusConfig *Prometheus) (sdkmetric.Reader, error) {
var opts []otelprom.Option
if prometheusConfig.Host == nil {
Expand Down
162 changes: 161 additions & 1 deletion config/metric_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func TestReader(t *testing.T) {
wantErr: &url.Error{Op: "parse", URL: " ", Err: errors.New("invalid URI for request")},
},
{
name: "periodic/grpc-http-none-compression",
name: "periodic/otlp-grpc-none-compression",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
Expand All @@ -289,6 +289,86 @@ func TestReader(t *testing.T) {
},
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
},
{
name: "periodic/otlp-grpc-delta-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "grpc/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("delta"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
},
{
name: "periodic/otlp-grpc-cumulative-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "grpc/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("cumulative"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
},
{
name: "periodic/otlp-grpc-lowmemory-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "grpc/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("lowmemory"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
},
{
name: "periodic/otlp-grpc-invalid-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "grpc/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("invalid"),
},
},
},
},
wantErr: errors.New("unsupported temporality preference \"invalid\""),
},
{
name: "periodic/otlp-grpc-invalid-compression",
reader: MetricReader{
Expand Down Expand Up @@ -421,6 +501,86 @@ func TestReader(t *testing.T) {
},
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
},
{
name: "periodic/otlp-http-cumulative-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "http/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("cumulative"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
},
{
name: "periodic/otlp-http-lowmemory-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "http/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("lowmemory"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
},
{
name: "periodic/otlp-http-delta-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "http/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("delta"),
},
},
},
},
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
},
{
name: "periodic/otlp-http-invalid-temporality",
reader: MetricReader{
Periodic: &PeriodicMetricReader{
Exporter: MetricExporter{
OTLP: &OTLPMetric{
Protocol: "http/protobuf",
Endpoint: "localhost:4318",
Compression: ptr("none"),
Timeout: ptr(1000),
Headers: map[string]string{
"test": "test1",
},
TemporalityPreference: ptr("invalid"),
},
},
},
},
wantErr: errors.New("unsupported temporality preference \"invalid\""),
},
{
name: "periodic/otlp-http-invalid-compression",
reader: MetricReader{
Expand Down

0 comments on commit 355fbbd

Please sign in to comment.