diff --git a/api/metric/api_test.go b/api/metric/api_test.go index 6de55447b..f8158a4a4 100644 --- a/api/metric/api_test.go +++ b/api/metric/api_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metric +package metric_test import ( "context" @@ -21,7 +21,9 @@ import ( "go.opentelemetry.io/api/core" "go.opentelemetry.io/api/key" + "go.opentelemetry.io/api/metric" "go.opentelemetry.io/api/unit" + mock "go.opentelemetry.io/internal/metric" "github.com/google/go-cmp/cmp" ) @@ -29,7 +31,7 @@ import ( func TestCounterOptions(t *testing.T) { type testcase struct { name string - opts []CounterOptionApplier + opts []metric.CounterOptionApplier keys []core.Key desc string unit unit.Unit @@ -46,10 +48,10 @@ func TestCounterOptions(t *testing.T) { }, { name: "keys keys keys", - opts: []CounterOptionApplier{ - WithKeys(key.New("foo"), key.New("foo2")), - WithKeys(key.New("bar"), key.New("bar2")), - WithKeys(key.New("baz"), key.New("baz2")), + opts: []metric.CounterOptionApplier{ + 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"), @@ -62,8 +64,8 @@ func TestCounterOptions(t *testing.T) { }, { name: "description", - opts: []CounterOptionApplier{ - WithDescription("stuff"), + opts: []metric.CounterOptionApplier{ + metric.WithDescription("stuff"), }, keys: nil, desc: "stuff", @@ -72,9 +74,9 @@ func TestCounterOptions(t *testing.T) { }, { name: "description override", - opts: []CounterOptionApplier{ - WithDescription("stuff"), - WithDescription("things"), + opts: []metric.CounterOptionApplier{ + metric.WithDescription("stuff"), + metric.WithDescription("things"), }, keys: nil, desc: "things", @@ -83,8 +85,8 @@ func TestCounterOptions(t *testing.T) { }, { name: "unit", - opts: []CounterOptionApplier{ - WithUnit("s"), + opts: []metric.CounterOptionApplier{ + metric.WithUnit("s"), }, keys: nil, desc: "", @@ -93,9 +95,9 @@ func TestCounterOptions(t *testing.T) { }, { name: "unit override", - opts: []CounterOptionApplier{ - WithUnit("s"), - WithUnit("h"), + opts: []metric.CounterOptionApplier{ + metric.WithUnit("s"), + metric.WithUnit("h"), }, keys: nil, desc: "", @@ -104,8 +106,8 @@ func TestCounterOptions(t *testing.T) { }, { name: "nonmonotonic", - opts: []CounterOptionApplier{ - WithMonotonic(false), + opts: []metric.CounterOptionApplier{ + metric.WithMonotonic(false), }, keys: nil, desc: "", @@ -114,9 +116,9 @@ func TestCounterOptions(t *testing.T) { }, { name: "nonmonotonic, but not really", - opts: []CounterOptionApplier{ - WithMonotonic(false), - WithMonotonic(true), + opts: []metric.CounterOptionApplier{ + metric.WithMonotonic(false), + metric.WithMonotonic(true), }, keys: nil, desc: "", @@ -126,9 +128,9 @@ func TestCounterOptions(t *testing.T) { } for idx, tt := range testcases { t.Logf("Testing counter case %s (%d)", tt.name, idx) - opts := &Options{} - ApplyCounterOptions(opts, tt.opts...) - checkOptions(t, opts, &Options{ + opts := &metric.Options{} + metric.ApplyCounterOptions(opts, tt.opts...) + checkOptions(t, opts, &metric.Options{ Description: tt.desc, Unit: tt.unit, Keys: tt.keys, @@ -140,7 +142,7 @@ func TestCounterOptions(t *testing.T) { func TestGaugeOptions(t *testing.T) { type testcase struct { name string - opts []GaugeOptionApplier + opts []metric.GaugeOptionApplier keys []core.Key desc string unit unit.Unit @@ -157,10 +159,10 @@ func TestGaugeOptions(t *testing.T) { }, { name: "keys keys keys", - opts: []GaugeOptionApplier{ - WithKeys(key.New("foo"), key.New("foo2")), - WithKeys(key.New("bar"), key.New("bar2")), - WithKeys(key.New("baz"), key.New("baz2")), + opts: []metric.GaugeOptionApplier{ + 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"), @@ -173,8 +175,8 @@ func TestGaugeOptions(t *testing.T) { }, { name: "description", - opts: []GaugeOptionApplier{ - WithDescription("stuff"), + opts: []metric.GaugeOptionApplier{ + metric.WithDescription("stuff"), }, keys: nil, desc: "stuff", @@ -183,9 +185,9 @@ func TestGaugeOptions(t *testing.T) { }, { name: "description override", - opts: []GaugeOptionApplier{ - WithDescription("stuff"), - WithDescription("things"), + opts: []metric.GaugeOptionApplier{ + metric.WithDescription("stuff"), + metric.WithDescription("things"), }, keys: nil, desc: "things", @@ -194,8 +196,8 @@ func TestGaugeOptions(t *testing.T) { }, { name: "unit", - opts: []GaugeOptionApplier{ - WithUnit("s"), + opts: []metric.GaugeOptionApplier{ + metric.WithUnit("s"), }, keys: nil, desc: "", @@ -204,9 +206,9 @@ func TestGaugeOptions(t *testing.T) { }, { name: "unit override", - opts: []GaugeOptionApplier{ - WithUnit("s"), - WithUnit("h"), + opts: []metric.GaugeOptionApplier{ + metric.WithUnit("s"), + metric.WithUnit("h"), }, keys: nil, desc: "", @@ -215,8 +217,8 @@ func TestGaugeOptions(t *testing.T) { }, { name: "monotonic", - opts: []GaugeOptionApplier{ - WithMonotonic(true), + opts: []metric.GaugeOptionApplier{ + metric.WithMonotonic(true), }, keys: nil, desc: "", @@ -225,9 +227,9 @@ func TestGaugeOptions(t *testing.T) { }, { name: "monotonic, but not really", - opts: []GaugeOptionApplier{ - WithMonotonic(true), - WithMonotonic(false), + opts: []metric.GaugeOptionApplier{ + metric.WithMonotonic(true), + metric.WithMonotonic(false), }, keys: nil, desc: "", @@ -237,9 +239,9 @@ func TestGaugeOptions(t *testing.T) { } for idx, tt := range testcases { t.Logf("Testing gauge case %s (%d)", tt.name, idx) - opts := &Options{} - ApplyGaugeOptions(opts, tt.opts...) - checkOptions(t, opts, &Options{ + opts := &metric.Options{} + metric.ApplyGaugeOptions(opts, tt.opts...) + checkOptions(t, opts, &metric.Options{ Description: tt.desc, Unit: tt.unit, Keys: tt.keys, @@ -251,7 +253,7 @@ func TestGaugeOptions(t *testing.T) { func TestMeasureOptions(t *testing.T) { type testcase struct { name string - opts []MeasureOptionApplier + opts []metric.MeasureOptionApplier keys []core.Key desc string unit unit.Unit @@ -268,10 +270,10 @@ func TestMeasureOptions(t *testing.T) { }, { name: "keys keys keys", - opts: []MeasureOptionApplier{ - WithKeys(key.New("foo"), key.New("foo2")), - WithKeys(key.New("bar"), key.New("bar2")), - WithKeys(key.New("baz"), key.New("baz2")), + 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"), @@ -284,8 +286,8 @@ func TestMeasureOptions(t *testing.T) { }, { name: "description", - opts: []MeasureOptionApplier{ - WithDescription("stuff"), + opts: []metric.MeasureOptionApplier{ + metric.WithDescription("stuff"), }, keys: nil, desc: "stuff", @@ -294,9 +296,9 @@ func TestMeasureOptions(t *testing.T) { }, { name: "description override", - opts: []MeasureOptionApplier{ - WithDescription("stuff"), - WithDescription("things"), + opts: []metric.MeasureOptionApplier{ + metric.WithDescription("stuff"), + metric.WithDescription("things"), }, keys: nil, desc: "things", @@ -305,8 +307,8 @@ func TestMeasureOptions(t *testing.T) { }, { name: "unit", - opts: []MeasureOptionApplier{ - WithUnit("s"), + opts: []metric.MeasureOptionApplier{ + metric.WithUnit("s"), }, keys: nil, desc: "", @@ -315,9 +317,9 @@ func TestMeasureOptions(t *testing.T) { }, { name: "unit override", - opts: []MeasureOptionApplier{ - WithUnit("s"), - WithUnit("h"), + opts: []metric.MeasureOptionApplier{ + metric.WithUnit("s"), + metric.WithUnit("h"), }, keys: nil, desc: "", @@ -326,8 +328,8 @@ func TestMeasureOptions(t *testing.T) { }, { name: "not absolute", - opts: []MeasureOptionApplier{ - WithAbsolute(false), + opts: []metric.MeasureOptionApplier{ + metric.WithAbsolute(false), }, keys: nil, desc: "", @@ -336,9 +338,9 @@ func TestMeasureOptions(t *testing.T) { }, { name: "not absolute, but not really", - opts: []MeasureOptionApplier{ - WithAbsolute(false), - WithAbsolute(true), + opts: []metric.MeasureOptionApplier{ + metric.WithAbsolute(false), + metric.WithAbsolute(true), }, keys: nil, desc: "", @@ -348,9 +350,9 @@ func TestMeasureOptions(t *testing.T) { } for idx, tt := range testcases { t.Logf("Testing measure case %s (%d)", tt.name, idx) - opts := &Options{} - ApplyMeasureOptions(opts, tt.opts...) - checkOptions(t, opts, &Options{ + opts := &metric.Options{} + metric.ApplyMeasureOptions(opts, tt.opts...) + checkOptions(t, opts, &metric.Options{ Description: tt.desc, Unit: tt.unit, Keys: tt.keys, @@ -359,7 +361,7 @@ func TestMeasureOptions(t *testing.T) { } } -func checkOptions(t *testing.T, got *Options, expected *Options) { +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) } @@ -367,7 +369,7 @@ func checkOptions(t *testing.T, got *Options, expected *Options) { func TestCounter(t *testing.T) { { - meter := newMockMeter() + meter := mock.NewMeter() c := meter.NewFloat64Counter("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -376,10 +378,10 @@ func TestCounter(t *testing.T) { handle.Add(ctx, 42) meter.RecordBatch(ctx, labels, c.Measurement(42)) t.Log("Testing float counter") - checkBatches(t, ctx, labels, meter, core.Float64NumberKind, c.instrument) + checkBatches(t, ctx, labels, meter, core.Float64NumberKind, c.Impl()) } { - meter := newMockMeter() + meter := mock.NewMeter() c := meter.NewInt64Counter("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -388,13 +390,13 @@ func TestCounter(t *testing.T) { handle.Add(ctx, 42) meter.RecordBatch(ctx, labels, c.Measurement(42)) t.Log("Testing int counter") - checkBatches(t, ctx, labels, meter, core.Int64NumberKind, c.instrument) + checkBatches(t, ctx, labels, meter, core.Int64NumberKind, c.Impl()) } } func TestGauge(t *testing.T) { { - meter := newMockMeter() + meter := mock.NewMeter() g := meter.NewFloat64Gauge("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -403,10 +405,10 @@ func TestGauge(t *testing.T) { handle.Set(ctx, 42) meter.RecordBatch(ctx, labels, g.Measurement(42)) t.Log("Testing float gauge") - checkBatches(t, ctx, labels, meter, core.Float64NumberKind, g.instrument) + checkBatches(t, ctx, labels, meter, core.Float64NumberKind, g.Impl()) } { - meter := newMockMeter() + meter := mock.NewMeter() g := meter.NewInt64Gauge("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -415,13 +417,13 @@ func TestGauge(t *testing.T) { handle.Set(ctx, 42) meter.RecordBatch(ctx, labels, g.Measurement(42)) t.Log("Testing int gauge") - checkBatches(t, ctx, labels, meter, core.Int64NumberKind, g.instrument) + checkBatches(t, ctx, labels, meter, core.Int64NumberKind, g.Impl()) } } func TestMeasure(t *testing.T) { { - meter := newMockMeter() + meter := mock.NewMeter() m := meter.NewFloat64Measure("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -430,10 +432,10 @@ func TestMeasure(t *testing.T) { handle.Record(ctx, 42) meter.RecordBatch(ctx, labels, m.Measurement(42)) t.Log("Testing float measure") - checkBatches(t, ctx, labels, meter, core.Float64NumberKind, m.instrument) + checkBatches(t, ctx, labels, meter, core.Float64NumberKind, m.Impl()) } { - meter := newMockMeter() + meter := mock.NewMeter() m := meter.NewInt64Measure("ajwaj") ctx := context.Background() labels := meter.Labels() @@ -442,53 +444,53 @@ func TestMeasure(t *testing.T) { handle.Record(ctx, 42) meter.RecordBatch(ctx, labels, m.Measurement(42)) t.Log("Testing int measure") - checkBatches(t, ctx, labels, meter, core.Int64NumberKind, m.instrument) + checkBatches(t, ctx, labels, meter, core.Int64NumberKind, m.Impl()) } } -func checkBatches(t *testing.T, ctx context.Context, labels LabelSet, meter *mockMeter, kind core.NumberKind, instrument InstrumentImpl) { +func checkBatches(t *testing.T, ctx context.Context, labels metric.LabelSet, meter *mock.Meter, kind core.NumberKind, instrument metric.InstrumentImpl) { t.Helper() - if len(meter.measurementBatches) != 3 { - t.Errorf("Expected 3 recorded measurement batches, got %d", len(meter.measurementBatches)) + if len(meter.MeasurementBatches) != 3 { + t.Errorf("Expected 3 recorded measurement batches, got %d", len(meter.MeasurementBatches)) } - ourInstrument := instrument.(*mockInstrument) - ourLabelSet := labels.(*mockLabelSet) + ourInstrument := instrument.(*mock.Instrument) + ourLabelSet := labels.(*mock.LabelSet) minLen := 3 - if minLen > len(meter.measurementBatches) { - minLen = len(meter.measurementBatches) + if minLen > len(meter.MeasurementBatches) { + minLen = len(meter.MeasurementBatches) } for i := 0; i < minLen; i++ { - got := meter.measurementBatches[i] - if got.ctx != ctx { + got := meter.MeasurementBatches[i] + if got.Ctx != ctx { d := func(c context.Context) string { return fmt.Sprintf("(ptr: %p, ctx %#v)", c, c) } - t.Errorf("Wrong recorded context in batch %d, expected %s, got %s", i, d(ctx), d(got.ctx)) + t.Errorf("Wrong recorded context in batch %d, expected %s, got %s", i, d(ctx), d(got.Ctx)) } - if got.labelSet != ourLabelSet { - d := func(l *mockLabelSet) string { - return fmt.Sprintf("(ptr: %p, labels %#v)", l, l.labels) + if got.LabelSet != ourLabelSet { + d := func(l *mock.LabelSet) string { + return fmt.Sprintf("(ptr: %p, labels %#v)", l, l.Labels) } - t.Errorf("Wrong recorded label set in batch %d, expected %s, got %s", i, d(ourLabelSet), d(got.labelSet)) + t.Errorf("Wrong recorded label set in batch %d, expected %s, got %s", i, d(ourLabelSet), d(got.LabelSet)) } - if len(got.measurements) != 1 { - t.Errorf("Expected 1 measurement in batch %d, got %d", i, len(got.measurements)) + if len(got.Measurements) != 1 { + t.Errorf("Expected 1 measurement in batch %d, got %d", i, len(got.Measurements)) } minMLen := 1 - if minMLen > len(got.measurements) { - minMLen = len(got.measurements) + if minMLen > len(got.Measurements) { + minMLen = len(got.Measurements) } for j := 0; j < minMLen; j++ { - measurement := got.measurements[j] - if measurement.instrument != ourInstrument { - d := func(i *mockInstrument) string { + measurement := got.Measurements[j] + if measurement.Instrument != ourInstrument { + d := func(i *mock.Instrument) string { return fmt.Sprintf("(ptr: %p, instrument %#v)", i, i) } - t.Errorf("Wrong recorded instrument in measurement %d in batch %d, expected %s, got %s", j, i, d(ourInstrument), d(measurement.instrument)) + t.Errorf("Wrong recorded instrument in measurement %d in batch %d, expected %s, got %s", j, i, d(ourInstrument), d(measurement.Instrument)) } ft := fortyTwo(t, kind) - if measurement.number.CompareNumber(kind, ft) != 0 { - t.Errorf("Wrong recorded value in measurement %d in batch %d, expected %s, got %s", j, i, ft.Emit(kind), measurement.number.Emit(kind)) + if measurement.Number.CompareNumber(kind, ft) != 0 { + t.Errorf("Wrong recorded value in measurement %d in batch %d, expected %s, got %s", j, i, ft.Emit(kind), measurement.Number.Emit(kind)) } } } diff --git a/api/metric/global.go b/api/metric/global.go index 5c0d402a0..f0e6dbd6f 100644 --- a/api/metric/global.go +++ b/api/metric/global.go @@ -26,7 +26,7 @@ func GlobalMeter() Meter { if t := global.Load(); t != nil { return t.(Meter) } - return noopMeter{} + return NoopMeter{} } // SetGlobalMeter sets provided meter as a global meter. diff --git a/api/metric/global_test.go b/api/metric/global_test.go index a41ec22d4..4dce238aa 100644 --- a/api/metric/global_test.go +++ b/api/metric/global_test.go @@ -12,22 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -package metric +package metric_test import ( "testing" + + "go.opentelemetry.io/api/metric" + mock "go.opentelemetry.io/internal/metric" ) func TestGlobalMeter(t *testing.T) { - m := GlobalMeter() - if _, ok := m.(noopMeter); !ok { - t.Errorf("Expected global meter to be a noopMeter instance, got an instance of %T", m) + m := metric.GlobalMeter() + if _, ok := m.(metric.NoopMeter); !ok { + t.Errorf("Expected global meter to be a NoopMeter instance, got an instance of %T", m) } - SetGlobalMeter(newMockMeter()) + metric.SetGlobalMeter(mock.NewMeter()) - m = GlobalMeter() - if _, ok := m.(*mockMeter); !ok { - t.Errorf("Expected global meter to be a *mockMetric.MockMeter instance, got an instance of %T", m) + m = metric.GlobalMeter() + if _, ok := m.(*mock.Meter); !ok { + t.Errorf("Expected global meter to be a *mock.Meter instance, got an instance of %T", m) } } diff --git a/api/metric/mock_test.go b/api/metric/mock_test.go deleted file mode 100644 index 161b45ba3..000000000 --- a/api/metric/mock_test.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2019, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metric - -import ( - "context" - - "go.opentelemetry.io/api/core" -) - -type ( - mockHandle struct { - instrument *mockInstrument - labelSet *mockLabelSet - } - - mockInstrument struct { - name string - kind mockKind - numberKind core.NumberKind - opts Options - } - - mockLabelSet struct { - meter *mockMeter - labels map[core.Key]core.Value - } - - batch struct { - ctx context.Context - labelSet *mockLabelSet - measurements []mockMeasurement - } - - mockMeter struct { - measurementBatches []batch - } - - mockKind int8 - - mockMeasurement struct { - instrument *mockInstrument - number core.Number - } -) - -var ( - _ InstrumentImpl = &mockInstrument{} - _ HandleImpl = &mockHandle{} - _ LabelSet = &mockLabelSet{} - _ Meter = &mockMeter{} -) - -const ( - mockKindCounter mockKind = iota - mockKindGauge - mockKindMeasure -) - -func (i *mockInstrument) AcquireHandle(labels LabelSet) HandleImpl { - return &mockHandle{ - instrument: i, - labelSet: labels.(*mockLabelSet), - } -} - -func (i *mockInstrument) RecordOne(ctx context.Context, number core.Number, labels LabelSet) { - doRecordBatch(labels.(*mockLabelSet), ctx, i, number) -} - -func (h *mockHandle) RecordOne(ctx context.Context, number core.Number) { - doRecordBatch(h.labelSet, ctx, h.instrument, number) -} - -func (h *mockHandle) Release() { -} - -func doRecordBatch(labelSet *mockLabelSet, ctx context.Context, instrument *mockInstrument, number core.Number) { - labelSet.meter.recordMockBatch(ctx, labelSet, mockMeasurement{ - instrument: instrument, - number: number, - }) -} - -func (s *mockLabelSet) Meter() Meter { - return s.meter -} - -func newMockMeter() *mockMeter { - return &mockMeter{} -} - -func (m *mockMeter) Labels(labels ...core.KeyValue) LabelSet { - ul := make(map[core.Key]core.Value) - for _, kv := range labels { - ul[kv.Key] = kv.Value - } - return &mockLabelSet{ - meter: m, - labels: ul, - } -} - -func (m *mockMeter) NewInt64Counter(name string, cos ...CounterOptionApplier) Int64Counter { - instrument := m.newCounterInstrument(name, core.Int64NumberKind, cos...) - return WrapInt64CounterInstrument(instrument) -} - -func (m *mockMeter) NewFloat64Counter(name string, cos ...CounterOptionApplier) Float64Counter { - instrument := m.newCounterInstrument(name, core.Float64NumberKind, cos...) - return WrapFloat64CounterInstrument(instrument) -} - -func (m *mockMeter) newCounterInstrument(name string, numberKind core.NumberKind, cos ...CounterOptionApplier) *mockInstrument { - opts := Options{} - ApplyCounterOptions(&opts, cos...) - return &mockInstrument{ - name: name, - kind: mockKindCounter, - numberKind: numberKind, - opts: opts, - } -} - -func (m *mockMeter) NewInt64Gauge(name string, gos ...GaugeOptionApplier) Int64Gauge { - instrument := m.newGaugeInstrument(name, core.Int64NumberKind, gos...) - return WrapInt64GaugeInstrument(instrument) -} - -func (m *mockMeter) NewFloat64Gauge(name string, gos ...GaugeOptionApplier) Float64Gauge { - instrument := m.newGaugeInstrument(name, core.Float64NumberKind, gos...) - return WrapFloat64GaugeInstrument(instrument) -} - -func (m *mockMeter) newGaugeInstrument(name string, numberKind core.NumberKind, gos ...GaugeOptionApplier) *mockInstrument { - opts := Options{} - ApplyGaugeOptions(&opts, gos...) - return &mockInstrument{ - name: name, - kind: mockKindGauge, - numberKind: numberKind, - opts: opts, - } -} - -func (m *mockMeter) NewInt64Measure(name string, mos ...MeasureOptionApplier) Int64Measure { - instrument := m.newMeasureInstrument(name, core.Int64NumberKind, mos...) - return WrapInt64MeasureInstrument(instrument) -} - -func (m *mockMeter) NewFloat64Measure(name string, mos ...MeasureOptionApplier) Float64Measure { - instrument := m.newMeasureInstrument(name, core.Float64NumberKind, mos...) - return WrapFloat64MeasureInstrument(instrument) -} - -func (m *mockMeter) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...MeasureOptionApplier) *mockInstrument { - opts := Options{} - ApplyMeasureOptions(&opts, mos...) - return &mockInstrument{ - name: name, - kind: mockKindMeasure, - numberKind: numberKind, - opts: opts, - } -} - -func (m *mockMeter) RecordBatch(ctx context.Context, labels LabelSet, measurements ...Measurement) { - ourLabelSet := labels.(*mockLabelSet) - mm := make([]mockMeasurement, len(measurements)) - for i := 0; i < len(measurements); i++ { - m := measurements[i] - mm[i] = mockMeasurement{ - instrument: m.InstrumentImpl().(*mockInstrument), - number: m.Number(), - } - } - m.recordMockBatch(ctx, ourLabelSet, mm...) -} - -func (m *mockMeter) recordMockBatch(ctx context.Context, labelSet *mockLabelSet, measurements ...mockMeasurement) { - m.measurementBatches = append(m.measurementBatches, batch{ - ctx: ctx, - labelSet: labelSet, - measurements: measurements, - }) -} diff --git a/api/metric/noop.go b/api/metric/noop.go index f68cc8c91..3e2bff4b8 100644 --- a/api/metric/noop.go +++ b/api/metric/noop.go @@ -6,12 +6,12 @@ import ( "go.opentelemetry.io/api/core" ) -type noopMeter struct{} +type NoopMeter struct{} type noopHandle struct{} type noopLabelSet struct{} type noopInstrument struct{} -var _ Meter = noopMeter{} +var _ Meter = NoopMeter{} var _ InstrumentImpl = noopInstrument{} var _ HandleImpl = noopHandle{} var _ LabelSet = noopLabelSet{} @@ -30,36 +30,36 @@ func (noopInstrument) RecordOne(context.Context, core.Number, LabelSet) { } func (noopInstrument) Meter() Meter { - return noopMeter{} + return NoopMeter{} } -func (noopMeter) Labels(...core.KeyValue) LabelSet { +func (NoopMeter) Labels(...core.KeyValue) LabelSet { return noopLabelSet{} } -func (noopMeter) NewInt64Counter(name string, cos ...CounterOptionApplier) Int64Counter { +func (NoopMeter) NewInt64Counter(name string, cos ...CounterOptionApplier) Int64Counter { return WrapInt64CounterInstrument(noopInstrument{}) } -func (noopMeter) NewFloat64Counter(name string, cos ...CounterOptionApplier) Float64Counter { +func (NoopMeter) NewFloat64Counter(name string, cos ...CounterOptionApplier) Float64Counter { return WrapFloat64CounterInstrument(noopInstrument{}) } -func (noopMeter) NewInt64Gauge(name string, gos ...GaugeOptionApplier) Int64Gauge { +func (NoopMeter) NewInt64Gauge(name string, gos ...GaugeOptionApplier) Int64Gauge { return WrapInt64GaugeInstrument(noopInstrument{}) } -func (noopMeter) NewFloat64Gauge(name string, gos ...GaugeOptionApplier) Float64Gauge { +func (NoopMeter) NewFloat64Gauge(name string, gos ...GaugeOptionApplier) Float64Gauge { return WrapFloat64GaugeInstrument(noopInstrument{}) } -func (noopMeter) NewInt64Measure(name string, mos ...MeasureOptionApplier) Int64Measure { +func (NoopMeter) NewInt64Measure(name string, mos ...MeasureOptionApplier) Int64Measure { return WrapInt64MeasureInstrument(noopInstrument{}) } -func (noopMeter) NewFloat64Measure(name string, mos ...MeasureOptionApplier) Float64Measure { +func (NoopMeter) NewFloat64Measure(name string, mos ...MeasureOptionApplier) Float64Measure { return WrapFloat64MeasureInstrument(noopInstrument{}) } -func (noopMeter) RecordBatch(context.Context, LabelSet, ...Measurement) { +func (NoopMeter) RecordBatch(context.Context, LabelSet, ...Measurement) { } diff --git a/internal/metric/mock.go b/internal/metric/mock.go new file mode 100644 index 000000000..da05d15c0 --- /dev/null +++ b/internal/metric/mock.go @@ -0,0 +1,199 @@ +// Copyright 2019, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metric + +import ( + "context" + + "go.opentelemetry.io/api/core" + apimetric "go.opentelemetry.io/api/metric" +) + +type ( + Handle struct { + Instrument *Instrument + LabelSet *LabelSet + } + + Instrument struct { + Name string + Kind Kind + NumberKind core.NumberKind + Opts apimetric.Options + } + + LabelSet struct { + TheMeter *Meter + Labels map[core.Key]core.Value + } + + Batch struct { + Ctx context.Context + LabelSet *LabelSet + Measurements []Measurement + } + + Meter struct { + MeasurementBatches []Batch + } + + Kind int8 + + Measurement struct { + Instrument *Instrument + Number core.Number + } +) + +var ( + _ apimetric.InstrumentImpl = &Instrument{} + _ apimetric.HandleImpl = &Handle{} + _ apimetric.LabelSet = &LabelSet{} + _ apimetric.Meter = &Meter{} +) + +const ( + KindCounter Kind = iota + KindGauge + KindMeasure +) + +func (i *Instrument) AcquireHandle(labels apimetric.LabelSet) apimetric.HandleImpl { + return &Handle{ + Instrument: i, + LabelSet: labels.(*LabelSet), + } +} + +func (i *Instrument) RecordOne(ctx context.Context, number core.Number, labels apimetric.LabelSet) { + doRecordBatch(ctx, labels.(*LabelSet), i, number) +} + +func (h *Handle) RecordOne(ctx context.Context, number core.Number) { + doRecordBatch(ctx, h.LabelSet, h.Instrument, number) +} + +func (h *Handle) Release() { +} + +func doRecordBatch(ctx context.Context, labelSet *LabelSet, instrument *Instrument, number core.Number) { + labelSet.TheMeter.recordMockBatch(ctx, labelSet, Measurement{ + Instrument: instrument, + Number: number, + }) +} + +func (s *LabelSet) Meter() apimetric.Meter { + return s.TheMeter +} + +func NewMeter() *Meter { + return &Meter{} +} + +func (m *Meter) Labels(labels ...core.KeyValue) apimetric.LabelSet { + ul := make(map[core.Key]core.Value) + for _, kv := range labels { + ul[kv.Key] = kv.Value + } + return &LabelSet{ + TheMeter: m, + Labels: ul, + } +} + +func (m *Meter) NewInt64Counter(name string, cos ...apimetric.CounterOptionApplier) apimetric.Int64Counter { + instrument := m.newCounterInstrument(name, core.Int64NumberKind, cos...) + return apimetric.WrapInt64CounterInstrument(instrument) +} + +func (m *Meter) NewFloat64Counter(name string, cos ...apimetric.CounterOptionApplier) apimetric.Float64Counter { + instrument := m.newCounterInstrument(name, core.Float64NumberKind, cos...) + return apimetric.WrapFloat64CounterInstrument(instrument) +} + +func (m *Meter) newCounterInstrument(name string, numberKind core.NumberKind, cos ...apimetric.CounterOptionApplier) *Instrument { + opts := apimetric.Options{} + apimetric.ApplyCounterOptions(&opts, cos...) + return &Instrument{ + Name: name, + Kind: KindCounter, + NumberKind: numberKind, + Opts: opts, + } +} + +func (m *Meter) NewInt64Gauge(name string, gos ...apimetric.GaugeOptionApplier) apimetric.Int64Gauge { + instrument := m.newGaugeInstrument(name, core.Int64NumberKind, gos...) + return apimetric.WrapInt64GaugeInstrument(instrument) +} + +func (m *Meter) NewFloat64Gauge(name string, gos ...apimetric.GaugeOptionApplier) apimetric.Float64Gauge { + instrument := m.newGaugeInstrument(name, core.Float64NumberKind, gos...) + return apimetric.WrapFloat64GaugeInstrument(instrument) +} + +func (m *Meter) newGaugeInstrument(name string, numberKind core.NumberKind, gos ...apimetric.GaugeOptionApplier) *Instrument { + opts := apimetric.Options{} + apimetric.ApplyGaugeOptions(&opts, gos...) + return &Instrument{ + Name: name, + Kind: KindGauge, + NumberKind: numberKind, + Opts: opts, + } +} + +func (m *Meter) NewInt64Measure(name string, mos ...apimetric.MeasureOptionApplier) apimetric.Int64Measure { + instrument := m.newMeasureInstrument(name, core.Int64NumberKind, mos...) + return apimetric.WrapInt64MeasureInstrument(instrument) +} + +func (m *Meter) NewFloat64Measure(name string, mos ...apimetric.MeasureOptionApplier) apimetric.Float64Measure { + instrument := m.newMeasureInstrument(name, core.Float64NumberKind, mos...) + return apimetric.WrapFloat64MeasureInstrument(instrument) +} + +func (m *Meter) newMeasureInstrument(name string, numberKind core.NumberKind, mos ...apimetric.MeasureOptionApplier) *Instrument { + opts := apimetric.Options{} + apimetric.ApplyMeasureOptions(&opts, mos...) + return &Instrument{ + Name: name, + Kind: KindMeasure, + NumberKind: numberKind, + Opts: opts, + } +} + +func (m *Meter) RecordBatch(ctx context.Context, labels apimetric.LabelSet, measurements ...apimetric.Measurement) { + ourLabelSet := labels.(*LabelSet) + mm := make([]Measurement, len(measurements)) + for i := 0; i < len(measurements); i++ { + m := measurements[i] + mm[i] = Measurement{ + Instrument: m.InstrumentImpl().(*Instrument), + Number: m.Number(), + } + } + m.recordMockBatch(ctx, ourLabelSet, mm...) +} + +func (m *Meter) recordMockBatch(ctx context.Context, labelSet *LabelSet, measurements ...Measurement) { + m.MeasurementBatches = append(m.MeasurementBatches, Batch{ + Ctx: ctx, + LabelSet: labelSet, + Measurements: measurements, + }) +}