Skip to content

Commit 355fbbd

Browse files
codebotendmathieu
andauthored
config: add support for temporality configuration (#5860)
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]>
1 parent 9393fc0 commit 355fbbd

File tree

3 files changed

+209
-1
lines changed

3 files changed

+209
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1414
- Move examples from `go.opentelemetry.io/otel` to this repository under `examples` directory. (#6158)
1515
- Support yaml/json struct tags for generated code in `go.opentelemetry.io/contrib/config`. (#5433)
1616
- Add support for parsing YAML configuration via `ParseYAML` in `go.opentelemetry.io/contrib/config`. (#5433)
17+
- Add support for temporality preference configuration in `go.opentelemetry.io/contrib/config`. (#5860)
1718

1819
### Changed
1920

config/metric.go

+47
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"go.opentelemetry.io/otel/metric/noop"
2929
"go.opentelemetry.io/otel/sdk/instrumentation"
3030
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
31+
"go.opentelemetry.io/otel/sdk/metric/metricdata"
3132
"go.opentelemetry.io/otel/sdk/resource"
3233
)
3334

@@ -167,6 +168,18 @@ func otlpHTTPMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
167168
if len(otlpConfig.Headers) > 0 {
168169
opts = append(opts, otlpmetrichttp.WithHeaders(otlpConfig.Headers))
169170
}
171+
if otlpConfig.TemporalityPreference != nil {
172+
switch *otlpConfig.TemporalityPreference {
173+
case "delta":
174+
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(deltaTemporality))
175+
case "cumulative":
176+
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(cumulativeTemporality))
177+
case "lowmemory":
178+
opts = append(opts, otlpmetrichttp.WithTemporalitySelector(lowMemory))
179+
default:
180+
return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference)
181+
}
182+
}
170183

171184
return otlpmetrichttp.New(ctx, opts...)
172185
}
@@ -210,10 +223,44 @@ func otlpGRPCMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
210223
if len(otlpConfig.Headers) > 0 {
211224
opts = append(opts, otlpmetricgrpc.WithHeaders(otlpConfig.Headers))
212225
}
226+
if otlpConfig.TemporalityPreference != nil {
227+
switch *otlpConfig.TemporalityPreference {
228+
case "delta":
229+
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(deltaTemporality))
230+
case "cumulative":
231+
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(cumulativeTemporality))
232+
case "lowmemory":
233+
opts = append(opts, otlpmetricgrpc.WithTemporalitySelector(lowMemory))
234+
default:
235+
return nil, fmt.Errorf("unsupported temporality preference %q", *otlpConfig.TemporalityPreference)
236+
}
237+
}
213238

214239
return otlpmetricgrpc.New(ctx, opts...)
215240
}
216241

242+
func cumulativeTemporality(sdkmetric.InstrumentKind) metricdata.Temporality {
243+
return metricdata.CumulativeTemporality
244+
}
245+
246+
func deltaTemporality(ik sdkmetric.InstrumentKind) metricdata.Temporality {
247+
switch ik {
248+
case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindHistogram, sdkmetric.InstrumentKindObservableCounter:
249+
return metricdata.DeltaTemporality
250+
default:
251+
return metricdata.CumulativeTemporality
252+
}
253+
}
254+
255+
func lowMemory(ik sdkmetric.InstrumentKind) metricdata.Temporality {
256+
switch ik {
257+
case sdkmetric.InstrumentKindCounter, sdkmetric.InstrumentKindHistogram:
258+
return metricdata.DeltaTemporality
259+
default:
260+
return metricdata.CumulativeTemporality
261+
}
262+
}
263+
217264
func prometheusReader(ctx context.Context, prometheusConfig *Prometheus) (sdkmetric.Reader, error) {
218265
var opts []otelprom.Option
219266
if prometheusConfig.Host == nil {

config/metric_test.go

+161-1
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ func TestReader(t *testing.T) {
271271
wantErr: &url.Error{Op: "parse", URL: " ", Err: errors.New("invalid URI for request")},
272272
},
273273
{
274-
name: "periodic/grpc-http-none-compression",
274+
name: "periodic/otlp-grpc-none-compression",
275275
reader: MetricReader{
276276
Periodic: &PeriodicMetricReader{
277277
Exporter: MetricExporter{
@@ -289,6 +289,86 @@ func TestReader(t *testing.T) {
289289
},
290290
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
291291
},
292+
{
293+
name: "periodic/otlp-grpc-delta-temporality",
294+
reader: MetricReader{
295+
Periodic: &PeriodicMetricReader{
296+
Exporter: MetricExporter{
297+
OTLP: &OTLPMetric{
298+
Protocol: "grpc/protobuf",
299+
Endpoint: "localhost:4318",
300+
Compression: ptr("none"),
301+
Timeout: ptr(1000),
302+
Headers: map[string]string{
303+
"test": "test1",
304+
},
305+
TemporalityPreference: ptr("delta"),
306+
},
307+
},
308+
},
309+
},
310+
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
311+
},
312+
{
313+
name: "periodic/otlp-grpc-cumulative-temporality",
314+
reader: MetricReader{
315+
Periodic: &PeriodicMetricReader{
316+
Exporter: MetricExporter{
317+
OTLP: &OTLPMetric{
318+
Protocol: "grpc/protobuf",
319+
Endpoint: "localhost:4318",
320+
Compression: ptr("none"),
321+
Timeout: ptr(1000),
322+
Headers: map[string]string{
323+
"test": "test1",
324+
},
325+
TemporalityPreference: ptr("cumulative"),
326+
},
327+
},
328+
},
329+
},
330+
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
331+
},
332+
{
333+
name: "periodic/otlp-grpc-lowmemory-temporality",
334+
reader: MetricReader{
335+
Periodic: &PeriodicMetricReader{
336+
Exporter: MetricExporter{
337+
OTLP: &OTLPMetric{
338+
Protocol: "grpc/protobuf",
339+
Endpoint: "localhost:4318",
340+
Compression: ptr("none"),
341+
Timeout: ptr(1000),
342+
Headers: map[string]string{
343+
"test": "test1",
344+
},
345+
TemporalityPreference: ptr("lowmemory"),
346+
},
347+
},
348+
},
349+
},
350+
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
351+
},
352+
{
353+
name: "periodic/otlp-grpc-invalid-temporality",
354+
reader: MetricReader{
355+
Periodic: &PeriodicMetricReader{
356+
Exporter: MetricExporter{
357+
OTLP: &OTLPMetric{
358+
Protocol: "grpc/protobuf",
359+
Endpoint: "localhost:4318",
360+
Compression: ptr("none"),
361+
Timeout: ptr(1000),
362+
Headers: map[string]string{
363+
"test": "test1",
364+
},
365+
TemporalityPreference: ptr("invalid"),
366+
},
367+
},
368+
},
369+
},
370+
wantErr: errors.New("unsupported temporality preference \"invalid\""),
371+
},
292372
{
293373
name: "periodic/otlp-grpc-invalid-compression",
294374
reader: MetricReader{
@@ -421,6 +501,86 @@ func TestReader(t *testing.T) {
421501
},
422502
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
423503
},
504+
{
505+
name: "periodic/otlp-http-cumulative-temporality",
506+
reader: MetricReader{
507+
Periodic: &PeriodicMetricReader{
508+
Exporter: MetricExporter{
509+
OTLP: &OTLPMetric{
510+
Protocol: "http/protobuf",
511+
Endpoint: "localhost:4318",
512+
Compression: ptr("none"),
513+
Timeout: ptr(1000),
514+
Headers: map[string]string{
515+
"test": "test1",
516+
},
517+
TemporalityPreference: ptr("cumulative"),
518+
},
519+
},
520+
},
521+
},
522+
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
523+
},
524+
{
525+
name: "periodic/otlp-http-lowmemory-temporality",
526+
reader: MetricReader{
527+
Periodic: &PeriodicMetricReader{
528+
Exporter: MetricExporter{
529+
OTLP: &OTLPMetric{
530+
Protocol: "http/protobuf",
531+
Endpoint: "localhost:4318",
532+
Compression: ptr("none"),
533+
Timeout: ptr(1000),
534+
Headers: map[string]string{
535+
"test": "test1",
536+
},
537+
TemporalityPreference: ptr("lowmemory"),
538+
},
539+
},
540+
},
541+
},
542+
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
543+
},
544+
{
545+
name: "periodic/otlp-http-delta-temporality",
546+
reader: MetricReader{
547+
Periodic: &PeriodicMetricReader{
548+
Exporter: MetricExporter{
549+
OTLP: &OTLPMetric{
550+
Protocol: "http/protobuf",
551+
Endpoint: "localhost:4318",
552+
Compression: ptr("none"),
553+
Timeout: ptr(1000),
554+
Headers: map[string]string{
555+
"test": "test1",
556+
},
557+
TemporalityPreference: ptr("delta"),
558+
},
559+
},
560+
},
561+
},
562+
wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter),
563+
},
564+
{
565+
name: "periodic/otlp-http-invalid-temporality",
566+
reader: MetricReader{
567+
Periodic: &PeriodicMetricReader{
568+
Exporter: MetricExporter{
569+
OTLP: &OTLPMetric{
570+
Protocol: "http/protobuf",
571+
Endpoint: "localhost:4318",
572+
Compression: ptr("none"),
573+
Timeout: ptr(1000),
574+
Headers: map[string]string{
575+
"test": "test1",
576+
},
577+
TemporalityPreference: ptr("invalid"),
578+
},
579+
},
580+
},
581+
},
582+
wantErr: errors.New("unsupported temporality preference \"invalid\""),
583+
},
424584
{
425585
name: "periodic/otlp-http-invalid-compression",
426586
reader: MetricReader{

0 commit comments

Comments
 (0)