1// Copyright The OpenTelemetry Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
16
17import (
18	"go.opentelemetry.io/otel/metric/sdkapi"
19	export "go.opentelemetry.io/otel/sdk/export/metric"
20	"go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
21	"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
22	"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
23	"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
24	"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
25)
26
27type (
28	selectorInexpensive struct{}
29	selectorExact       struct{}
30	selectorHistogram   struct {
31		options []histogram.Option
32	}
33)
34
35var (
36	_ export.AggregatorSelector = selectorInexpensive{}
37	_ export.AggregatorSelector = selectorExact{}
38	_ export.AggregatorSelector = selectorHistogram{}
39)
40
41// NewWithInexpensiveDistribution returns a simple aggregator selector
42// that uses minmaxsumcount aggregators for `Histogram`
43// instruments.  This selector is faster and uses less memory than the
44// others in this package because minmaxsumcount aggregators maintain
45// the least information about the distribution among these choices.
46func NewWithInexpensiveDistribution() export.AggregatorSelector {
47	return selectorInexpensive{}
48}
49
50// NewWithExactDistribution returns a simple aggregator selector that
51// uses exact aggregators for `Histogram` instruments.  This
52// selector uses more memory than the others in this package because
53// exact aggregators maintain the most information about the
54// distribution among these choices.
55func NewWithExactDistribution() export.AggregatorSelector {
56	return selectorExact{}
57}
58
59// NewWithHistogramDistribution returns a simple aggregator selector
60// that uses histogram aggregators for `Histogram` instruments.
61// This selector is a good default choice for most metric exporters.
62func NewWithHistogramDistribution(options ...histogram.Option) export.AggregatorSelector {
63	return selectorHistogram{options: options}
64}
65
66func sumAggs(aggPtrs []*export.Aggregator) {
67	aggs := sum.New(len(aggPtrs))
68	for i := range aggPtrs {
69		*aggPtrs[i] = &aggs[i]
70	}
71}
72
73func lastValueAggs(aggPtrs []*export.Aggregator) {
74	aggs := lastvalue.New(len(aggPtrs))
75	for i := range aggPtrs {
76		*aggPtrs[i] = &aggs[i]
77	}
78}
79
80func (selectorInexpensive) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
81	switch descriptor.InstrumentKind() {
82	case sdkapi.GaugeObserverInstrumentKind:
83		lastValueAggs(aggPtrs)
84	case sdkapi.HistogramInstrumentKind:
85		aggs := minmaxsumcount.New(len(aggPtrs), descriptor)
86		for i := range aggPtrs {
87			*aggPtrs[i] = &aggs[i]
88		}
89	default:
90		sumAggs(aggPtrs)
91	}
92}
93
94func (selectorExact) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
95	switch descriptor.InstrumentKind() {
96	case sdkapi.GaugeObserverInstrumentKind:
97		lastValueAggs(aggPtrs)
98	case sdkapi.HistogramInstrumentKind:
99		aggs := exact.New(len(aggPtrs))
100		for i := range aggPtrs {
101			*aggPtrs[i] = &aggs[i]
102		}
103	default:
104		sumAggs(aggPtrs)
105	}
106}
107
108func (s selectorHistogram) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
109	switch descriptor.InstrumentKind() {
110	case sdkapi.GaugeObserverInstrumentKind:
111		lastValueAggs(aggPtrs)
112	case sdkapi.HistogramInstrumentKind:
113		aggs := histogram.New(len(aggPtrs), descriptor, s.options...)
114		for i := range aggPtrs {
115			*aggPtrs[i] = &aggs[i]
116		}
117	default:
118		sumAggs(aggPtrs)
119	}
120}
121