1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-04-25 12:04:40 +02:00

Remove metric options; rename "counter" aggregator to "sum" (#541)

* Remove options (mostly)

* Rename counter aggregator to 'sum'

* Fix prometheus test

* Rewordings from feedback
This commit is contained in:
Joshua MacDonald 2020-03-11 20:21:34 -07:00 committed by GitHub
parent d9210f5676
commit 23e65ac79d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 368 additions and 865 deletions

View File

@ -12,9 +12,9 @@ import (
"go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/api/trace"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch" "go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
sdktrace "go.opentelemetry.io/otel/sdk/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace"
) )
@ -41,7 +41,7 @@ func newFixture(b *testing.B) *benchFixture {
func (*benchFixture) AggregatorFor(descriptor *export.Descriptor) export.Aggregator { func (*benchFixture) AggregatorFor(descriptor *export.Descriptor) export.Aggregator {
switch descriptor.MetricKind() { switch descriptor.MetricKind() {
case export.CounterKind: case export.CounterKind:
return counter.New() return sum.New()
case export.MeasureKind: case export.MeasureKind:
if strings.HasSuffix(descriptor.Name(), "minmaxsumcount") { if strings.HasSuffix(descriptor.Name(), "minmaxsumcount") {
return minmaxsumcount.New(descriptor) return minmaxsumcount.New(descriptor)

View File

@ -68,7 +68,7 @@ type instImpl struct {
name string name string
mkind metricKind mkind metricKind
nkind core.NumberKind nkind core.NumberKind
opts interface{} opts []metric.Option
} }
type obsImpl struct { type obsImpl struct {
@ -76,7 +76,7 @@ type obsImpl struct {
name string name string
nkind core.NumberKind nkind core.NumberKind
opts []metric.ObserverOptionApplier opts []metric.Option
meter *meter meter *meter
callback interface{} callback interface{}
} }
@ -181,7 +181,7 @@ func (m *meter) setDelegate(provider metric.Provider) {
m.orderedObservers = nil m.orderedObservers = nil
} }
func (m *meter) newInst(name string, mkind metricKind, nkind core.NumberKind, opts interface{}) (metric.InstrumentImpl, error) { func (m *meter) newInst(name string, mkind metricKind, nkind core.NumberKind, opts []metric.Option) (metric.InstrumentImpl, error) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
@ -209,18 +209,18 @@ func delegateCheck(has hasImpl, err error) (metric.InstrumentImpl, error) {
return nil, err return nil, err
} }
func newInstDelegate(m metric.Meter, name string, mkind metricKind, nkind core.NumberKind, opts interface{}) (metric.InstrumentImpl, error) { func newInstDelegate(m metric.Meter, name string, mkind metricKind, nkind core.NumberKind, opts []metric.Option) (metric.InstrumentImpl, error) {
switch mkind { switch mkind {
case counterKind: case counterKind:
if nkind == core.Int64NumberKind { if nkind == core.Int64NumberKind {
return delegateCheck(m.NewInt64Counter(name, opts.([]metric.CounterOptionApplier)...)) return delegateCheck(m.NewInt64Counter(name, opts...))
} }
return delegateCheck(m.NewFloat64Counter(name, opts.([]metric.CounterOptionApplier)...)) return delegateCheck(m.NewFloat64Counter(name, opts...))
case measureKind: case measureKind:
if nkind == core.Int64NumberKind { if nkind == core.Int64NumberKind {
return delegateCheck(m.NewInt64Measure(name, opts.([]metric.MeasureOptionApplier)...)) return delegateCheck(m.NewInt64Measure(name, opts...))
} }
return delegateCheck(m.NewFloat64Measure(name, opts.([]metric.MeasureOptionApplier)...)) return delegateCheck(m.NewFloat64Measure(name, opts...))
} }
return nil, errInvalidMetricKind return nil, errInvalidMetricKind
} }
@ -419,34 +419,34 @@ func (labels *labelSet) Delegate() metric.LabelSet {
// Constructors // Constructors
func (m *meter) NewInt64Counter(name string, opts ...metric.CounterOptionApplier) (metric.Int64Counter, error) { func (m *meter) NewInt64Counter(name string, opts ...metric.Option) (metric.Int64Counter, error) {
return metric.WrapInt64CounterInstrument(m.newInst(name, counterKind, core.Int64NumberKind, opts)) return metric.WrapInt64CounterInstrument(m.newInst(name, counterKind, core.Int64NumberKind, opts))
} }
func (m *meter) NewFloat64Counter(name string, opts ...metric.CounterOptionApplier) (metric.Float64Counter, error) { func (m *meter) NewFloat64Counter(name string, opts ...metric.Option) (metric.Float64Counter, error) {
return metric.WrapFloat64CounterInstrument(m.newInst(name, counterKind, core.Float64NumberKind, opts)) return metric.WrapFloat64CounterInstrument(m.newInst(name, counterKind, core.Float64NumberKind, opts))
} }
func (m *meter) NewInt64Measure(name string, opts ...metric.MeasureOptionApplier) (metric.Int64Measure, error) { func (m *meter) NewInt64Measure(name string, opts ...metric.Option) (metric.Int64Measure, error) {
return metric.WrapInt64MeasureInstrument(m.newInst(name, measureKind, core.Int64NumberKind, opts)) return metric.WrapInt64MeasureInstrument(m.newInst(name, measureKind, core.Int64NumberKind, opts))
} }
func (m *meter) NewFloat64Measure(name string, opts ...metric.MeasureOptionApplier) (metric.Float64Measure, error) { func (m *meter) NewFloat64Measure(name string, opts ...metric.Option) (metric.Float64Measure, error) {
return metric.WrapFloat64MeasureInstrument(m.newInst(name, measureKind, core.Float64NumberKind, opts)) return metric.WrapFloat64MeasureInstrument(m.newInst(name, measureKind, core.Float64NumberKind, opts))
} }
func (m *meter) RegisterInt64Observer(name string, callback metric.Int64ObserverCallback, oos ...metric.ObserverOptionApplier) (metric.Int64Observer, error) { func (m *meter) RegisterInt64Observer(name string, callback metric.Int64ObserverCallback, opts ...metric.Option) (metric.Int64Observer, error) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).RegisterInt64Observer(name, callback, oos...) return (*meterPtr).RegisterInt64Observer(name, callback, opts...)
} }
obs := &obsImpl{ obs := &obsImpl{
name: name, name: name,
nkind: core.Int64NumberKind, nkind: core.Int64NumberKind,
opts: oos, opts: opts,
meter: m, meter: m,
callback: callback, callback: callback,
} }
@ -456,18 +456,18 @@ func (m *meter) RegisterInt64Observer(name string, callback metric.Int64Observer
}, nil }, nil
} }
func (m *meter) RegisterFloat64Observer(name string, callback metric.Float64ObserverCallback, oos ...metric.ObserverOptionApplier) (metric.Float64Observer, error) { func (m *meter) RegisterFloat64Observer(name string, callback metric.Float64ObserverCallback, opts ...metric.Option) (metric.Float64Observer, error) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).RegisterFloat64Observer(name, callback, oos...) return (*meterPtr).RegisterFloat64Observer(name, callback, opts...)
} }
obs := &obsImpl{ obs := &obsImpl{
name: name, name: name,
nkind: core.Float64NumberKind, nkind: core.Float64NumberKind,
opts: oos, opts: opts,
meter: m, meter: m,
callback: callback, callback: callback,
} }

View File

@ -278,7 +278,7 @@ func (m *meterProviderWithConstructorError) Meter(name string) metric.Meter {
return &meterWithConstructorError{m.Provider.Meter(name)} return &meterWithConstructorError{m.Provider.Meter(name)}
} }
func (m *meterWithConstructorError) NewInt64Counter(name string, cos ...metric.CounterOptionApplier) (metric.Int64Counter, error) { func (m *meterWithConstructorError) NewInt64Counter(name string, opts ...metric.Option) (metric.Int64Counter, error) {
return metric.Int64Counter{}, errors.New("constructor error") return metric.Int64Counter{}, errors.New("constructor error")
} }

View File

@ -33,8 +33,8 @@ type Provider interface {
type LabelSet interface { type LabelSet interface {
} }
// Options contains some options for metrics of any kind. // Config contains some options for metrics of any kind.
type Options struct { type Config struct {
// Description is an optional field describing the metric // Description is an optional field describing the metric
// instrument. // instrument.
Description string Description string
@ -43,42 +43,12 @@ type Options struct {
// Keys are recommended keys determined in the handles // Keys are recommended keys determined in the handles
// obtained for the metric. // obtained for the metric.
Keys []core.Key Keys []core.Key
// Alternate defines the property of metric value dependent on
// a metric type.
//
// - for Counter, true implies that the metric is an up-down
// Counter
//
// - for Measure, true implies that the metric supports
// positive and negative values
//
// - for Observer, true implies that the metric is a
// non-descending Observer
Alternate bool
} }
// CounterOptionApplier is an interface for applying metric options // Option is an interface for applying metric options.
// that are valid only for counter metrics. type Option interface {
type CounterOptionApplier interface { // Apply is used to set the Option value of a Config.
// ApplyCounterOption is used to make some general or Apply(*Config)
// counter-specific changes in the Options.
ApplyCounterOption(*Options)
}
// MeasureOptionApplier is an interface for applying metric options
// that are valid only for measure metrics.
type MeasureOptionApplier interface {
// ApplyMeasureOption is used to make some general or
// measure-specific changes in the Options.
ApplyMeasureOption(*Options)
}
// ObserverOptionApplier is an interface for applying metric options
// that are valid only for observer metrics.
type ObserverOptionApplier interface {
// ApplyObserverOption is used to make some general or
// observer-specific changes in the Options.
ApplyObserverOption(*Options)
} }
// Measurement is used for reporting a batch of metric // Measurement is used for reporting a batch of metric
@ -119,25 +89,25 @@ type Meter interface {
// NewInt64Counter creates a new integral counter with a given // NewInt64Counter creates a new integral counter with a given
// name and customized with passed options. // name and customized with passed options.
NewInt64Counter(name string, cos ...CounterOptionApplier) (Int64Counter, error) NewInt64Counter(name string, opts ...Option) (Int64Counter, error)
// NewFloat64Counter creates a new floating point counter with // NewFloat64Counter creates a new floating point counter with
// a given name and customized with passed options. // a given name and customized with passed options.
NewFloat64Counter(name string, cos ...CounterOptionApplier) (Float64Counter, error) NewFloat64Counter(name string, opts ...Option) (Float64Counter, error)
// NewInt64Measure creates a new integral measure with a given // NewInt64Measure creates a new integral measure with a given
// name and customized with passed options. // name and customized with passed options.
NewInt64Measure(name string, mos ...MeasureOptionApplier) (Int64Measure, error) NewInt64Measure(name string, opts ...Option) (Int64Measure, error)
// NewFloat64Measure creates a new floating point measure with // NewFloat64Measure creates a new floating point measure with
// a given name and customized with passed options. // a given name and customized with passed options.
NewFloat64Measure(name string, mos ...MeasureOptionApplier) (Float64Measure, error) NewFloat64Measure(name string, opts ...Option) (Float64Measure, error)
// RegisterInt64Observer creates a new integral observer with a // RegisterInt64Observer creates a new integral observer with a
// given name, running a given callback, and customized with passed // given name, running a given callback, and customized with passed
// options. Callback can be nil. // options. Callback can be nil.
RegisterInt64Observer(name string, callback Int64ObserverCallback, oos ...ObserverOptionApplier) (Int64Observer, error) RegisterInt64Observer(name string, callback Int64ObserverCallback, opts ...Option) (Int64Observer, error)
// RegisterFloat64Observer creates a new floating point observer // RegisterFloat64Observer creates a new floating point observer
// with a given name, running a given callback, and customized with // with a given name, running a given callback, and customized with
// passed options. Callback can be nil. // passed options. Callback can be nil.
RegisterFloat64Observer(name string, callback Float64ObserverCallback, oos ...ObserverOptionApplier) (Float64Observer, error) RegisterFloat64Observer(name string, callback Float64ObserverCallback, opts ...Option) (Float64Observer, error)
} }
// Int64ObserverResult is an interface for reporting integral // Int64ObserverResult is an interface for reporting integral
@ -172,138 +142,36 @@ type Float64Observer interface {
Unregister() Unregister()
} }
// Option supports specifying the various metric options.
type Option func(*Options)
// OptionApplier is an interface for applying metric options that are
// valid for all the kinds of metrics.
type OptionApplier interface {
CounterOptionApplier
MeasureOptionApplier
ObserverOptionApplier
// ApplyOption is used to make some general changes in the
// Options.
ApplyOption(*Options)
}
// CounterObserverOptionApplier is an interface for applying metric
// options that are valid for counter or observer metrics.
type CounterObserverOptionApplier interface {
CounterOptionApplier
ObserverOptionApplier
}
type optionWrapper struct {
F Option
}
type counterOptionWrapper struct {
F Option
}
type measureOptionWrapper struct {
F Option
}
type observerOptionWrapper struct {
F Option
}
type counterObserverOptionWrapper struct {
FC Option
FO Option
}
var (
_ OptionApplier = optionWrapper{}
_ CounterOptionApplier = counterOptionWrapper{}
_ MeasureOptionApplier = measureOptionWrapper{}
_ ObserverOptionApplier = observerOptionWrapper{}
)
func (o optionWrapper) ApplyCounterOption(opts *Options) {
o.ApplyOption(opts)
}
func (o optionWrapper) ApplyMeasureOption(opts *Options) {
o.ApplyOption(opts)
}
func (o optionWrapper) ApplyObserverOption(opts *Options) {
o.ApplyOption(opts)
}
func (o optionWrapper) ApplyOption(opts *Options) {
o.F(opts)
}
func (o counterOptionWrapper) ApplyCounterOption(opts *Options) {
o.F(opts)
}
func (o measureOptionWrapper) ApplyMeasureOption(opts *Options) {
o.F(opts)
}
func (o counterObserverOptionWrapper) ApplyCounterOption(opts *Options) {
o.FC(opts)
}
func (o counterObserverOptionWrapper) ApplyObserverOption(opts *Options) {
o.FO(opts)
}
func (o observerOptionWrapper) ApplyObserverOption(opts *Options) {
o.F(opts)
}
// WithDescription applies provided description. // WithDescription applies provided description.
func WithDescription(desc string) OptionApplier { func WithDescription(desc string) Option {
return optionWrapper{ return descriptionOption(desc)
F: func(opts *Options) { }
opts.Description = desc
}, type descriptionOption string
}
func (d descriptionOption) Apply(config *Config) {
config.Description = string(d)
} }
// WithUnit applies provided unit. // WithUnit applies provided unit.
func WithUnit(unit unit.Unit) OptionApplier { func WithUnit(unit unit.Unit) Option {
return optionWrapper{ return unitOption(unit)
F: func(opts *Options) { }
opts.Unit = unit
}, type unitOption unit.Unit
}
func (u unitOption) Apply(config *Config) {
config.Unit = unit.Unit(u)
} }
// WithKeys applies recommended label keys. Multiple `WithKeys` // WithKeys applies recommended label keys. Multiple `WithKeys`
// options accumulate. // options accumulate.
func WithKeys(keys ...core.Key) OptionApplier { func WithKeys(keys ...core.Key) Option {
return optionWrapper{ return keysOption(keys)
F: func(opts *Options) {
opts.Keys = append(opts.Keys, keys...)
},
}
} }
// WithMonotonic sets whether a counter or an observer is not type keysOption []core.Key
// permitted to go down.
func WithMonotonic(monotonic bool) CounterObserverOptionApplier {
return counterObserverOptionWrapper{
FC: func(opts *Options) {
opts.Alternate = !monotonic
},
FO: func(opts *Options) {
opts.Alternate = monotonic
},
}
}
// WithAbsolute sets whether a measure is not permitted to be func (k keysOption) Apply(config *Config) {
// negative. config.Keys = append(config.Keys, k...)
func WithAbsolute(absolute bool) MeasureOptionApplier {
return measureOptionWrapper{
F: func(opts *Options) {
opts.Alternate = !absolute
},
}
} }

View File

@ -33,14 +33,13 @@ import (
var Must = metric.Must var Must = metric.Must
func TestCounterOptions(t *testing.T) { func TestOptions(t *testing.T) {
type testcase struct { type testcase struct {
name string name string
opts []metric.CounterOptionApplier opts []metric.Option
keys []core.Key keys []core.Key
desc string desc string
unit unit.Unit unit unit.Unit
alt bool
} }
testcases := []testcase{ testcases := []testcase{
{ {
@ -49,11 +48,10 @@ func TestCounterOptions(t *testing.T) {
keys: nil, keys: nil,
desc: "", desc: "",
unit: "", unit: "",
alt: false,
}, },
{ {
name: "keys keys keys", name: "keys keys keys",
opts: []metric.CounterOptionApplier{ opts: []metric.Option{
metric.WithKeys(key.New("foo"), key.New("foo2")), metric.WithKeys(key.New("foo"), key.New("foo2")),
metric.WithKeys(key.New("bar"), key.New("bar2")), metric.WithKeys(key.New("bar"), key.New("bar2")),
metric.WithKeys(key.New("baz"), key.New("baz2")), metric.WithKeys(key.New("baz"), key.New("baz2")),
@ -65,311 +63,56 @@ func TestCounterOptions(t *testing.T) {
}, },
desc: "", desc: "",
unit: "", unit: "",
alt: false,
}, },
{ {
name: "description", name: "description",
opts: []metric.CounterOptionApplier{ opts: []metric.Option{
metric.WithDescription("stuff"), metric.WithDescription("stuff"),
}, },
keys: nil, keys: nil,
desc: "stuff", desc: "stuff",
unit: "", unit: "",
alt: false,
}, },
{ {
name: "description override", name: "description override",
opts: []metric.CounterOptionApplier{ opts: []metric.Option{
metric.WithDescription("stuff"), metric.WithDescription("stuff"),
metric.WithDescription("things"), metric.WithDescription("things"),
}, },
keys: nil, keys: nil,
desc: "things", desc: "things",
unit: "", unit: "",
alt: false,
}, },
{ {
name: "unit", name: "unit",
opts: []metric.CounterOptionApplier{ opts: []metric.Option{
metric.WithUnit("s"), metric.WithUnit("s"),
}, },
keys: nil, keys: nil,
desc: "", desc: "",
unit: "s", unit: "s",
alt: false,
}, },
{ {
name: "unit override", name: "unit override",
opts: []metric.CounterOptionApplier{ opts: []metric.Option{
metric.WithUnit("s"), metric.WithUnit("s"),
metric.WithUnit("h"), metric.WithUnit("h"),
}, },
keys: nil, keys: nil,
desc: "", desc: "",
unit: "h", unit: "h",
alt: false,
},
{
name: "nonmonotonic",
opts: []metric.CounterOptionApplier{
metric.WithMonotonic(false),
},
keys: nil,
desc: "",
unit: "",
alt: true,
},
{
name: "nonmonotonic, but not really",
opts: []metric.CounterOptionApplier{
metric.WithMonotonic(false),
metric.WithMonotonic(true),
},
keys: nil,
desc: "",
unit: "",
alt: false,
}, },
} }
for idx, tt := range testcases { for idx, tt := range testcases {
t.Logf("Testing counter case %s (%d)", tt.name, idx) t.Logf("Testing counter case %s (%d)", tt.name, idx)
opts := &metric.Options{} if diff := cmp.Diff(metric.Configure(tt.opts), metric.Config{
metric.ApplyCounterOptions(opts, tt.opts...)
checkOptions(t, opts, &metric.Options{
Description: tt.desc, Description: tt.desc,
Unit: tt.unit, Unit: tt.unit,
Keys: tt.keys, Keys: tt.keys,
Alternate: tt.alt, }); diff != "" {
})
}
}
func TestMeasureOptions(t *testing.T) {
type testcase struct {
name string
opts []metric.MeasureOptionApplier
keys []core.Key
desc string
unit unit.Unit
alt bool
}
testcases := []testcase{
{
name: "no opts",
opts: nil,
keys: nil,
desc: "",
unit: "",
alt: false,
},
{
name: "keys keys keys",
opts: []metric.MeasureOptionApplier{
metric.WithKeys(key.New("foo"), key.New("foo2")),
metric.WithKeys(key.New("bar"), key.New("bar2")),
metric.WithKeys(key.New("baz"), key.New("baz2")),
},
keys: []core.Key{
key.New("foo"), key.New("foo2"),
key.New("bar"), key.New("bar2"),
key.New("baz"), key.New("baz2"),
},
desc: "",
unit: "",
alt: false,
},
{
name: "description",
opts: []metric.MeasureOptionApplier{
metric.WithDescription("stuff"),
},
keys: nil,
desc: "stuff",
unit: "",
alt: false,
},
{
name: "description override",
opts: []metric.MeasureOptionApplier{
metric.WithDescription("stuff"),
metric.WithDescription("things"),
},
keys: nil,
desc: "things",
unit: "",
alt: false,
},
{
name: "unit",
opts: []metric.MeasureOptionApplier{
metric.WithUnit("s"),
},
keys: nil,
desc: "",
unit: "s",
alt: false,
},
{
name: "unit override",
opts: []metric.MeasureOptionApplier{
metric.WithUnit("s"),
metric.WithUnit("h"),
},
keys: nil,
desc: "",
unit: "h",
alt: false,
},
{
name: "not absolute",
opts: []metric.MeasureOptionApplier{
metric.WithAbsolute(false),
},
keys: nil,
desc: "",
unit: "",
alt: true,
},
{
name: "not absolute, but not really",
opts: []metric.MeasureOptionApplier{
metric.WithAbsolute(false),
metric.WithAbsolute(true),
},
keys: nil,
desc: "",
unit: "",
alt: false,
},
}
for idx, tt := range testcases {
t.Logf("Testing measure case %s (%d)", tt.name, idx)
opts := &metric.Options{}
metric.ApplyMeasureOptions(opts, tt.opts...)
checkOptions(t, opts, &metric.Options{
Description: tt.desc,
Unit: tt.unit,
Keys: tt.keys,
Alternate: tt.alt,
})
}
}
func TestObserverOptions(t *testing.T) {
type testcase struct {
name string
opts []metric.ObserverOptionApplier
keys []core.Key
desc string
unit unit.Unit
alt bool
}
testcases := []testcase{
{
name: "no opts",
opts: nil,
keys: nil,
desc: "",
unit: "",
alt: false,
},
{
name: "keys keys keys",
opts: []metric.ObserverOptionApplier{
metric.WithKeys(key.New("foo"), key.New("foo2")),
metric.WithKeys(key.New("bar"), key.New("bar2")),
metric.WithKeys(key.New("baz"), key.New("baz2")),
},
keys: []core.Key{
key.New("foo"), key.New("foo2"),
key.New("bar"), key.New("bar2"),
key.New("baz"), key.New("baz2"),
},
desc: "",
unit: "",
alt: false,
},
{
name: "description",
opts: []metric.ObserverOptionApplier{
metric.WithDescription("stuff"),
},
keys: nil,
desc: "stuff",
unit: "",
alt: false,
},
{
name: "description override",
opts: []metric.ObserverOptionApplier{
metric.WithDescription("stuff"),
metric.WithDescription("things"),
},
keys: nil,
desc: "things",
unit: "",
alt: false,
},
{
name: "unit",
opts: []metric.ObserverOptionApplier{
metric.WithUnit("s"),
},
keys: nil,
desc: "",
unit: "s",
alt: false,
},
{
name: "unit override",
opts: []metric.ObserverOptionApplier{
metric.WithUnit("s"),
metric.WithUnit("h"),
},
keys: nil,
desc: "",
unit: "h",
alt: false,
},
{
name: "monotonic",
opts: []metric.ObserverOptionApplier{
metric.WithMonotonic(true),
},
keys: nil,
desc: "",
unit: "",
alt: true,
},
{
name: "monotonic, but not really",
opts: []metric.ObserverOptionApplier{
metric.WithMonotonic(true),
metric.WithMonotonic(false),
},
keys: nil,
desc: "",
unit: "",
alt: false,
},
}
for idx, tt := range testcases {
t.Logf("Testing observer case %s (%d)", tt.name, idx)
opts := &metric.Options{}
metric.ApplyObserverOptions(opts, tt.opts...)
checkOptions(t, opts, &metric.Options{
Description: tt.desc,
Unit: tt.unit,
Keys: tt.keys,
Alternate: tt.alt,
})
}
}
func checkOptions(t *testing.T, got *metric.Options, expected *metric.Options) {
if diff := cmp.Diff(got, expected); diff != "" {
t.Errorf("Compare options: -got +want %s", diff) t.Errorf("Compare options: -got +want %s", diff)
} }
}
} }
func TestCounter(t *testing.T) { func TestCounter(t *testing.T) {

View File

@ -29,7 +29,7 @@ func Must(meter Meter) MeterMust {
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the // NewInt64Counter calls `Meter.NewInt64Counter` and returns the
// instrument, panicking if it encounters an error. // instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64Counter(name string, cos ...CounterOptionApplier) Int64Counter { func (mm MeterMust) NewInt64Counter(name string, cos ...Option) Int64Counter {
if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil { if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
panic(err) panic(err)
} else { } else {
@ -39,7 +39,7 @@ func (mm MeterMust) NewInt64Counter(name string, cos ...CounterOptionApplier) In
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the // NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
// instrument, panicking if it encounters an error. // instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64Counter(name string, cos ...CounterOptionApplier) Float64Counter { func (mm MeterMust) NewFloat64Counter(name string, cos ...Option) Float64Counter {
if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil { if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
panic(err) panic(err)
} else { } else {
@ -49,7 +49,7 @@ func (mm MeterMust) NewFloat64Counter(name string, cos ...CounterOptionApplier)
// NewInt64Measure calls `Meter.NewInt64Measure` and returns the // NewInt64Measure calls `Meter.NewInt64Measure` and returns the
// instrument, panicking if it encounters an error. // instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64Measure(name string, mos ...MeasureOptionApplier) Int64Measure { func (mm MeterMust) NewInt64Measure(name string, mos ...Option) Int64Measure {
if inst, err := mm.meter.NewInt64Measure(name, mos...); err != nil { if inst, err := mm.meter.NewInt64Measure(name, mos...); err != nil {
panic(err) panic(err)
} else { } else {
@ -59,7 +59,7 @@ func (mm MeterMust) NewInt64Measure(name string, mos ...MeasureOptionApplier) In
// NewFloat64Measure calls `Meter.NewFloat64Measure` and returns the // NewFloat64Measure calls `Meter.NewFloat64Measure` and returns the
// instrument, panicking if it encounters an error. // instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64Measure(name string, mos ...MeasureOptionApplier) Float64Measure { func (mm MeterMust) NewFloat64Measure(name string, mos ...Option) Float64Measure {
if inst, err := mm.meter.NewFloat64Measure(name, mos...); err != nil { if inst, err := mm.meter.NewFloat64Measure(name, mos...); err != nil {
panic(err) panic(err)
} else { } else {
@ -69,7 +69,7 @@ func (mm MeterMust) NewFloat64Measure(name string, mos ...MeasureOptionApplier)
// RegisterInt64Observer calls `Meter.RegisterInt64Observer` and // RegisterInt64Observer calls `Meter.RegisterInt64Observer` and
// returns the instrument, panicking if it encounters an error. // returns the instrument, panicking if it encounters an error.
func (mm MeterMust) RegisterInt64Observer(name string, callback Int64ObserverCallback, oos ...ObserverOptionApplier) Int64Observer { func (mm MeterMust) RegisterInt64Observer(name string, callback Int64ObserverCallback, oos ...Option) Int64Observer {
if inst, err := mm.meter.RegisterInt64Observer(name, callback, oos...); err != nil { if inst, err := mm.meter.RegisterInt64Observer(name, callback, oos...); err != nil {
panic(err) panic(err)
} else { } else {
@ -79,7 +79,7 @@ func (mm MeterMust) RegisterInt64Observer(name string, callback Int64ObserverCal
// RegisterFloat64Observer calls `Meter.RegisterFloat64Observer` and // RegisterFloat64Observer calls `Meter.RegisterFloat64Observer` and
// returns the instrument, panicking if it encounters an error. // returns the instrument, panicking if it encounters an error.
func (mm MeterMust) RegisterFloat64Observer(name string, callback Float64ObserverCallback, oos ...ObserverOptionApplier) Float64Observer { func (mm MeterMust) RegisterFloat64Observer(name string, callback Float64ObserverCallback, oos ...Option) Float64Observer {
if inst, err := mm.meter.RegisterFloat64Observer(name, callback, oos...); err != nil { if inst, err := mm.meter.RegisterFloat64Observer(name, callback, oos...); err != nil {
panic(err) panic(err)
} else { } else {

View File

@ -59,26 +59,26 @@ func (NoopMeter) Labels(...core.KeyValue) LabelSet {
func (NoopMeter) RecordBatch(context.Context, LabelSet, ...Measurement) { func (NoopMeter) RecordBatch(context.Context, LabelSet, ...Measurement) {
} }
func (NoopMeter) NewInt64Counter(name string, cos ...CounterOptionApplier) (Int64Counter, error) { func (NoopMeter) NewInt64Counter(name string, cos ...Option) (Int64Counter, error) {
return WrapInt64CounterInstrument(noopInstrument{}, nil) return WrapInt64CounterInstrument(noopInstrument{}, nil)
} }
func (NoopMeter) NewFloat64Counter(name string, cos ...CounterOptionApplier) (Float64Counter, error) { func (NoopMeter) NewFloat64Counter(name string, cos ...Option) (Float64Counter, error) {
return WrapFloat64CounterInstrument(noopInstrument{}, nil) return WrapFloat64CounterInstrument(noopInstrument{}, nil)
} }
func (NoopMeter) NewInt64Measure(name string, mos ...MeasureOptionApplier) (Int64Measure, error) { func (NoopMeter) NewInt64Measure(name string, mos ...Option) (Int64Measure, error) {
return WrapInt64MeasureInstrument(noopInstrument{}, nil) return WrapInt64MeasureInstrument(noopInstrument{}, nil)
} }
func (NoopMeter) NewFloat64Measure(name string, mos ...MeasureOptionApplier) (Float64Measure, error) { func (NoopMeter) NewFloat64Measure(name string, mos ...Option) (Float64Measure, error) {
return WrapFloat64MeasureInstrument(noopInstrument{}, nil) return WrapFloat64MeasureInstrument(noopInstrument{}, nil)
} }
func (NoopMeter) RegisterInt64Observer(name string, callback Int64ObserverCallback, oos ...ObserverOptionApplier) (Int64Observer, error) { func (NoopMeter) RegisterInt64Observer(name string, callback Int64ObserverCallback, oos ...Option) (Int64Observer, error) {
return noopInt64Observer{}, nil return noopInt64Observer{}, nil
} }
func (NoopMeter) RegisterFloat64Observer(name string, callback Float64ObserverCallback, oos ...ObserverOptionApplier) (Float64Observer, error) { func (NoopMeter) RegisterFloat64Observer(name string, callback Float64ObserverCallback, oos ...Option) (Float64Observer, error) {
return noopFloat64Observer{}, nil return noopFloat64Observer{}, nil
} }

View File

@ -87,26 +87,11 @@ func WrapFloat64MeasureInstrument(instrument InstrumentImpl, err error) (Float64
return Float64Measure{commonMetric: common}, err return Float64Measure{commonMetric: common}, err
} }
// ApplyCounterOptions is a helper that applies all the counter // Configure is a helper that applies all the options to a Config.
// options to passed opts. func Configure(opts []Option) Config {
func ApplyCounterOptions(opts *Options, cos ...CounterOptionApplier) { var config Config
for _, o := range cos { for _, o := range opts {
o.ApplyCounterOption(opts) o.Apply(&config)
}
}
// ApplyMeasureOptions is a helper that applies all the measure
// options to passed opts.
func ApplyMeasureOptions(opts *Options, mos ...MeasureOptionApplier) {
for _, o := range mos {
o.ApplyMeasureOption(opts)
}
}
// ApplyObserverOptions is a helper that applies all the observer
// options to passed opts.
func ApplyObserverOptions(opts *Options, mos ...ObserverOptionApplier) {
for _, o := range mos {
o.ApplyObserverOption(opts)
} }
return config
} }

View File

@ -29,7 +29,7 @@ import (
"go.opentelemetry.io/otel/exporters/metric/test" "go.opentelemetry.io/otel/exporters/metric/test"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
// TestDogstatsLabels that labels are formatted in the correct style, // TestDogstatsLabels that labels are formatted in the correct style,
@ -44,8 +44,8 @@ func TestDogstatsLabels(t *testing.T) {
ctx := context.Background() ctx := context.Background()
checkpointSet := test.NewCheckpointSet(encoder) checkpointSet := test.NewCheckpointSet(encoder)
desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind, false) desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind)
cagg := counter.New() cagg := sum.New()
_ = cagg.Update(ctx, core.NewInt64Number(123), desc) _ = cagg.Update(ctx, core.NewInt64Number(123), desc)
cagg.Checkpoint(ctx, desc) cagg.Checkpoint(ctx, desc)

View File

@ -124,13 +124,13 @@ timer.B.D:%s|ms
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
cdesc := export.NewDescriptor( cdesc := export.NewDescriptor(
"counter", export.CounterKind, nil, "", "", nkind, false) "counter", export.CounterKind, nil, "", "", nkind)
gdesc := export.NewDescriptor( gdesc := export.NewDescriptor(
"observer", export.ObserverKind, nil, "", "", nkind, false) "observer", export.ObserverKind, nil, "", "", nkind)
mdesc := export.NewDescriptor( mdesc := export.NewDescriptor(
"measure", export.MeasureKind, nil, "", "", nkind, false) "measure", export.MeasureKind, nil, "", "", nkind)
tdesc := export.NewDescriptor( tdesc := export.NewDescriptor(
"timer", export.MeasureKind, nil, "", unit.Milliseconds, nkind, false) "timer", export.MeasureKind, nil, "", unit.Milliseconds, nkind)
labels := []core.KeyValue{ labels := []core.KeyValue{
key.New("A").String("B"), key.New("A").String("B"),
@ -285,7 +285,7 @@ func TestPacketSplit(t *testing.T) {
} }
checkpointSet := test.NewCheckpointSet(adapter.LabelEncoder) checkpointSet := test.NewCheckpointSet(adapter.LabelEncoder)
desc := export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind, false) desc := export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind)
var expected []string var expected []string

View File

@ -30,11 +30,11 @@ func TestPrometheusExporter(t *testing.T) {
checkpointSet := test.NewCheckpointSet(metric.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(metric.NewDefaultLabelEncoder())
counter := export.NewDescriptor( counter := export.NewDescriptor(
"counter", export.CounterKind, nil, "", "", core.Float64NumberKind, false) "counter", export.CounterKind, nil, "", "", core.Float64NumberKind)
lastValue := export.NewDescriptor( lastValue := export.NewDescriptor(
"lastvalue", export.ObserverKind, nil, "", "", core.Float64NumberKind, false) "lastvalue", export.ObserverKind, nil, "", "", core.Float64NumberKind)
measure := export.NewDescriptor( measure := export.NewDescriptor(
"measure", export.MeasureKind, nil, "", "", core.Float64NumberKind, false) "measure", export.MeasureKind, nil, "", "", core.Float64NumberKind)
labels := []core.KeyValue{ labels := []core.KeyValue{
key.New("A").String("B"), key.New("A").String("B"),

View File

@ -18,10 +18,10 @@ import (
"go.opentelemetry.io/otel/sdk/export/metric/aggregator" "go.opentelemetry.io/otel/sdk/export/metric/aggregator"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array" "go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch" "go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
aggtest "go.opentelemetry.io/otel/sdk/metric/aggregator/test" aggtest "go.opentelemetry.io/otel/sdk/metric/aggregator/test"
) )
@ -82,7 +82,7 @@ func TestStdoutTimestamp(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
ctx := context.Background() ctx := context.Background()
desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Int64NumberKind, false) desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Int64NumberKind)
lvagg := lastvalue.New() lvagg := lastvalue.New()
aggtest.CheckedUpdate(t, lvagg, core.NewInt64Number(321), desc) aggtest.CheckedUpdate(t, lvagg, core.NewInt64Number(321), desc)
lvagg.Checkpoint(ctx, desc) lvagg.Checkpoint(ctx, desc)
@ -127,8 +127,8 @@ func TestStdoutCounterFormat(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind, false) desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind)
cagg := counter.New() cagg := sum.New()
aggtest.CheckedUpdate(fix.t, cagg, core.NewInt64Number(123), desc) aggtest.CheckedUpdate(fix.t, cagg, core.NewInt64Number(123), desc)
cagg.Checkpoint(fix.ctx, desc) cagg.Checkpoint(fix.ctx, desc)
@ -144,7 +144,7 @@ func TestStdoutLastValueFormat(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Float64NumberKind, false) desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Float64NumberKind)
lvagg := lastvalue.New() lvagg := lastvalue.New()
aggtest.CheckedUpdate(fix.t, lvagg, core.NewFloat64Number(123.456), desc) aggtest.CheckedUpdate(fix.t, lvagg, core.NewFloat64Number(123.456), desc)
lvagg.Checkpoint(fix.ctx, desc) lvagg.Checkpoint(fix.ctx, desc)
@ -161,7 +161,7 @@ func TestStdoutMinMaxSumCount(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind, false) desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind)
magg := minmaxsumcount.New(desc) magg := minmaxsumcount.New(desc)
aggtest.CheckedUpdate(fix.t, magg, core.NewFloat64Number(123.456), desc) aggtest.CheckedUpdate(fix.t, magg, core.NewFloat64Number(123.456), desc)
aggtest.CheckedUpdate(fix.t, magg, core.NewFloat64Number(876.543), desc) aggtest.CheckedUpdate(fix.t, magg, core.NewFloat64Number(876.543), desc)
@ -181,7 +181,7 @@ func TestStdoutMeasureFormat(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind, false) desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind)
magg := array.New() magg := array.New()
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
@ -222,7 +222,7 @@ func TestStdoutMeasureFormat(t *testing.T) {
} }
func TestStdoutEmptyDataSet(t *testing.T) { func TestStdoutEmptyDataSet(t *testing.T) {
desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind, false) desc := export.NewDescriptor("test.name", export.MeasureKind, nil, "", "", core.Float64NumberKind)
for name, tc := range map[string]export.Aggregator{ for name, tc := range map[string]export.Aggregator{
"ddsketch": ddsketch.New(ddsketch.NewDefaultConfig(), desc), "ddsketch": ddsketch.New(ddsketch.NewDefaultConfig(), desc),
"minmaxsumcount": minmaxsumcount.New(desc), "minmaxsumcount": minmaxsumcount.New(desc),
@ -252,7 +252,7 @@ func TestStdoutLastValueNotSet(t *testing.T) {
checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder()) checkpointSet := test.NewCheckpointSet(sdk.NewDefaultLabelEncoder())
desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Float64NumberKind, false) desc := export.NewDescriptor("test.name", export.ObserverKind, nil, "", "", core.Float64NumberKind)
lvagg := lastvalue.New() lvagg := lastvalue.New()
lvagg.Checkpoint(fix.ctx, desc) lvagg.Checkpoint(fix.ctx, desc)
@ -270,8 +270,8 @@ func TestStdoutCounterWithUnspecifiedKeys(t *testing.T) {
keys := []core.Key{key.New("C"), key.New("D")} keys := []core.Key{key.New("C"), key.New("D")}
desc := export.NewDescriptor("test.name", export.CounterKind, keys, "", "", core.Int64NumberKind, false) desc := export.NewDescriptor("test.name", export.CounterKind, keys, "", "", core.Int64NumberKind)
cagg := counter.New() cagg := sum.New()
aggtest.CheckedUpdate(fix.t, cagg, core.NewInt64Number(10), desc) aggtest.CheckedUpdate(fix.t, cagg, core.NewInt64Number(10), desc)
cagg.Checkpoint(fix.ctx, desc) cagg.Checkpoint(fix.ctx, desc)

View File

@ -6,8 +6,8 @@ import (
"go.opentelemetry.io/otel/api/core" "go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array" "go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
type CheckpointSet struct { type CheckpointSet struct {
@ -61,7 +61,7 @@ func (p *CheckpointSet) AddLastValue(desc *export.Descriptor, v float64, labels
} }
func (p *CheckpointSet) AddCounter(desc *export.Descriptor, v float64, labels ...core.KeyValue) { func (p *CheckpointSet) AddCounter(desc *export.Descriptor, v float64, labels ...core.KeyValue) {
p.updateAggregator(desc, counter.New(), v, labels...) p.updateAggregator(desc, sum.New(), v, labels...)
} }
func (p *CheckpointSet) AddMeasure(desc *export.Descriptor, v float64, labels ...core.KeyValue) { func (p *CheckpointSet) AddMeasure(desc *export.Descriptor, v float64, labels ...core.KeyValue) {

View File

@ -32,7 +32,7 @@ type (
Name string Name string
Kind Kind Kind Kind
NumberKind core.NumberKind NumberKind core.NumberKind
Opts apimetric.Options Config apimetric.Config
} }
LabelSet struct { LabelSet struct {
@ -187,51 +187,47 @@ func (m *Meter) Labels(labels ...core.KeyValue) apimetric.LabelSet {
} }
} }
func (m *Meter) NewInt64Counter(name string, cos ...apimetric.CounterOptionApplier) (apimetric.Int64Counter, error) { func (m *Meter) NewInt64Counter(name string, opts ...apimetric.Option) (apimetric.Int64Counter, error) {
instrument := m.newCounterInstrument(name, core.Int64NumberKind, cos...) instrument := m.newCounterInstrument(name, core.Int64NumberKind, opts)
return apimetric.WrapInt64CounterInstrument(instrument, nil) return apimetric.WrapInt64CounterInstrument(instrument, nil)
} }
func (m *Meter) NewFloat64Counter(name string, cos ...apimetric.CounterOptionApplier) (apimetric.Float64Counter, error) { func (m *Meter) NewFloat64Counter(name string, opts ...apimetric.Option) (apimetric.Float64Counter, error) {
instrument := m.newCounterInstrument(name, core.Float64NumberKind, cos...) instrument := m.newCounterInstrument(name, core.Float64NumberKind, opts)
return apimetric.WrapFloat64CounterInstrument(instrument, nil) return apimetric.WrapFloat64CounterInstrument(instrument, nil)
} }
func (m *Meter) newCounterInstrument(name string, numberKind core.NumberKind, cos ...apimetric.CounterOptionApplier) *Instrument { func (m *Meter) newCounterInstrument(name string, numberKind core.NumberKind, opts []apimetric.Option) *Instrument {
opts := apimetric.Options{}
apimetric.ApplyCounterOptions(&opts, cos...)
return &Instrument{ return &Instrument{
Name: name, Name: name,
Kind: KindCounter, Kind: KindCounter,
NumberKind: numberKind, NumberKind: numberKind,
Opts: opts, Config: apimetric.Configure(opts),
} }
} }
func (m *Meter) NewInt64Measure(name string, mos ...apimetric.MeasureOptionApplier) (apimetric.Int64Measure, error) { func (m *Meter) NewInt64Measure(name string, opts ...apimetric.Option) (apimetric.Int64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Int64NumberKind, mos...) instrument := m.newMeasureInstrument(name, core.Int64NumberKind, opts)
return apimetric.WrapInt64MeasureInstrument(instrument, nil) return apimetric.WrapInt64MeasureInstrument(instrument, nil)
} }
func (m *Meter) NewFloat64Measure(name string, mos ...apimetric.MeasureOptionApplier) (apimetric.Float64Measure, error) { func (m *Meter) NewFloat64Measure(name string, opts ...apimetric.Option) (apimetric.Float64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Float64NumberKind, mos...) instrument := m.newMeasureInstrument(name, core.Float64NumberKind, opts)
return apimetric.WrapFloat64MeasureInstrument(instrument, nil) return apimetric.WrapFloat64MeasureInstrument(instrument, nil)
} }
func (m *Meter) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...apimetric.MeasureOptionApplier) *Instrument { func (m *Meter) newMeasureInstrument(name string, numberKind core.NumberKind, opts []apimetric.Option) *Instrument {
opts := apimetric.Options{}
apimetric.ApplyMeasureOptions(&opts, mos...)
return &Instrument{ return &Instrument{
Name: name, Name: name,
Kind: KindMeasure, Kind: KindMeasure,
NumberKind: numberKind, NumberKind: numberKind,
Opts: opts, Config: apimetric.Configure(opts),
} }
} }
func (m *Meter) RegisterInt64Observer(name string, callback apimetric.Int64ObserverCallback, oos ...apimetric.ObserverOptionApplier) (apimetric.Int64Observer, error) { func (m *Meter) RegisterInt64Observer(name string, callback apimetric.Int64ObserverCallback, opts ...apimetric.Option) (apimetric.Int64Observer, error) {
wrappedCallback := wrapInt64ObserverCallback(callback) wrappedCallback := wrapInt64ObserverCallback(callback)
return m.newObserver(name, wrappedCallback, core.Int64NumberKind, oos...), nil return m.newObserver(name, wrappedCallback, core.Int64NumberKind, opts), nil
} }
func wrapInt64ObserverCallback(callback apimetric.Int64ObserverCallback) observerCallback { func wrapInt64ObserverCallback(callback apimetric.Int64ObserverCallback) observerCallback {
@ -246,9 +242,9 @@ func wrapInt64ObserverCallback(callback apimetric.Int64ObserverCallback) observe
} }
} }
func (m *Meter) RegisterFloat64Observer(name string, callback apimetric.Float64ObserverCallback, oos ...apimetric.ObserverOptionApplier) (apimetric.Float64Observer, error) { func (m *Meter) RegisterFloat64Observer(name string, callback apimetric.Float64ObserverCallback, opts ...apimetric.Option) (apimetric.Float64Observer, error) {
wrappedCallback := wrapFloat64ObserverCallback(callback) wrappedCallback := wrapFloat64ObserverCallback(callback)
return m.newObserver(name, wrappedCallback, core.Float64NumberKind, oos...), nil return m.newObserver(name, wrappedCallback, core.Float64NumberKind, opts), nil
} }
func wrapFloat64ObserverCallback(callback apimetric.Float64ObserverCallback) observerCallback { func wrapFloat64ObserverCallback(callback apimetric.Float64ObserverCallback) observerCallback {
@ -263,15 +259,13 @@ func wrapFloat64ObserverCallback(callback apimetric.Float64ObserverCallback) obs
} }
} }
func (m *Meter) newObserver(name string, callback observerCallback, numberKind core.NumberKind, oos ...apimetric.ObserverOptionApplier) *Observer { func (m *Meter) newObserver(name string, callback observerCallback, numberKind core.NumberKind, opts []apimetric.Option) *Observer {
opts := apimetric.Options{}
apimetric.ApplyObserverOptions(&opts, oos...)
obs := &Observer{ obs := &Observer{
Instrument: &Instrument{ Instrument: &Instrument{
Name: name, Name: name,
Kind: KindObserver, Kind: KindObserver,
NumberKind: numberKind, NumberKind: numberKind,
Opts: opts, Config: apimetric.Configure(opts),
}, },
Meter: m, Meter: m,
Dead: false, Dead: false,

View File

@ -132,8 +132,8 @@ func RangeTest(number core.Number, descriptor *export.Descriptor) error {
} }
switch descriptor.MetricKind() { switch descriptor.MetricKind() {
case export.CounterKind, export.MeasureKind: case export.CounterKind:
if !descriptor.Alternate() && number.IsNegative(numberKind) { if number.IsNegative(numberKind) {
return ErrNegativeInput return ErrNegativeInput
} }
} }

View File

@ -16,7 +16,6 @@ package aggregator_test // import "go.opentelemetry.io/otel/sdk/export/metric/ag
import ( import (
"errors" "errors"
"fmt"
"math" "math"
"testing" "testing"
@ -25,15 +24,15 @@ import (
"go.opentelemetry.io/otel/api/core" "go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregator" "go.opentelemetry.io/otel/sdk/export/metric/aggregator"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
func TestInconsistentMergeErr(t *testing.T) { func TestInconsistentMergeErr(t *testing.T) {
err := aggregator.NewInconsistentMergeError(counter.New(), lastvalue.New()) err := aggregator.NewInconsistentMergeError(sum.New(), lastvalue.New())
require.Equal( require.Equal(
t, t,
"cannot merge *counter.Aggregator with *lastvalue.Aggregator: inconsistent aggregator types", "cannot merge *sum.Aggregator with *lastvalue.Aggregator: inconsistent aggregator types",
err.Error(), err.Error(),
) )
require.True(t, errors.Is(err, aggregator.ErrInconsistentType)) require.True(t, errors.Is(err, aggregator.ErrInconsistentType))
@ -51,7 +50,7 @@ func testRangeNaN(t *testing.T, desc *export.Descriptor) {
} }
} }
func testRangeNegative(t *testing.T, alt bool, desc *export.Descriptor) { func testRangeNegative(t *testing.T, desc *export.Descriptor) {
var neg, pos core.Number var neg, pos core.Number
if desc.NumberKind() == core.Float64NumberKind { if desc.NumberKind() == core.Float64NumberKind {
@ -66,15 +65,27 @@ func testRangeNegative(t *testing.T, alt bool, desc *export.Descriptor) {
negErr := aggregator.RangeTest(neg, desc) negErr := aggregator.RangeTest(neg, desc)
require.Nil(t, posErr) require.Nil(t, posErr)
require.Equal(t, negErr, aggregator.ErrNegativeInput)
if desc.MetricKind() == export.ObserverKind {
require.Nil(t, negErr)
} else {
require.Equal(t, negErr == nil, alt)
}
} }
func TestRangeTest(t *testing.T) { func TestRangeTest(t *testing.T) {
// Only Counters implement a range test.
for _, nkind := range []core.NumberKind{core.Float64NumberKind, core.Int64NumberKind} {
t.Run(nkind.String(), func(t *testing.T) {
desc := export.NewDescriptor(
"name",
export.CounterKind,
nil,
"",
"",
nkind,
)
testRangeNegative(t, desc)
})
}
}
func TestNaNTest(t *testing.T) {
for _, nkind := range []core.NumberKind{core.Float64NumberKind, core.Int64NumberKind} { for _, nkind := range []core.NumberKind{core.Float64NumberKind, core.Int64NumberKind} {
t.Run(nkind.String(), func(t *testing.T) { t.Run(nkind.String(), func(t *testing.T) {
for _, mkind := range []export.Kind{ for _, mkind := range []export.Kind{
@ -82,9 +93,6 @@ func TestRangeTest(t *testing.T) {
export.MeasureKind, export.MeasureKind,
export.ObserverKind, export.ObserverKind,
} { } {
t.Run(mkind.String(), func(t *testing.T) {
for _, alt := range []bool{true, false} {
t.Run(fmt.Sprint(alt), func(t *testing.T) {
desc := export.NewDescriptor( desc := export.NewDescriptor(
"name", "name",
mkind, mkind,
@ -92,13 +100,8 @@ func TestRangeTest(t *testing.T) {
"", "",
"", "",
nkind, nkind,
alt,
) )
testRangeNaN(t, desc) testRangeNaN(t, desc)
testRangeNegative(t, alt, desc)
})
}
})
} }
}) })
} }

View File

@ -309,7 +309,6 @@ type Descriptor struct {
description string description string
unit unit.Unit unit unit.Unit
numberKind core.NumberKind numberKind core.NumberKind
alternate bool
} }
// NewDescriptor builds a new descriptor, for use by `Meter` // NewDescriptor builds a new descriptor, for use by `Meter`
@ -325,7 +324,6 @@ func NewDescriptor(
description string, description string,
unit unit.Unit, unit unit.Unit,
numberKind core.NumberKind, numberKind core.NumberKind,
alternate bool,
) *Descriptor { ) *Descriptor {
return &Descriptor{ return &Descriptor{
name: name, name: name,
@ -334,7 +332,6 @@ func NewDescriptor(
description: description, description: description,
unit: unit, unit: unit,
numberKind: numberKind, numberKind: numberKind,
alternate: alternate,
} }
} }
@ -373,16 +370,3 @@ func (d *Descriptor) Unit() unit.Unit {
func (d *Descriptor) NumberKind() core.NumberKind { func (d *Descriptor) NumberKind() core.NumberKind {
return d.numberKind return d.numberKind
} }
// Alternate returns true when the non-default behavior of the
// instrument was selected. It returns true if:
//
// - A counter instrument is non-monotonic
// - A measure instrument is non-absolute
// - An observer instrument is monotonic
//
// TODO: Consider renaming this method, or expanding to provide
// kind-specific tests (e.g., Monotonic(), Absolute()).
func (d *Descriptor) Alternate() bool {
return d.alternate
}

View File

@ -48,11 +48,10 @@ func TestMain(m *testing.M) {
type updateTest struct { type updateTest struct {
count int count int
absolute bool
} }
func (ut *updateTest) run(t *testing.T, profile test.Profile) { func (ut *updateTest) run(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !ut.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New() agg := New()
@ -63,12 +62,10 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
all.Append(x) all.Append(x)
test.CheckedUpdate(t, agg, x, descriptor) test.CheckedUpdate(t, agg, x, descriptor)
if !ut.absolute {
y := profile.Random(-1) y := profile.Random(-1)
all.Append(y) all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor) test.CheckedUpdate(t, agg, y, descriptor)
} }
}
ctx := context.Background() ctx := context.Background()
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)
@ -82,42 +79,36 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allSum).CoerceToFloat64(profile.NumberKind), (&allSum).CoerceToFloat64(profile.NumberKind),
sum.CoerceToFloat64(profile.NumberKind), sum.CoerceToFloat64(profile.NumberKind),
0.0000001, 0.0000001,
"Same sum - absolute") "Same sum")
count, err := agg.Count() count, err := agg.Count()
require.Nil(t, err) require.Nil(t, err)
require.Equal(t, all.Count(), count, "Same count - absolute") require.Equal(t, all.Count(), count, "Same count")
min, err := agg.Min() min, err := agg.Min()
require.Nil(t, err) require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min - absolute") require.Equal(t, all.Min(), min, "Same min")
max, err := agg.Max() max, err := agg.Max()
require.Nil(t, err) require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max - absolute") require.Equal(t, all.Max(), max, "Same max")
qx, err := agg.Quantile(0.5) qx, err := agg.Quantile(0.5)
require.Nil(t, err) require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median - absolute") require.Equal(t, all.Median(), qx, "Same median")
} }
func TestArrayUpdate(t *testing.T) { func TestArrayUpdate(t *testing.T) {
// Test with an odd an even number of measurements // Test with an odd an even number of measurements
for count := 999; count <= 1000; count++ { for count := 999; count <= 1000; count++ {
t.Run(fmt.Sprint("Odd=", count%2 == 1), func(t *testing.T) { t.Run(fmt.Sprint("Odd=", count%2 == 1), func(t *testing.T) {
// Test absolute and non-absolute
for _, absolute := range []bool{false, true} {
t.Run(fmt.Sprint("Absolute=", absolute), func(t *testing.T) {
ut := updateTest{ ut := updateTest{
count: count, count: count,
absolute: absolute,
} }
// Test integer and floating point // Test integer and floating point
test.RunProfiles(t, ut.run) test.RunProfiles(t, ut.run)
}) })
} }
})
}
} }
type mergeTest struct { type mergeTest struct {
@ -128,7 +119,7 @@ type mergeTest struct {
func (mt *mergeTest) run(t *testing.T, profile test.Profile) { func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !mt.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := New() agg1 := New()
agg2 := New() agg2 := New()
@ -225,7 +216,7 @@ func TestArrayErrors(t *testing.T) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
test.CheckedUpdate(t, agg, core.Number(0), descriptor) test.CheckedUpdate(t, agg, core.Number(0), descriptor)
@ -253,9 +244,7 @@ func TestArrayErrors(t *testing.T) {
} }
func TestArrayFloat64(t *testing.T) { func TestArrayFloat64(t *testing.T) {
for _, absolute := range []bool{false, true} { descriptor := test.NewAggregatorTest(export.MeasureKind, core.Float64NumberKind)
t.Run(fmt.Sprint("Absolute=", absolute), func(t *testing.T) {
descriptor := test.NewAggregatorTest(export.MeasureKind, core.Float64NumberKind, !absolute)
fpsf := func(sign int) []float64 { fpsf := func(sign int) []float64 {
// Check behavior of a bunch of odd floating // Check behavior of a bunch of odd floating
@ -295,12 +284,10 @@ func TestArrayFloat64(t *testing.T) {
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor) test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
} }
if !absolute {
for _, f := range fpsf(-1) { for _, f := range fpsf(-1) {
all.Append(core.NewFloat64Number(f)) all.Append(core.NewFloat64Number(f))
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor) test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
} }
}
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)
@ -333,6 +320,4 @@ func TestArrayFloat64(t *testing.T) {
for i := 0; i < len(po); i++ { for i := 0; i < len(po); i++ {
require.Equal(t, all.Points()[i], po[i], "Wrong point at position %d", i) require.Equal(t, all.Points()[i], po[i], "Wrong point at position %d", i)
} }
})
}
} }

View File

@ -28,13 +28,12 @@ import (
const count = 1000 const count = 1000
type updateTest struct { type updateTest struct {
absolute bool
} }
func (ut *updateTest) run(t *testing.T, profile test.Profile) { func (ut *updateTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !ut.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(NewDefaultConfig(), descriptor) agg := New(NewDefaultConfig(), descriptor)
all := test.NewNumbers(profile.NumberKind) all := test.NewNumbers(profile.NumberKind)
@ -43,12 +42,10 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
all.Append(x) all.Append(x)
test.CheckedUpdate(t, agg, x, descriptor) test.CheckedUpdate(t, agg, x, descriptor)
if !ut.absolute {
y := profile.Random(-1) y := profile.Random(-1)
all.Append(y) all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor) test.CheckedUpdate(t, agg, y, descriptor)
} }
}
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)
@ -61,10 +58,10 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allSum).CoerceToFloat64(profile.NumberKind), (&allSum).CoerceToFloat64(profile.NumberKind),
sum.CoerceToFloat64(profile.NumberKind), sum.CoerceToFloat64(profile.NumberKind),
1, 1,
"Same sum - absolute") "Same sum")
count, err := agg.Count() count, err := agg.Count()
require.Equal(t, all.Count(), count, "Same count - absolute") require.Equal(t, all.Count(), count, "Same count")
require.Nil(t, err) require.Nil(t, err)
max, err := agg.Max() max, err := agg.Max()
@ -72,7 +69,7 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
require.Equal(t, require.Equal(t,
all.Max(), all.Max(),
max, max,
"Same max - absolute") "Same max")
median, err := agg.Quantile(0.5) median, err := agg.Quantile(0.5)
require.Nil(t, err) require.Nil(t, err)
@ -81,20 +78,12 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allMedian).CoerceToFloat64(profile.NumberKind), (&allMedian).CoerceToFloat64(profile.NumberKind),
median.CoerceToFloat64(profile.NumberKind), median.CoerceToFloat64(profile.NumberKind),
10, 10,
"Same median - absolute") "Same median")
} }
func TestDDSketchUpdate(t *testing.T) { func TestDDSketchUpdate(t *testing.T) {
// Test absolute and non-absolute ut := updateTest{}
for _, absolute := range []bool{false, true} {
t.Run(fmt.Sprint("Absolute=", absolute), func(t *testing.T) {
ut := updateTest{
absolute: absolute,
}
// Test integer and floating point
test.RunProfiles(t, ut.run) test.RunProfiles(t, ut.run)
})
}
} }
type mergeTest struct { type mergeTest struct {
@ -103,7 +92,7 @@ type mergeTest struct {
func (mt *mergeTest) run(t *testing.T, profile test.Profile) { func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !mt.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := New(NewDefaultConfig(), descriptor) agg1 := New(NewDefaultConfig(), descriptor)
agg2 := New(NewDefaultConfig(), descriptor) agg2 := New(NewDefaultConfig(), descriptor)
@ -147,10 +136,10 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
(&allSum).CoerceToFloat64(profile.NumberKind), (&allSum).CoerceToFloat64(profile.NumberKind),
aggSum.CoerceToFloat64(profile.NumberKind), aggSum.CoerceToFloat64(profile.NumberKind),
1, 1,
"Same sum - absolute") "Same sum")
count, err := agg1.Count() count, err := agg1.Count()
require.Equal(t, all.Count(), count, "Same count - absolute") require.Equal(t, all.Count(), count, "Same count")
require.Nil(t, err) require.Nil(t, err)
max, err := agg1.Max() max, err := agg1.Max()
@ -158,7 +147,7 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
require.Equal(t, require.Equal(t,
all.Max(), all.Max(),
max, max,
"Same max - absolute") "Same max")
median, err := agg1.Quantile(0.5) median, err := agg1.Quantile(0.5)
require.Nil(t, err) require.Nil(t, err)
@ -167,7 +156,7 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
(&allMedian).CoerceToFloat64(profile.NumberKind), (&allMedian).CoerceToFloat64(profile.NumberKind),
median.CoerceToFloat64(profile.NumberKind), median.CoerceToFloat64(profile.NumberKind),
10, 10,
"Same median - absolute") "Same median")
} }
func TestDDSketchMerge(t *testing.T) { func TestDDSketchMerge(t *testing.T) {

View File

@ -116,7 +116,7 @@ func TestHistogramPositiveAndNegative(t *testing.T) {
// Validates count, sum and buckets for a given profile and policy // Validates count, sum and buckets for a given profile and policy
func histogram(t *testing.T, profile test.Profile, policy policy) { func histogram(t *testing.T, profile test.Profile, policy policy) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !policy.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(descriptor, boundaries[profile.NumberKind]) agg := New(descriptor, boundaries[profile.NumberKind])
@ -158,7 +158,7 @@ func TestHistogramMerge(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := New(descriptor, boundaries[profile.NumberKind]) agg1 := New(descriptor, boundaries[profile.NumberKind])
agg2 := New(descriptor, boundaries[profile.NumberKind]) agg2 := New(descriptor, boundaries[profile.NumberKind])
@ -210,7 +210,7 @@ func TestHistogramNotSet(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(descriptor, boundaries[profile.NumberKind]) agg := New(descriptor, boundaries[profile.NumberKind])
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)

View File

@ -55,7 +55,7 @@ func TestLastValueUpdate(t *testing.T) {
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New() agg := New()
record := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind, false) record := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind)
var last core.Number var last core.Number
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@ -79,7 +79,7 @@ func TestLastValueMerge(t *testing.T) {
agg1 := New() agg1 := New()
agg2 := New() agg2 := New()
descriptor := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind)
first1 := profile.Random(+1) first1 := profile.Random(+1)
first2 := profile.Random(+1) first2 := profile.Random(+1)
@ -107,7 +107,7 @@ func TestLastValueMerge(t *testing.T) {
} }
func TestLastValueNotSet(t *testing.T) { func TestLastValueNotSet(t *testing.T) {
descriptor := test.NewAggregatorTest(export.ObserverKind, core.Int64NumberKind, true) descriptor := test.NewAggregatorTest(export.ObserverKind, core.Int64NumberKind)
g := New() g := New()
g.Checkpoint(context.Background(), descriptor) g.Checkpoint(context.Background(), descriptor)

View File

@ -118,7 +118,7 @@ func TestMinMaxSumCountPositiveAndNegative(t *testing.T) {
// Validates min, max, sum and count for a given profile and policy // Validates min, max, sum and count for a given profile and policy
func minMaxSumCount(t *testing.T, profile test.Profile, policy policy) { func minMaxSumCount(t *testing.T, profile test.Profile, policy policy) {
ctx := context.Background() ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !policy.absolute) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(descriptor) agg := New(descriptor)
@ -166,7 +166,7 @@ func TestMinMaxSumCountMerge(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := New(descriptor) agg1 := New(descriptor)
agg2 := New(descriptor) agg2 := New(descriptor)
@ -224,7 +224,7 @@ func TestMaxSumCountNotSet(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(descriptor) agg := New(descriptor)
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package counter // import "go.opentelemetry.io/otel/sdk/metric/aggregator/counter" package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
import ( import (
"context" "context"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package counter package sum
import ( import (
"context" "context"
@ -49,13 +49,13 @@ func TestMain(m *testing.M) {
os.Exit(m.Run()) os.Exit(m.Run())
} }
func TestCounterMonotonic(t *testing.T) { func TestCounterSum(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New() agg := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind)
sum := core.Number(0) sum := core.Number(0)
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@ -72,44 +72,23 @@ func TestCounterMonotonic(t *testing.T) {
}) })
} }
func TestCounterMonotonicNegative(t *testing.T) { func TestMeasureSum(t *testing.T) {
ctx := context.Background() ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) { test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New() agg := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
for i := 0; i < count; i++ {
test.CheckedUpdate(t, agg, profile.Random(-1), descriptor)
}
sum := profile.Random(+1)
test.CheckedUpdate(t, agg, sum, descriptor)
agg.Checkpoint(ctx, descriptor)
asum, err := agg.Sum()
require.Equal(t, sum, asum, "Same sum - monotonic")
require.Nil(t, err)
})
}
func TestCounterNonMonotonic(t *testing.T) {
ctx := context.Background()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, true)
sum := core.Number(0) sum := core.Number(0)
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
x := profile.Random(+1) r1 := profile.Random(+1)
y := profile.Random(-1) r2 := profile.Random(-1)
sum.AddNumber(profile.NumberKind, x) test.CheckedUpdate(t, agg, r1, descriptor)
sum.AddNumber(profile.NumberKind, y) test.CheckedUpdate(t, agg, r2, descriptor)
test.CheckedUpdate(t, agg, x, descriptor) sum.AddNumber(profile.NumberKind, r1)
test.CheckedUpdate(t, agg, y, descriptor) sum.AddNumber(profile.NumberKind, r2)
} }
agg.Checkpoint(ctx, descriptor) agg.Checkpoint(ctx, descriptor)
@ -127,7 +106,7 @@ func TestCounterMerge(t *testing.T) {
agg1 := New() agg1 := New()
agg2 := New() agg2 := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, false) descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind)
sum := core.Number(0) sum := core.Number(0)
for i := 0; i < count; i++ { for i := 0; i < count; i++ {

View File

@ -53,9 +53,8 @@ func newProfiles() []Profile {
} }
} }
func NewAggregatorTest(mkind export.Kind, nkind core.NumberKind, alternate bool) *export.Descriptor { func NewAggregatorTest(mkind export.Kind, nkind core.NumberKind) *export.Descriptor {
desc := export.NewDescriptor("test.name", mkind, nil, "", "", nkind, alternate) return export.NewDescriptor("test.name", mkind, nil, "", "", nkind)
return desc
} }
func RunProfiles(t *testing.T, f func(*testing.T, Profile)) { func RunProfiles(t *testing.T, f func(*testing.T, Profile)) {

View File

@ -56,10 +56,10 @@ func TestGroupingStateless(t *testing.T) {
// Output lastvalue should have only the "G=H" and "G=" keys. // Output lastvalue should have only the "G=H" and "G=" keys.
// Output counter should have only the "C=D" and "C=" keys. // Output counter should have only the "C=D" and "C=" keys.
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/C=D": 30, // labels1 + labels2 "sum.a/C=D": 30, // labels1 + labels2
"counter.a/C=": 40, // labels3 "sum.a/C=": 40, // labels3
"counter.b/C=D": 30, // labels1 + labels2 "sum.b/C=D": 30, // labels1 + labels2
"counter.b/C=": 40, // labels3 "sum.b/C=": 40, // labels3
"lastvalue.a/G=H": 10, // labels1 "lastvalue.a/G=H": 10, // labels1
"lastvalue.a/G=": 30, // labels3 = last value "lastvalue.a/G=": 30, // labels3 = last value
"lastvalue.b/G=H": 10, // labels1 "lastvalue.b/G=H": 10, // labels1
@ -93,8 +93,8 @@ func TestGroupingStateful(t *testing.T) {
checkpointSet.ForEach(records1.AddTo) checkpointSet.ForEach(records1.AddTo)
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/C=D": 10, // labels1 "sum.a/C=D": 10, // labels1
"counter.b/C=D": 10, // labels1 "sum.b/C=D": 10, // labels1
}, records1) }, records1)
// Test that state was NOT reset // Test that state was NOT reset
@ -133,7 +133,7 @@ func TestGroupingStateful(t *testing.T) {
checkpointSet.ForEach(records4.AddTo) checkpointSet.ForEach(records4.AddTo)
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/C=D": 30, "sum.a/C=D": 30,
"counter.b/C=D": 30, "sum.b/C=D": 30,
}, records4) }, records4)
} }

View File

@ -23,8 +23,8 @@ import (
"go.opentelemetry.io/otel/api/key" "go.opentelemetry.io/otel/api/key"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
type ( type (
@ -43,14 +43,14 @@ type (
var ( var (
// LastValueADesc and LastValueBDesc group by "G" // LastValueADesc and LastValueBDesc group by "G"
LastValueADesc = export.NewDescriptor( LastValueADesc = export.NewDescriptor(
"lastvalue.a", export.ObserverKind, []core.Key{key.New("G")}, "", "", core.Int64NumberKind, false) "lastvalue.a", export.ObserverKind, []core.Key{key.New("G")}, "", "", core.Int64NumberKind)
LastValueBDesc = export.NewDescriptor( LastValueBDesc = export.NewDescriptor(
"lastvalue.b", export.ObserverKind, []core.Key{key.New("G")}, "", "", core.Int64NumberKind, false) "lastvalue.b", export.ObserverKind, []core.Key{key.New("G")}, "", "", core.Int64NumberKind)
// CounterADesc and CounterBDesc group by "C" // CounterADesc and CounterBDesc group by "C"
CounterADesc = export.NewDescriptor( CounterADesc = export.NewDescriptor(
"counter.a", export.CounterKind, []core.Key{key.New("C")}, "", "", core.Int64NumberKind, false) "sum.a", export.CounterKind, []core.Key{key.New("C")}, "", "", core.Int64NumberKind)
CounterBDesc = export.NewDescriptor( CounterBDesc = export.NewDescriptor(
"counter.b", export.CounterKind, []core.Key{key.New("C")}, "", "", core.Int64NumberKind, false) "sum.b", export.CounterKind, []core.Key{key.New("C")}, "", "", core.Int64NumberKind)
// SdkEncoder uses a non-standard encoder like K1~V1&K2~V2 // SdkEncoder uses a non-standard encoder like K1~V1&K2~V2
SdkEncoder = &Encoder{} SdkEncoder = &Encoder{}
@ -69,7 +69,7 @@ var (
) )
// NewAggregationSelector returns a policy that is consistent with the // NewAggregationSelector returns a policy that is consistent with the
// test descriptors above. I.e., it returns counter.New() for counter // test descriptors above. I.e., it returns sum.New() for counter
// instruments and lastvalue.New for lastValue instruments. // instruments and lastvalue.New for lastValue instruments.
func NewAggregationSelector() export.AggregationSelector { func NewAggregationSelector() export.AggregationSelector {
return &testAggregationSelector{} return &testAggregationSelector{}
@ -78,7 +78,7 @@ func NewAggregationSelector() export.AggregationSelector {
func (*testAggregationSelector) AggregatorFor(desc *export.Descriptor) export.Aggregator { func (*testAggregationSelector) AggregatorFor(desc *export.Descriptor) export.Aggregator {
switch desc.MetricKind() { switch desc.MetricKind() {
case export.CounterKind: case export.CounterKind:
return counter.New() return sum.New()
case export.ObserverKind: case export.ObserverKind:
return lastvalue.New() return lastvalue.New()
default: default:
@ -126,7 +126,7 @@ func NewCounterRecord(desc *export.Descriptor, labels export.Labels, value int64
// CounterAgg returns a checkpointed counter aggregator w/ the specified descriptor and value. // CounterAgg returns a checkpointed counter aggregator w/ the specified descriptor and value.
func CounterAgg(desc *export.Descriptor, v int64) export.Aggregator { func CounterAgg(desc *export.Descriptor, v int64) export.Aggregator {
ctx := context.Background() ctx := context.Background()
cagg := counter.New() cagg := sum.New()
_ = cagg.Update(ctx, core.NewInt64Number(v), desc) _ = cagg.Update(ctx, core.NewInt64Number(v), desc)
cagg.Checkpoint(ctx, desc) cagg.Checkpoint(ctx, desc)
return cagg return cagg
@ -139,7 +139,7 @@ func (o Output) AddTo(rec export.Record) {
key := fmt.Sprint(rec.Descriptor().Name(), "/", labels.Encoded()) key := fmt.Sprint(rec.Descriptor().Name(), "/", labels.Encoded())
var value int64 var value int64
switch t := rec.Aggregator().(type) { switch t := rec.Aggregator().(type) {
case *counter.Aggregator: case *sum.Aggregator:
sum, _ := t.Sum() sum, _ := t.Sum()
value = sum.AsInt64() value = sum.AsInt64()
case *lastvalue.Aggregator: case *lastvalue.Aggregator:

View File

@ -67,12 +67,12 @@ func TestUngroupedStateless(t *testing.T) {
// Output lastvalue should have only the "G=H" and "G=" keys. // Output lastvalue should have only the "G=H" and "G=" keys.
// Output counter should have only the "C=D" and "C=" keys. // Output counter should have only the "C=D" and "C=" keys.
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 60, // labels1 "sum.a/G~H&C~D": 60, // labels1
"counter.a/C~D&E~F": 20, // labels2 "sum.a/C~D&E~F": 20, // labels2
"counter.a/": 40, // labels3 "sum.a/": 40, // labels3
"counter.b/G~H&C~D": 60, // labels1 "sum.b/G~H&C~D": 60, // labels1
"counter.b/C~D&E~F": 20, // labels2 "sum.b/C~D&E~F": 20, // labels2
"counter.b/": 40, // labels3 "sum.b/": 40, // labels3
"lastvalue.a/G~H&C~D": 50, // labels1 "lastvalue.a/G~H&C~D": 50, // labels1
"lastvalue.a/C~D&E~F": 20, // labels2 "lastvalue.a/C~D&E~F": 20, // labels2
"lastvalue.a/": 30, // labels3 "lastvalue.a/": 30, // labels3
@ -108,8 +108,8 @@ func TestUngroupedStateful(t *testing.T) {
checkpointSet.ForEach(records1.AddTo) checkpointSet.ForEach(records1.AddTo)
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 10, // labels1 "sum.a/G~H&C~D": 10, // labels1
"counter.b/G~H&C~D": 10, // labels1 "sum.b/G~H&C~D": 10, // labels1
}, records1) }, records1)
// Test that state was NOT reset // Test that state was NOT reset
@ -148,7 +148,7 @@ func TestUngroupedStateful(t *testing.T) {
checkpointSet.ForEach(records4.AddTo) checkpointSet.ForEach(records4.AddTo)
require.EqualValues(t, map[string]int64{ require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 30, "sum.a/G~H&C~D": 30,
"counter.b/G~H&C~D": 30, "sum.b/G~H&C~D": 30,
}, records4) }, records4)
} }

View File

@ -26,10 +26,10 @@ import (
"go.opentelemetry.io/otel/api/metric" "go.opentelemetry.io/otel/api/metric"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch" "go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
type benchFixture struct { type benchFixture struct {
@ -52,7 +52,7 @@ func (*benchFixture) AggregatorFor(descriptor *export.Descriptor) export.Aggrega
name := descriptor.Name() name := descriptor.Name()
switch { switch {
case strings.HasSuffix(name, "counter"): case strings.HasSuffix(name, "counter"):
return counter.New() return sum.New()
case strings.HasSuffix(name, "lastvalue"): case strings.HasSuffix(name, "lastvalue"):
return lastvalue.New() return lastvalue.New()
default: default:

View File

@ -30,7 +30,7 @@ import (
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregator" "go.opentelemetry.io/otel/sdk/export/metric/aggregator"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
"go.opentelemetry.io/otel/sdk/metric/controller/push" "go.opentelemetry.io/otel/sdk/metric/controller/push"
) )
@ -85,7 +85,7 @@ func newFixture(t *testing.T) testFixture {
} }
func (b *testBatcher) AggregatorFor(*export.Descriptor) export.Aggregator { func (b *testBatcher) AggregatorFor(*export.Descriptor) export.Aggregator {
return counter.New() return sum.New()
} }
func (b *testBatcher) CheckpointSet() export.CheckpointSet { func (b *testBatcher) CheckpointSet() export.CheckpointSet {

View File

@ -30,7 +30,7 @@ import (
"go.opentelemetry.io/otel/sdk/export/metric/aggregator" "go.opentelemetry.io/otel/sdk/export/metric/aggregator"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array" "go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter" "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
var Must = metric.Must var Must = metric.Must
@ -47,7 +47,7 @@ func (cb *correctnessBatcher) AggregatorFor(descriptor *export.Descriptor) expor
name := descriptor.Name() name := descriptor.Name()
switch { switch {
case strings.HasSuffix(name, ".counter"): case strings.HasSuffix(name, ".counter"):
return counter.New() return sum.New()
case strings.HasSuffix(name, ".disabled"): case strings.HasSuffix(name, ".disabled"):
return nil return nil
default: default:
@ -84,7 +84,7 @@ func TestInputRangeTestCounter(t *testing.T) {
sdkErr = handleErr sdkErr = handleErr
}) })
counter := Must(sdk).NewInt64Counter("name.counter", metric.WithMonotonic(true)) counter := Must(sdk).NewInt64Counter("name.counter")
counter.Add(ctx, -1, sdk.Labels()) counter.Add(ctx, -1, sdk.Labels())
require.Equal(t, aggregator.ErrNegativeInput, sdkErr) require.Equal(t, aggregator.ErrNegativeInput, sdkErr)
@ -118,10 +118,10 @@ func TestInputRangeTestMeasure(t *testing.T) {
sdkErr = handleErr sdkErr = handleErr
}) })
measure := Must(sdk).NewFloat64Measure("name.measure", metric.WithAbsolute(true)) measure := Must(sdk).NewFloat64Measure("name.measure")
measure.Record(ctx, -1, sdk.Labels()) measure.Record(ctx, math.NaN(), sdk.Labels())
require.Equal(t, aggregator.ErrNegativeInput, sdkErr) require.Equal(t, aggregator.ErrNaNInput, sdkErr)
sdkErr = nil sdkErr = nil
checkpointed := sdk.Collect(ctx) checkpointed := sdk.Collect(ctx)
@ -149,7 +149,7 @@ func TestDisabledInstrument(t *testing.T) {
t: t, t: t,
} }
sdk := sdk.New(batcher, sdk.NewDefaultLabelEncoder()) sdk := sdk.New(batcher, sdk.NewDefaultLabelEncoder())
measure := Must(sdk).NewFloat64Measure("name.disabled", metric.WithAbsolute(true)) measure := Must(sdk).NewFloat64Measure("name.disabled")
measure.Record(ctx, -1, sdk.Labels()) measure.Record(ctx, -1, sdk.Labels())
checkpointed := sdk.Collect(ctx) checkpointed := sdk.Collect(ctx)
@ -169,7 +169,7 @@ func TestRecordNaN(t *testing.T) {
sdk.SetErrorHandler(func(handleErr error) { sdk.SetErrorHandler(func(handleErr error) {
sdkErr = handleErr sdkErr = handleErr
}) })
c := Must(sdk).NewFloat64Counter("counter.name") c := Must(sdk).NewFloat64Counter("sum.name")
require.Nil(t, sdkErr) require.Nil(t, sdkErr)
c.Add(ctx, math.NaN(), sdk.Labels()) c.Add(ctx, math.NaN(), sdk.Labels())

View File

@ -30,7 +30,7 @@ import (
) )
func TestStressInt64Histogram(t *testing.T) { func TestStressInt64Histogram(t *testing.T) {
desc := metric.NewDescriptor("some_metric", metric.MeasureKind, nil, "", "", core.Int64NumberKind, false) desc := metric.NewDescriptor("some_metric", metric.MeasureKind, nil, "", "", core.Int64NumberKind)
h := histogram.New(desc, []core.Number{core.NewInt64Number(25), core.NewInt64Number(50), core.NewInt64Number(75)}) h := histogram.New(desc, []core.Number{core.NewInt64Number(25), core.NewInt64Number(50), core.NewInt64Number(75)})
go func() { go func() {

View File

@ -461,18 +461,18 @@ func (m *SDK) labsFor(ls api.LabelSet) *labels {
return &m.empty return &m.empty
} }
func newDescriptor(name string, metricKind export.Kind, numberKind core.NumberKind, opts *api.Options) *export.Descriptor { func newDescriptor(name string, metricKind export.Kind, numberKind core.NumberKind, opts []api.Option) *export.Descriptor {
config := api.Configure(opts)
return export.NewDescriptor( return export.NewDescriptor(
name, name,
metricKind, metricKind,
opts.Keys, config.Keys,
opts.Description, config.Description,
opts.Unit, config.Unit,
numberKind, numberKind)
opts.Alternate)
} }
func (m *SDK) newInstrument(name string, metricKind export.Kind, numberKind core.NumberKind, opts *api.Options) *instrument { func (m *SDK) newInstrument(name string, metricKind export.Kind, numberKind core.NumberKind, opts []api.Option) *instrument {
descriptor := newDescriptor(name, metricKind, numberKind, opts) descriptor := newDescriptor(name, metricKind, numberKind, opts)
return &instrument{ return &instrument{
descriptor: descriptor, descriptor: descriptor,
@ -480,41 +480,35 @@ func (m *SDK) newInstrument(name string, metricKind export.Kind, numberKind core
} }
} }
func (m *SDK) newCounterInstrument(name string, numberKind core.NumberKind, cos ...api.CounterOptionApplier) *instrument { func (m *SDK) newCounterInstrument(name string, numberKind core.NumberKind, opts []api.Option) *instrument {
opts := api.Options{} return m.newInstrument(name, export.CounterKind, numberKind, opts)
api.ApplyCounterOptions(&opts, cos...)
return m.newInstrument(name, export.CounterKind, numberKind, &opts)
} }
func (m *SDK) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...api.MeasureOptionApplier) *instrument { func (m *SDK) newMeasureInstrument(name string, numberKind core.NumberKind, opts []api.Option) *instrument {
opts := api.Options{} return m.newInstrument(name, export.MeasureKind, numberKind, opts)
api.ApplyMeasureOptions(&opts, mos...)
return m.newInstrument(name, export.MeasureKind, numberKind, &opts)
} }
func (m *SDK) NewInt64Counter(name string, cos ...api.CounterOptionApplier) (api.Int64Counter, error) { func (m *SDK) NewInt64Counter(name string, opts ...api.Option) (api.Int64Counter, error) {
return api.WrapInt64CounterInstrument(m.newCounterInstrument(name, core.Int64NumberKind, cos...), nil) return api.WrapInt64CounterInstrument(m.newCounterInstrument(name, core.Int64NumberKind, opts), nil)
} }
func (m *SDK) NewFloat64Counter(name string, cos ...api.CounterOptionApplier) (api.Float64Counter, error) { func (m *SDK) NewFloat64Counter(name string, opts ...api.Option) (api.Float64Counter, error) {
return api.WrapFloat64CounterInstrument(m.newCounterInstrument(name, core.Float64NumberKind, cos...), nil) return api.WrapFloat64CounterInstrument(m.newCounterInstrument(name, core.Float64NumberKind, opts), nil)
} }
func (m *SDK) NewInt64Measure(name string, mos ...api.MeasureOptionApplier) (api.Int64Measure, error) { func (m *SDK) NewInt64Measure(name string, opts ...api.Option) (api.Int64Measure, error) {
return api.WrapInt64MeasureInstrument(m.newMeasureInstrument(name, core.Int64NumberKind, mos...), nil) return api.WrapInt64MeasureInstrument(m.newMeasureInstrument(name, core.Int64NumberKind, opts), nil)
} }
func (m *SDK) NewFloat64Measure(name string, mos ...api.MeasureOptionApplier) (api.Float64Measure, error) { func (m *SDK) NewFloat64Measure(name string, opts ...api.Option) (api.Float64Measure, error) {
return api.WrapFloat64MeasureInstrument(m.newMeasureInstrument(name, core.Float64NumberKind, mos...), nil) return api.WrapFloat64MeasureInstrument(m.newMeasureInstrument(name, core.Float64NumberKind, opts), nil)
} }
func (m *SDK) RegisterInt64Observer(name string, callback api.Int64ObserverCallback, oos ...api.ObserverOptionApplier) (api.Int64Observer, error) { func (m *SDK) RegisterInt64Observer(name string, callback api.Int64ObserverCallback, opts ...api.Option) (api.Int64Observer, error) {
if callback == nil { if callback == nil {
return api.NoopMeter{}.RegisterInt64Observer("", nil) return api.NoopMeter{}.RegisterInt64Observer("", nil)
} }
opts := api.Options{} descriptor := newDescriptor(name, export.ObserverKind, core.Int64NumberKind, opts)
api.ApplyObserverOptions(&opts, oos...)
descriptor := newDescriptor(name, export.ObserverKind, core.Int64NumberKind, &opts)
cb := wrapInt64ObserverCallback(callback) cb := wrapInt64ObserverCallback(callback)
obs := m.newObserver(descriptor, cb) obs := m.newObserver(descriptor, cb)
return int64Observer{ return int64Observer{
@ -531,13 +525,11 @@ func wrapInt64ObserverCallback(callback api.Int64ObserverCallback) observerCallb
} }
} }
func (m *SDK) RegisterFloat64Observer(name string, callback api.Float64ObserverCallback, oos ...api.ObserverOptionApplier) (api.Float64Observer, error) { func (m *SDK) RegisterFloat64Observer(name string, callback api.Float64ObserverCallback, opts ...api.Option) (api.Float64Observer, error) {
if callback == nil { if callback == nil {
return api.NoopMeter{}.RegisterFloat64Observer("", nil) return api.NoopMeter{}.RegisterFloat64Observer("", nil)
} }
opts := api.Options{} descriptor := newDescriptor(name, export.ObserverKind, core.Float64NumberKind, opts)
api.ApplyObserverOptions(&opts, oos...)
descriptor := newDescriptor(name, export.ObserverKind, core.Float64NumberKind, &opts)
cb := wrapFloat64ObserverCallback(callback) cb := wrapFloat64ObserverCallback(callback)
obs := m.newObserver(descriptor, cb) obs := m.newObserver(descriptor, cb)
return float64Observer{ return float64Observer{

View File

@ -17,9 +17,9 @@ package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
import ( import (
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array" "go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch" "go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
type ( type (
@ -72,7 +72,7 @@ func (selectorInexpensive) AggregatorFor(descriptor *export.Descriptor) export.A
case export.MeasureKind: case export.MeasureKind:
return minmaxsumcount.New(descriptor) return minmaxsumcount.New(descriptor)
default: default:
return counter.New() return sum.New()
} }
} }
@ -83,7 +83,7 @@ func (s selectorSketch) AggregatorFor(descriptor *export.Descriptor) export.Aggr
case export.MeasureKind: case export.MeasureKind:
return ddsketch.New(s.config, descriptor) return ddsketch.New(s.config, descriptor)
default: default:
return counter.New() return sum.New()
} }
} }
@ -94,6 +94,6 @@ func (selectorExact) AggregatorFor(descriptor *export.Descriptor) export.Aggrega
case export.MeasureKind: case export.MeasureKind:
return array.New() return array.New()
default: default:
return counter.New() return sum.New()
} }
} }

View File

@ -22,35 +22,35 @@ import (
"go.opentelemetry.io/otel/api/core" "go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array" "go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch" "go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount" "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
"go.opentelemetry.io/otel/sdk/metric/selector/simple" "go.opentelemetry.io/otel/sdk/metric/selector/simple"
) )
var ( var (
testCounterDesc = export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind, false) testCounterDesc = export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind)
testMeasureDesc = export.NewDescriptor("measure", export.MeasureKind, nil, "", "", core.Int64NumberKind, false) testMeasureDesc = export.NewDescriptor("measure", export.MeasureKind, nil, "", "", core.Int64NumberKind)
testObserverDesc = export.NewDescriptor("observer", export.ObserverKind, nil, "", "", core.Int64NumberKind, false) testObserverDesc = export.NewDescriptor("observer", export.ObserverKind, nil, "", "", core.Int64NumberKind)
) )
func TestInexpensiveMeasure(t *testing.T) { func TestInexpensiveMeasure(t *testing.T) {
inex := simple.NewWithInexpensiveMeasure() inex := simple.NewWithInexpensiveMeasure()
require.NotPanics(t, func() { _ = inex.AggregatorFor(testCounterDesc).(*counter.Aggregator) }) require.NotPanics(t, func() { _ = inex.AggregatorFor(testCounterDesc).(*sum.Aggregator) })
require.NotPanics(t, func() { _ = inex.AggregatorFor(testMeasureDesc).(*minmaxsumcount.Aggregator) }) require.NotPanics(t, func() { _ = inex.AggregatorFor(testMeasureDesc).(*minmaxsumcount.Aggregator) })
require.NotPanics(t, func() { _ = inex.AggregatorFor(testObserverDesc).(*minmaxsumcount.Aggregator) }) require.NotPanics(t, func() { _ = inex.AggregatorFor(testObserverDesc).(*minmaxsumcount.Aggregator) })
} }
func TestSketchMeasure(t *testing.T) { func TestSketchMeasure(t *testing.T) {
sk := simple.NewWithSketchMeasure(ddsketch.NewDefaultConfig()) sk := simple.NewWithSketchMeasure(ddsketch.NewDefaultConfig())
require.NotPanics(t, func() { _ = sk.AggregatorFor(testCounterDesc).(*counter.Aggregator) }) require.NotPanics(t, func() { _ = sk.AggregatorFor(testCounterDesc).(*sum.Aggregator) })
require.NotPanics(t, func() { _ = sk.AggregatorFor(testMeasureDesc).(*ddsketch.Aggregator) }) require.NotPanics(t, func() { _ = sk.AggregatorFor(testMeasureDesc).(*ddsketch.Aggregator) })
require.NotPanics(t, func() { _ = sk.AggregatorFor(testObserverDesc).(*ddsketch.Aggregator) }) require.NotPanics(t, func() { _ = sk.AggregatorFor(testObserverDesc).(*ddsketch.Aggregator) })
} }
func TestExactMeasure(t *testing.T) { func TestExactMeasure(t *testing.T) {
ex := simple.NewWithExactMeasure() ex := simple.NewWithExactMeasure()
require.NotPanics(t, func() { _ = ex.AggregatorFor(testCounterDesc).(*counter.Aggregator) }) require.NotPanics(t, func() { _ = ex.AggregatorFor(testCounterDesc).(*sum.Aggregator) })
require.NotPanics(t, func() { _ = ex.AggregatorFor(testMeasureDesc).(*array.Aggregator) }) require.NotPanics(t, func() { _ = ex.AggregatorFor(testMeasureDesc).(*array.Aggregator) })
require.NotPanics(t, func() { _ = ex.AggregatorFor(testObserverDesc).(*array.Aggregator) }) require.NotPanics(t, func() { _ = ex.AggregatorFor(testObserverDesc).(*array.Aggregator) })
} }

View File

@ -38,8 +38,8 @@ import (
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregator" "go.opentelemetry.io/otel/sdk/export/metric/aggregator"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/counter"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue" "go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
) )
const ( const (
@ -234,7 +234,7 @@ func (*testFixture) AggregatorFor(descriptor *export.Descriptor) export.Aggregat
name := descriptor.Name() name := descriptor.Name()
switch { switch {
case strings.HasSuffix(name, "counter"): case strings.HasSuffix(name, "counter"):
return counter.New() return sum.New()
case strings.HasSuffix(name, "lastvalue"): case strings.HasSuffix(name, "lastvalue"):
return lastvalue.New() return lastvalue.New()
default: default:
@ -265,15 +265,13 @@ func (f *testFixture) Process(_ context.Context, record export.Record) error {
agg := record.Aggregator() agg := record.Aggregator()
switch record.Descriptor().MetricKind() { switch record.Descriptor().MetricKind() {
case export.CounterKind: case export.CounterKind:
counter := agg.(aggregator.Sum) sum, err := agg.(aggregator.Sum).Sum()
sum, err := counter.Sum()
if err != nil { if err != nil {
f.T.Fatal("Sum error: ", err) f.T.Fatal("Sum error: ", err)
} }
f.impl.storeCollect(actual, sum, time.Time{}) f.impl.storeCollect(actual, sum, time.Time{})
case export.MeasureKind: case export.MeasureKind:
lvagg := agg.(aggregator.LastValue) lv, ts, err := agg.(aggregator.LastValue).LastValue()
lv, ts, err := lvagg.LastValue()
if err != nil && err != aggregator.ErrNoLastValue { if err != nil && err != aggregator.ErrNoLastValue {
f.T.Fatal("Last value error: ", err) f.T.Fatal("Last value error: ", err)
} }
@ -336,18 +334,14 @@ func float64sEqual(a, b core.Number) bool {
// Counters // Counters
func intCounterTestImpl(nonMonotonic bool) testImpl { func intCounterTestImpl() testImpl {
return testImpl{ return testImpl{
newInstrument: func(meter api.Meter, name string) withImpl { newInstrument: func(meter api.Meter, name string) withImpl {
return Must(meter).NewInt64Counter(name+".counter", api.WithMonotonic(!nonMonotonic)) return Must(meter).NewInt64Counter(name + ".counter")
}, },
getUpdateValue: func() core.Number { getUpdateValue: func() core.Number {
var offset int64
if nonMonotonic {
offset = -50
}
for { for {
x := offset + int64(rand.Intn(100)) x := int64(rand.Intn(100))
if x != 0 { if x != 0 {
return core.NewInt64Number(x) return core.NewInt64Number(x)
} }
@ -374,26 +368,18 @@ func intCounterTestImpl(nonMonotonic bool) testImpl {
} }
} }
func TestStressInt64CounterNormal(t *testing.T) { func TestStressInt64Counter(t *testing.T) {
stressTest(t, intCounterTestImpl(false)) stressTest(t, intCounterTestImpl())
} }
func TestStressInt64CounterNonMonotonic(t *testing.T) { func floatCounterTestImpl() testImpl {
stressTest(t, intCounterTestImpl(true))
}
func floatCounterTestImpl(nonMonotonic bool) testImpl {
return testImpl{ return testImpl{
newInstrument: func(meter api.Meter, name string) withImpl { newInstrument: func(meter api.Meter, name string) withImpl {
return Must(meter).NewFloat64Counter(name+".counter", api.WithMonotonic(!nonMonotonic)) return Must(meter).NewFloat64Counter(name + ".counter")
}, },
getUpdateValue: func() core.Number { getUpdateValue: func() core.Number {
var offset float64
if nonMonotonic {
offset = -0.5
}
for { for {
x := offset + rand.Float64() x := rand.Float64()
if x != 0 { if x != 0 {
return core.NewFloat64Number(x) return core.NewFloat64Number(x)
} }
@ -420,12 +406,8 @@ func floatCounterTestImpl(nonMonotonic bool) testImpl {
} }
} }
func TestStressFloat64CounterNormal(t *testing.T) { func TestStressFloat64Counter(t *testing.T) {
stressTest(t, floatCounterTestImpl(false)) stressTest(t, floatCounterTestImpl())
}
func TestStressFloat64CounterNonMonotonic(t *testing.T) {
stressTest(t, floatCounterTestImpl(true))
} }
// LastValue // LastValue
@ -433,7 +415,7 @@ func TestStressFloat64CounterNonMonotonic(t *testing.T) {
func intLastValueTestImpl() testImpl { func intLastValueTestImpl() testImpl {
return testImpl{ return testImpl{
newInstrument: func(meter api.Meter, name string) withImpl { newInstrument: func(meter api.Meter, name string) withImpl {
return Must(meter).NewInt64Measure(name+".lastvalue", metric.WithAbsolute(false)) return Must(meter).NewInt64Measure(name + ".lastvalue")
}, },
getUpdateValue: func() core.Number { getUpdateValue: func() core.Number {
r1 := rand.Int63() r1 := rand.Int63()
@ -475,7 +457,7 @@ func TestStressInt64LastValue(t *testing.T) {
func floatLastValueTestImpl() testImpl { func floatLastValueTestImpl() testImpl {
return testImpl{ return testImpl{
newInstrument: func(meter api.Meter, name string) withImpl { newInstrument: func(meter api.Meter, name string) withImpl {
return Must(meter).NewFloat64Measure(name+".lastvalue", metric.WithAbsolute(false)) return Must(meter).NewFloat64Measure(name + ".lastvalue")
}, },
getUpdateValue: func() core.Number { getUpdateValue: func() core.Number {
return core.NewFloat64Number((-0.5 + rand.Float64()) * 100000) return core.NewFloat64Number((-0.5 + rand.Float64()) * 100000)