1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-12 10:04:29 +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"
export "go.opentelemetry.io/otel/sdk/export/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/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
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 {
switch descriptor.MetricKind() {
case export.CounterKind:
return counter.New()
return sum.New()
case export.MeasureKind:
if strings.HasSuffix(descriptor.Name(), "minmaxsumcount") {
return minmaxsumcount.New(descriptor)

View File

@ -68,7 +68,7 @@ type instImpl struct {
name string
mkind metricKind
nkind core.NumberKind
opts interface{}
opts []metric.Option
}
type obsImpl struct {
@ -76,7 +76,7 @@ type obsImpl struct {
name string
nkind core.NumberKind
opts []metric.ObserverOptionApplier
opts []metric.Option
meter *meter
callback interface{}
}
@ -181,7 +181,7 @@ func (m *meter) setDelegate(provider metric.Provider) {
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()
defer m.lock.Unlock()
@ -209,18 +209,18 @@ func delegateCheck(has hasImpl, err error) (metric.InstrumentImpl, error) {
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 {
case counterKind:
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:
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
}
@ -419,34 +419,34 @@ func (labels *labelSet) Delegate() metric.LabelSet {
// 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))
}
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))
}
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))
}
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))
}
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()
defer m.lock.Unlock()
if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).RegisterInt64Observer(name, callback, oos...)
return (*meterPtr).RegisterInt64Observer(name, callback, opts...)
}
obs := &obsImpl{
name: name,
nkind: core.Int64NumberKind,
opts: oos,
opts: opts,
meter: m,
callback: callback,
}
@ -456,18 +456,18 @@ func (m *meter) RegisterInt64Observer(name string, callback metric.Int64Observer
}, 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()
defer m.lock.Unlock()
if meterPtr := (*metric.Meter)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).RegisterFloat64Observer(name, callback, oos...)
return (*meterPtr).RegisterFloat64Observer(name, callback, opts...)
}
obs := &obsImpl{
name: name,
nkind: core.Float64NumberKind,
opts: oos,
opts: opts,
meter: m,
callback: callback,
}

View File

@ -278,7 +278,7 @@ func (m *meterProviderWithConstructorError) Meter(name string) metric.Meter {
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")
}

View File

@ -33,8 +33,8 @@ type Provider interface {
type LabelSet interface {
}
// Options contains some options for metrics of any kind.
type Options struct {
// Config contains some options for metrics of any kind.
type Config struct {
// Description is an optional field describing the metric
// instrument.
Description string
@ -43,42 +43,12 @@ type Options struct {
// Keys are recommended keys determined in the handles
// obtained for the metric.
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
// that are valid only for counter metrics.
type CounterOptionApplier interface {
// ApplyCounterOption is used to make some general or
// 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)
// Option is an interface for applying metric options.
type Option interface {
// Apply is used to set the Option value of a Config.
Apply(*Config)
}
// 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
// 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
// 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
// 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
// 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
// given name, running a given callback, and customized with passed
// 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
// with a given name, running a given callback, and customized with
// 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
@ -172,138 +142,36 @@ type Float64Observer interface {
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.
func WithDescription(desc string) OptionApplier {
return optionWrapper{
F: func(opts *Options) {
opts.Description = desc
},
}
func WithDescription(desc string) Option {
return descriptionOption(desc)
}
type descriptionOption string
func (d descriptionOption) Apply(config *Config) {
config.Description = string(d)
}
// WithUnit applies provided unit.
func WithUnit(unit unit.Unit) OptionApplier {
return optionWrapper{
F: func(opts *Options) {
opts.Unit = unit
},
}
func WithUnit(unit unit.Unit) Option {
return unitOption(unit)
}
type unitOption unit.Unit
func (u unitOption) Apply(config *Config) {
config.Unit = unit.Unit(u)
}
// WithKeys applies recommended label keys. Multiple `WithKeys`
// options accumulate.
func WithKeys(keys ...core.Key) OptionApplier {
return optionWrapper{
F: func(opts *Options) {
opts.Keys = append(opts.Keys, keys...)
},
}
func WithKeys(keys ...core.Key) Option {
return keysOption(keys)
}
// WithMonotonic sets whether a counter or an observer is not
// 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
},
}
}
type keysOption []core.Key
// WithAbsolute sets whether a measure is not permitted to be
// negative.
func WithAbsolute(absolute bool) MeasureOptionApplier {
return measureOptionWrapper{
F: func(opts *Options) {
opts.Alternate = !absolute
},
}
func (k keysOption) Apply(config *Config) {
config.Keys = append(config.Keys, k...)
}

View File

@ -33,14 +33,13 @@ import (
var Must = metric.Must
func TestCounterOptions(t *testing.T) {
func TestOptions(t *testing.T) {
type testcase struct {
name string
opts []metric.CounterOptionApplier
opts []metric.Option
keys []core.Key
desc string
unit unit.Unit
alt bool
}
testcases := []testcase{
{
@ -49,11 +48,10 @@ func TestCounterOptions(t *testing.T) {
keys: nil,
desc: "",
unit: "",
alt: false,
},
{
name: "keys keys keys",
opts: []metric.CounterOptionApplier{
opts: []metric.Option{
metric.WithKeys(key.New("foo"), key.New("foo2")),
metric.WithKeys(key.New("bar"), key.New("bar2")),
metric.WithKeys(key.New("baz"), key.New("baz2")),
@ -65,310 +63,55 @@ func TestCounterOptions(t *testing.T) {
},
desc: "",
unit: "",
alt: false,
},
{
name: "description",
opts: []metric.CounterOptionApplier{
opts: []metric.Option{
metric.WithDescription("stuff"),
},
keys: nil,
desc: "stuff",
unit: "",
alt: false,
},
{
name: "description override",
opts: []metric.CounterOptionApplier{
opts: []metric.Option{
metric.WithDescription("stuff"),
metric.WithDescription("things"),
},
keys: nil,
desc: "things",
unit: "",
alt: false,
},
{
name: "unit",
opts: []metric.CounterOptionApplier{
opts: []metric.Option{
metric.WithUnit("s"),
},
keys: nil,
desc: "",
unit: "s",
alt: false,
},
{
name: "unit override",
opts: []metric.CounterOptionApplier{
opts: []metric.Option{
metric.WithUnit("s"),
metric.WithUnit("h"),
},
keys: nil,
desc: "",
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 {
t.Logf("Testing counter case %s (%d)", tt.name, idx)
opts := &metric.Options{}
metric.ApplyCounterOptions(opts, tt.opts...)
checkOptions(t, opts, &metric.Options{
if diff := cmp.Diff(metric.Configure(tt.opts), metric.Config{
Description: tt.desc,
Unit: tt.unit,
Keys: tt.keys,
Alternate: tt.alt,
})
}
}
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)
}); diff != "" {
t.Errorf("Compare options: -got +want %s", diff)
}
}
}

View File

@ -29,7 +29,7 @@ func Must(meter Meter) MeterMust {
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
// 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 {
panic(err)
} else {
@ -39,7 +39,7 @@ func (mm MeterMust) NewInt64Counter(name string, cos ...CounterOptionApplier) In
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
// 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 {
panic(err)
} else {
@ -49,7 +49,7 @@ func (mm MeterMust) NewFloat64Counter(name string, cos ...CounterOptionApplier)
// NewInt64Measure calls `Meter.NewInt64Measure` and returns the
// 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 {
panic(err)
} else {
@ -59,7 +59,7 @@ func (mm MeterMust) NewInt64Measure(name string, mos ...MeasureOptionApplier) In
// NewFloat64Measure calls `Meter.NewFloat64Measure` and returns the
// 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 {
panic(err)
} else {
@ -69,7 +69,7 @@ func (mm MeterMust) NewFloat64Measure(name string, mos ...MeasureOptionApplier)
// RegisterInt64Observer calls `Meter.RegisterInt64Observer` and
// 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 {
panic(err)
} else {
@ -79,7 +79,7 @@ func (mm MeterMust) RegisterInt64Observer(name string, callback Int64ObserverCal
// RegisterFloat64Observer calls `Meter.RegisterFloat64Observer` and
// 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 {
panic(err)
} else {

View File

@ -59,26 +59,26 @@ func (NoopMeter) Labels(...core.KeyValue) LabelSet {
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)
}
func (NoopMeter) NewFloat64Counter(name string, cos ...CounterOptionApplier) (Float64Counter, error) {
func (NoopMeter) NewFloat64Counter(name string, cos ...Option) (Float64Counter, error) {
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)
}
func (NoopMeter) NewFloat64Measure(name string, mos ...MeasureOptionApplier) (Float64Measure, error) {
func (NoopMeter) NewFloat64Measure(name string, mos ...Option) (Float64Measure, error) {
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
}
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
}

View File

@ -87,26 +87,11 @@ func WrapFloat64MeasureInstrument(instrument InstrumentImpl, err error) (Float64
return Float64Measure{commonMetric: common}, err
}
// ApplyCounterOptions is a helper that applies all the counter
// options to passed opts.
func ApplyCounterOptions(opts *Options, cos ...CounterOptionApplier) {
for _, o := range cos {
o.ApplyCounterOption(opts)
}
}
// 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)
// Configure is a helper that applies all the options to a Config.
func Configure(opts []Option) Config {
var config Config
for _, o := range opts {
o.Apply(&config)
}
return config
}

View File

@ -29,7 +29,7 @@ import (
"go.opentelemetry.io/otel/exporters/metric/test"
export "go.opentelemetry.io/otel/sdk/export/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,
@ -44,8 +44,8 @@ func TestDogstatsLabels(t *testing.T) {
ctx := context.Background()
checkpointSet := test.NewCheckpointSet(encoder)
desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind, false)
cagg := counter.New()
desc := export.NewDescriptor("test.name", export.CounterKind, nil, "", "", core.Int64NumberKind)
cagg := sum.New()
_ = cagg.Update(ctx, core.NewInt64Number(123), desc)
cagg.Checkpoint(ctx, desc)

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@ import (
"go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric"
"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/sum"
)
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) {
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) {

View File

@ -32,7 +32,7 @@ type (
Name string
Kind Kind
NumberKind core.NumberKind
Opts apimetric.Options
Config apimetric.Config
}
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) {
instrument := m.newCounterInstrument(name, core.Int64NumberKind, cos...)
func (m *Meter) NewInt64Counter(name string, opts ...apimetric.Option) (apimetric.Int64Counter, error) {
instrument := m.newCounterInstrument(name, core.Int64NumberKind, opts)
return apimetric.WrapInt64CounterInstrument(instrument, nil)
}
func (m *Meter) NewFloat64Counter(name string, cos ...apimetric.CounterOptionApplier) (apimetric.Float64Counter, error) {
instrument := m.newCounterInstrument(name, core.Float64NumberKind, cos...)
func (m *Meter) NewFloat64Counter(name string, opts ...apimetric.Option) (apimetric.Float64Counter, error) {
instrument := m.newCounterInstrument(name, core.Float64NumberKind, opts)
return apimetric.WrapFloat64CounterInstrument(instrument, nil)
}
func (m *Meter) newCounterInstrument(name string, numberKind core.NumberKind, cos ...apimetric.CounterOptionApplier) *Instrument {
opts := apimetric.Options{}
apimetric.ApplyCounterOptions(&opts, cos...)
func (m *Meter) newCounterInstrument(name string, numberKind core.NumberKind, opts []apimetric.Option) *Instrument {
return &Instrument{
Name: name,
Kind: KindCounter,
NumberKind: numberKind,
Opts: opts,
Config: apimetric.Configure(opts),
}
}
func (m *Meter) NewInt64Measure(name string, mos ...apimetric.MeasureOptionApplier) (apimetric.Int64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Int64NumberKind, mos...)
func (m *Meter) NewInt64Measure(name string, opts ...apimetric.Option) (apimetric.Int64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Int64NumberKind, opts)
return apimetric.WrapInt64MeasureInstrument(instrument, nil)
}
func (m *Meter) NewFloat64Measure(name string, mos ...apimetric.MeasureOptionApplier) (apimetric.Float64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Float64NumberKind, mos...)
func (m *Meter) NewFloat64Measure(name string, opts ...apimetric.Option) (apimetric.Float64Measure, error) {
instrument := m.newMeasureInstrument(name, core.Float64NumberKind, opts)
return apimetric.WrapFloat64MeasureInstrument(instrument, nil)
}
func (m *Meter) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...apimetric.MeasureOptionApplier) *Instrument {
opts := apimetric.Options{}
apimetric.ApplyMeasureOptions(&opts, mos...)
func (m *Meter) newMeasureInstrument(name string, numberKind core.NumberKind, opts []apimetric.Option) *Instrument {
return &Instrument{
Name: name,
Kind: KindMeasure,
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)
return m.newObserver(name, wrappedCallback, core.Int64NumberKind, oos...), nil
return m.newObserver(name, wrappedCallback, core.Int64NumberKind, opts), nil
}
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)
return m.newObserver(name, wrappedCallback, core.Float64NumberKind, oos...), nil
return m.newObserver(name, wrappedCallback, core.Float64NumberKind, opts), nil
}
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 {
opts := apimetric.Options{}
apimetric.ApplyObserverOptions(&opts, oos...)
func (m *Meter) newObserver(name string, callback observerCallback, numberKind core.NumberKind, opts []apimetric.Option) *Observer {
obs := &Observer{
Instrument: &Instrument{
Name: name,
Kind: KindObserver,
NumberKind: numberKind,
Opts: opts,
Config: apimetric.Configure(opts),
},
Meter: m,
Dead: false,

View File

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

View File

@ -16,7 +16,6 @@ package aggregator_test // import "go.opentelemetry.io/otel/sdk/export/metric/ag
import (
"errors"
"fmt"
"math"
"testing"
@ -25,15 +24,15 @@ import (
"go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric"
"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/sum"
)
func TestInconsistentMergeErr(t *testing.T) {
err := aggregator.NewInconsistentMergeError(counter.New(), lastvalue.New())
err := aggregator.NewInconsistentMergeError(sum.New(), lastvalue.New())
require.Equal(
t,
"cannot merge *counter.Aggregator with *lastvalue.Aggregator: inconsistent aggregator types",
"cannot merge *sum.Aggregator with *lastvalue.Aggregator: inconsistent aggregator types",
err.Error(),
)
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
if desc.NumberKind() == core.Float64NumberKind {
@ -66,15 +65,27 @@ func testRangeNegative(t *testing.T, alt bool, desc *export.Descriptor) {
negErr := aggregator.RangeTest(neg, desc)
require.Nil(t, posErr)
if desc.MetricKind() == export.ObserverKind {
require.Nil(t, negErr)
} else {
require.Equal(t, negErr == nil, alt)
}
require.Equal(t, negErr, aggregator.ErrNegativeInput)
}
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} {
t.Run(nkind.String(), func(t *testing.T) {
for _, mkind := range []export.Kind{
@ -82,23 +93,15 @@ func TestRangeTest(t *testing.T) {
export.MeasureKind,
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(
"name",
mkind,
nil,
"",
"",
nkind,
alt,
)
testRangeNaN(t, desc)
testRangeNegative(t, alt, desc)
})
}
})
desc := export.NewDescriptor(
"name",
mkind,
nil,
"",
"",
nkind,
)
testRangeNaN(t, desc)
}
})
}

View File

@ -309,7 +309,6 @@ type Descriptor struct {
description string
unit unit.Unit
numberKind core.NumberKind
alternate bool
}
// NewDescriptor builds a new descriptor, for use by `Meter`
@ -325,7 +324,6 @@ func NewDescriptor(
description string,
unit unit.Unit,
numberKind core.NumberKind,
alternate bool,
) *Descriptor {
return &Descriptor{
name: name,
@ -334,7 +332,6 @@ func NewDescriptor(
description: description,
unit: unit,
numberKind: numberKind,
alternate: alternate,
}
}
@ -373,16 +370,3 @@ func (d *Descriptor) Unit() unit.Unit {
func (d *Descriptor) NumberKind() core.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

@ -47,12 +47,11 @@ func TestMain(m *testing.M) {
}
type updateTest struct {
count int
absolute bool
count int
}
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()
@ -63,11 +62,9 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
all.Append(x)
test.CheckedUpdate(t, agg, x, descriptor)
if !ut.absolute {
y := profile.Random(-1)
all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor)
}
y := profile.Random(-1)
all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor)
}
ctx := context.Background()
@ -82,40 +79,34 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allSum).CoerceToFloat64(profile.NumberKind),
sum.CoerceToFloat64(profile.NumberKind),
0.0000001,
"Same sum - absolute")
"Same sum")
count, err := agg.Count()
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()
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()
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)
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) {
// Test with an odd an even number of measurements
for count := 999; count <= 1000; count++ {
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{
count: count,
absolute: absolute,
}
// Test integer and floating point
test.RunProfiles(t, ut.run)
})
ut := updateTest{
count: count,
}
// Test integer and floating point
test.RunProfiles(t, ut.run)
})
}
}
@ -128,7 +119,7 @@ type mergeTest struct {
func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !mt.absolute)
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := New()
agg2 := New()
@ -225,7 +216,7 @@ func TestArrayErrors(t *testing.T) {
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)
@ -253,86 +244,80 @@ func TestArrayErrors(t *testing.T) {
}
func TestArrayFloat64(t *testing.T) {
for _, absolute := range []bool{false, true} {
t.Run(fmt.Sprint("Absolute=", absolute), func(t *testing.T) {
descriptor := test.NewAggregatorTest(export.MeasureKind, core.Float64NumberKind, !absolute)
descriptor := test.NewAggregatorTest(export.MeasureKind, core.Float64NumberKind)
fpsf := func(sign int) []float64 {
// Check behavior of a bunch of odd floating
// points except for NaN, which is invalid.
return []float64{
0,
math.Inf(sign),
1 / math.Inf(sign),
1,
2,
1e100,
math.MaxFloat64,
math.SmallestNonzeroFloat64,
math.MaxFloat32,
math.SmallestNonzeroFloat32,
math.E,
math.Pi,
math.Phi,
math.Sqrt2,
math.SqrtE,
math.SqrtPi,
math.SqrtPhi,
math.Ln2,
math.Log2E,
math.Ln10,
math.Log10E,
}
}
fpsf := func(sign int) []float64 {
// Check behavior of a bunch of odd floating
// points except for NaN, which is invalid.
return []float64{
0,
math.Inf(sign),
1 / math.Inf(sign),
1,
2,
1e100,
math.MaxFloat64,
math.SmallestNonzeroFloat64,
math.MaxFloat32,
math.SmallestNonzeroFloat32,
math.E,
math.Pi,
math.Phi,
math.Sqrt2,
math.SqrtE,
math.SqrtPi,
math.SqrtPhi,
math.Ln2,
math.Log2E,
math.Ln10,
math.Log10E,
}
}
all := test.NewNumbers(core.Float64NumberKind)
all := test.NewNumbers(core.Float64NumberKind)
ctx := context.Background()
agg := New()
ctx := context.Background()
agg := New()
for _, f := range fpsf(1) {
all.Append(core.NewFloat64Number(f))
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
}
for _, f := range fpsf(1) {
all.Append(core.NewFloat64Number(f))
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
}
if !absolute {
for _, f := range fpsf(-1) {
all.Append(core.NewFloat64Number(f))
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
}
}
for _, f := range fpsf(-1) {
all.Append(core.NewFloat64Number(f))
test.CheckedUpdate(t, agg, core.NewFloat64Number(f), descriptor)
}
agg.Checkpoint(ctx, descriptor)
agg.Checkpoint(ctx, descriptor)
all.Sort()
all.Sort()
sum, err := agg.Sum()
require.Nil(t, err)
allSum := all.Sum()
require.InEpsilon(t, (&allSum).AsFloat64(), sum.AsFloat64(), 0.0000001, "Same sum")
sum, err := agg.Sum()
require.Nil(t, err)
allSum := all.Sum()
require.InEpsilon(t, (&allSum).AsFloat64(), sum.AsFloat64(), 0.0000001, "Same sum")
count, err := agg.Count()
require.Equal(t, all.Count(), count, "Same count")
require.Nil(t, err)
count, err := agg.Count()
require.Equal(t, all.Count(), count, "Same count")
require.Nil(t, err)
min, err := agg.Min()
require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min")
min, err := agg.Min()
require.Nil(t, err)
require.Equal(t, all.Min(), min, "Same min")
max, err := agg.Max()
require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max")
max, err := agg.Max()
require.Nil(t, err)
require.Equal(t, all.Max(), max, "Same max")
qx, err := agg.Quantile(0.5)
require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median")
qx, err := agg.Quantile(0.5)
require.Nil(t, err)
require.Equal(t, all.Median(), qx, "Same median")
po, err := agg.Points()
require.Nil(t, err)
require.Equal(t, all.Len(), len(po), "Points() must have same length of updates")
for i := 0; i < len(po); i++ {
require.Equal(t, all.Points()[i], po[i], "Wrong point at position %d", i)
}
})
po, err := agg.Points()
require.Nil(t, err)
require.Equal(t, all.Len(), len(po), "Points() must have same length of updates")
for i := 0; i < len(po); 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
type updateTest struct {
absolute bool
}
func (ut *updateTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !ut.absolute)
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(NewDefaultConfig(), descriptor)
all := test.NewNumbers(profile.NumberKind)
@ -43,11 +42,9 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
all.Append(x)
test.CheckedUpdate(t, agg, x, descriptor)
if !ut.absolute {
y := profile.Random(-1)
all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor)
}
y := profile.Random(-1)
all.Append(y)
test.CheckedUpdate(t, agg, y, descriptor)
}
agg.Checkpoint(ctx, descriptor)
@ -61,10 +58,10 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allSum).CoerceToFloat64(profile.NumberKind),
sum.CoerceToFloat64(profile.NumberKind),
1,
"Same sum - absolute")
"Same sum")
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)
max, err := agg.Max()
@ -72,7 +69,7 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
require.Equal(t,
all.Max(),
max,
"Same max - absolute")
"Same max")
median, err := agg.Quantile(0.5)
require.Nil(t, err)
@ -81,20 +78,12 @@ func (ut *updateTest) run(t *testing.T, profile test.Profile) {
(&allMedian).CoerceToFloat64(profile.NumberKind),
median.CoerceToFloat64(profile.NumberKind),
10,
"Same median - absolute")
"Same median")
}
func TestDDSketchUpdate(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{
absolute: absolute,
}
// Test integer and floating point
test.RunProfiles(t, ut.run)
})
}
ut := updateTest{}
test.RunProfiles(t, ut.run)
}
type mergeTest struct {
@ -103,7 +92,7 @@ type mergeTest struct {
func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !mt.absolute)
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg1 := 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),
aggSum.CoerceToFloat64(profile.NumberKind),
1,
"Same sum - absolute")
"Same sum")
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)
max, err := agg1.Max()
@ -158,7 +147,7 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
require.Equal(t,
all.Max(),
max,
"Same max - absolute")
"Same max")
median, err := agg1.Quantile(0.5)
require.Nil(t, err)
@ -167,7 +156,7 @@ func (mt *mergeTest) run(t *testing.T, profile test.Profile) {
(&allMedian).CoerceToFloat64(profile.NumberKind),
median.CoerceToFloat64(profile.NumberKind),
10,
"Same median - absolute")
"Same median")
}
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
func histogram(t *testing.T, profile test.Profile, policy policy) {
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])
@ -158,7 +158,7 @@ func TestHistogramMerge(t *testing.T) {
ctx := context.Background()
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])
agg2 := New(descriptor, boundaries[profile.NumberKind])
@ -210,7 +210,7 @@ func TestHistogramNotSet(t *testing.T) {
ctx := context.Background()
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.Checkpoint(ctx, descriptor)

View File

@ -55,7 +55,7 @@ func TestLastValueUpdate(t *testing.T) {
test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New()
record := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind, false)
record := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind)
var last core.Number
for i := 0; i < count; i++ {
@ -79,7 +79,7 @@ func TestLastValueMerge(t *testing.T) {
agg1 := New()
agg2 := New()
descriptor := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind, false)
descriptor := test.NewAggregatorTest(export.ObserverKind, profile.NumberKind)
first1 := profile.Random(+1)
first2 := profile.Random(+1)
@ -107,7 +107,7 @@ func TestLastValueMerge(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.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
func minMaxSumCount(t *testing.T, profile test.Profile, policy policy) {
ctx := context.Background()
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind, !policy.absolute)
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
agg := New(descriptor)
@ -166,7 +166,7 @@ func TestMinMaxSumCountMerge(t *testing.T) {
ctx := context.Background()
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)
agg2 := New(descriptor)
@ -224,7 +224,7 @@ func TestMaxSumCountNotSet(t *testing.T) {
ctx := context.Background()
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.Checkpoint(ctx, descriptor)

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// 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 (
"context"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package counter
package sum
import (
"context"
@ -49,13 +49,13 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func TestCounterMonotonic(t *testing.T) {
func TestCounterSum(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, false)
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind)
sum := core.Number(0)
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()
test.RunProfiles(t, func(t *testing.T, profile test.Profile) {
agg := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, false)
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)
descriptor := test.NewAggregatorTest(export.MeasureKind, profile.NumberKind)
sum := core.Number(0)
for i := 0; i < count; i++ {
x := profile.Random(+1)
y := profile.Random(-1)
sum.AddNumber(profile.NumberKind, x)
sum.AddNumber(profile.NumberKind, y)
test.CheckedUpdate(t, agg, x, descriptor)
test.CheckedUpdate(t, agg, y, descriptor)
r1 := profile.Random(+1)
r2 := profile.Random(-1)
test.CheckedUpdate(t, agg, r1, descriptor)
test.CheckedUpdate(t, agg, r2, descriptor)
sum.AddNumber(profile.NumberKind, r1)
sum.AddNumber(profile.NumberKind, r2)
}
agg.Checkpoint(ctx, descriptor)
@ -127,7 +106,7 @@ func TestCounterMerge(t *testing.T) {
agg1 := New()
agg2 := New()
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind, false)
descriptor := test.NewAggregatorTest(export.CounterKind, profile.NumberKind)
sum := core.Number(0)
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 {
desc := export.NewDescriptor("test.name", mkind, nil, "", "", nkind, alternate)
return desc
func NewAggregatorTest(mkind export.Kind, nkind core.NumberKind) *export.Descriptor {
return export.NewDescriptor("test.name", mkind, nil, "", "", nkind)
}
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 counter should have only the "C=D" and "C=" keys.
require.EqualValues(t, map[string]int64{
"counter.a/C=D": 30, // labels1 + labels2
"counter.a/C=": 40, // labels3
"counter.b/C=D": 30, // labels1 + labels2
"counter.b/C=": 40, // labels3
"sum.a/C=D": 30, // labels1 + labels2
"sum.a/C=": 40, // labels3
"sum.b/C=D": 30, // labels1 + labels2
"sum.b/C=": 40, // labels3
"lastvalue.a/G=H": 10, // labels1
"lastvalue.a/G=": 30, // labels3 = last value
"lastvalue.b/G=H": 10, // labels1
@ -93,8 +93,8 @@ func TestGroupingStateful(t *testing.T) {
checkpointSet.ForEach(records1.AddTo)
require.EqualValues(t, map[string]int64{
"counter.a/C=D": 10, // labels1
"counter.b/C=D": 10, // labels1
"sum.a/C=D": 10, // labels1
"sum.b/C=D": 10, // labels1
}, records1)
// Test that state was NOT reset
@ -133,7 +133,7 @@ func TestGroupingStateful(t *testing.T) {
checkpointSet.ForEach(records4.AddTo)
require.EqualValues(t, map[string]int64{
"counter.a/C=D": 30,
"counter.b/C=D": 30,
"sum.a/C=D": 30,
"sum.b/C=D": 30,
}, records4)
}

View File

@ -23,8 +23,8 @@ import (
"go.opentelemetry.io/otel/api/key"
export "go.opentelemetry.io/otel/sdk/export/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/sum"
)
type (
@ -43,14 +43,14 @@ type (
var (
// LastValueADesc and LastValueBDesc group by "G"
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(
"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 = 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(
"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 = &Encoder{}
@ -69,7 +69,7 @@ var (
)
// 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.
func NewAggregationSelector() export.AggregationSelector {
return &testAggregationSelector{}
@ -78,7 +78,7 @@ func NewAggregationSelector() export.AggregationSelector {
func (*testAggregationSelector) AggregatorFor(desc *export.Descriptor) export.Aggregator {
switch desc.MetricKind() {
case export.CounterKind:
return counter.New()
return sum.New()
case export.ObserverKind:
return lastvalue.New()
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.
func CounterAgg(desc *export.Descriptor, v int64) export.Aggregator {
ctx := context.Background()
cagg := counter.New()
cagg := sum.New()
_ = cagg.Update(ctx, core.NewInt64Number(v), desc)
cagg.Checkpoint(ctx, desc)
return cagg
@ -139,7 +139,7 @@ func (o Output) AddTo(rec export.Record) {
key := fmt.Sprint(rec.Descriptor().Name(), "/", labels.Encoded())
var value int64
switch t := rec.Aggregator().(type) {
case *counter.Aggregator:
case *sum.Aggregator:
sum, _ := t.Sum()
value = sum.AsInt64()
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 counter should have only the "C=D" and "C=" keys.
require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 60, // labels1
"counter.a/C~D&E~F": 20, // labels2
"counter.a/": 40, // labels3
"counter.b/G~H&C~D": 60, // labels1
"counter.b/C~D&E~F": 20, // labels2
"counter.b/": 40, // labels3
"sum.a/G~H&C~D": 60, // labels1
"sum.a/C~D&E~F": 20, // labels2
"sum.a/": 40, // labels3
"sum.b/G~H&C~D": 60, // labels1
"sum.b/C~D&E~F": 20, // labels2
"sum.b/": 40, // labels3
"lastvalue.a/G~H&C~D": 50, // labels1
"lastvalue.a/C~D&E~F": 20, // labels2
"lastvalue.a/": 30, // labels3
@ -108,8 +108,8 @@ func TestUngroupedStateful(t *testing.T) {
checkpointSet.ForEach(records1.AddTo)
require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 10, // labels1
"counter.b/G~H&C~D": 10, // labels1
"sum.a/G~H&C~D": 10, // labels1
"sum.b/G~H&C~D": 10, // labels1
}, records1)
// Test that state was NOT reset
@ -148,7 +148,7 @@ func TestUngroupedStateful(t *testing.T) {
checkpointSet.ForEach(records4.AddTo)
require.EqualValues(t, map[string]int64{
"counter.a/G~H&C~D": 30,
"counter.b/G~H&C~D": 30,
"sum.a/G~H&C~D": 30,
"sum.b/G~H&C~D": 30,
}, records4)
}

View File

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

View File

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

View File

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

View File

@ -30,7 +30,7 @@ import (
)
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)})
go func() {

View File

@ -461,18 +461,18 @@ func (m *SDK) labsFor(ls api.LabelSet) *labels {
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(
name,
metricKind,
opts.Keys,
opts.Description,
opts.Unit,
numberKind,
opts.Alternate)
config.Keys,
config.Description,
config.Unit,
numberKind)
}
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)
return &instrument{
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 {
opts := api.Options{}
api.ApplyCounterOptions(&opts, cos...)
return m.newInstrument(name, export.CounterKind, numberKind, &opts)
func (m *SDK) newCounterInstrument(name string, numberKind core.NumberKind, opts []api.Option) *instrument {
return m.newInstrument(name, export.CounterKind, numberKind, opts)
}
func (m *SDK) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...api.MeasureOptionApplier) *instrument {
opts := api.Options{}
api.ApplyMeasureOptions(&opts, mos...)
return m.newInstrument(name, export.MeasureKind, numberKind, &opts)
func (m *SDK) newMeasureInstrument(name string, numberKind core.NumberKind, opts []api.Option) *instrument {
return m.newInstrument(name, export.MeasureKind, numberKind, opts)
}
func (m *SDK) NewInt64Counter(name string, cos ...api.CounterOptionApplier) (api.Int64Counter, error) {
return api.WrapInt64CounterInstrument(m.newCounterInstrument(name, core.Int64NumberKind, cos...), nil)
func (m *SDK) NewInt64Counter(name string, opts ...api.Option) (api.Int64Counter, error) {
return api.WrapInt64CounterInstrument(m.newCounterInstrument(name, core.Int64NumberKind, opts), nil)
}
func (m *SDK) NewFloat64Counter(name string, cos ...api.CounterOptionApplier) (api.Float64Counter, error) {
return api.WrapFloat64CounterInstrument(m.newCounterInstrument(name, core.Float64NumberKind, cos...), nil)
func (m *SDK) NewFloat64Counter(name string, opts ...api.Option) (api.Float64Counter, error) {
return api.WrapFloat64CounterInstrument(m.newCounterInstrument(name, core.Float64NumberKind, opts), nil)
}
func (m *SDK) NewInt64Measure(name string, mos ...api.MeasureOptionApplier) (api.Int64Measure, error) {
return api.WrapInt64MeasureInstrument(m.newMeasureInstrument(name, core.Int64NumberKind, mos...), nil)
func (m *SDK) NewInt64Measure(name string, opts ...api.Option) (api.Int64Measure, error) {
return api.WrapInt64MeasureInstrument(m.newMeasureInstrument(name, core.Int64NumberKind, opts), nil)
}
func (m *SDK) NewFloat64Measure(name string, mos ...api.MeasureOptionApplier) (api.Float64Measure, error) {
return api.WrapFloat64MeasureInstrument(m.newMeasureInstrument(name, core.Float64NumberKind, mos...), nil)
func (m *SDK) NewFloat64Measure(name string, opts ...api.Option) (api.Float64Measure, error) {
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 {
return api.NoopMeter{}.RegisterInt64Observer("", nil)
}
opts := api.Options{}
api.ApplyObserverOptions(&opts, oos...)
descriptor := newDescriptor(name, export.ObserverKind, core.Int64NumberKind, &opts)
descriptor := newDescriptor(name, export.ObserverKind, core.Int64NumberKind, opts)
cb := wrapInt64ObserverCallback(callback)
obs := m.newObserver(descriptor, cb)
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 {
return api.NoopMeter{}.RegisterFloat64Observer("", nil)
}
opts := api.Options{}
api.ApplyObserverOptions(&opts, oos...)
descriptor := newDescriptor(name, export.ObserverKind, core.Float64NumberKind, &opts)
descriptor := newDescriptor(name, export.ObserverKind, core.Float64NumberKind, opts)
cb := wrapFloat64ObserverCallback(callback)
obs := m.newObserver(descriptor, cb)
return float64Observer{

View File

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

View File

@ -22,35 +22,35 @@ import (
"go.opentelemetry.io/otel/api/core"
export "go.opentelemetry.io/otel/sdk/export/metric"
"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/minmaxsumcount"
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
)
var (
testCounterDesc = export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind, false)
testMeasureDesc = export.NewDescriptor("measure", export.MeasureKind, nil, "", "", core.Int64NumberKind, false)
testObserverDesc = export.NewDescriptor("observer", export.ObserverKind, nil, "", "", core.Int64NumberKind, false)
testCounterDesc = export.NewDescriptor("counter", export.CounterKind, nil, "", "", core.Int64NumberKind)
testMeasureDesc = export.NewDescriptor("measure", export.MeasureKind, nil, "", "", core.Int64NumberKind)
testObserverDesc = export.NewDescriptor("observer", export.ObserverKind, nil, "", "", core.Int64NumberKind)
)
func TestInexpensiveMeasure(t *testing.T) {
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(testObserverDesc).(*minmaxsumcount.Aggregator) })
}
func TestSketchMeasure(t *testing.T) {
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(testObserverDesc).(*ddsketch.Aggregator) })
}
func TestExactMeasure(t *testing.T) {
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(testObserverDesc).(*array.Aggregator) })
}

View File

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