mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-01-18 03:22:12 +02:00
Remove bound metric instruments from the API (new champion) (#2399)
* Remove bound metric instruments from the API * Removed dead code * Added changelog message * Added PR number Co-authored-by: Joshua MacDonald <jmacd@lightstep.com> Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
parent
b663c7c2bd
commit
034956199a
@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
### Removed
|
||||
|
||||
- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350)
|
||||
- Remove the metric Bound Instruments interface and implementations. (#2399)
|
||||
|
||||
## [1.2.0] - 2021-11-12
|
||||
|
||||
|
@ -41,10 +41,6 @@ import (
|
||||
// in the MeterProvider and Meters ensure that each instrument has a delegate
|
||||
// before the global provider is set.
|
||||
//
|
||||
// Bound instrument operations are implemented by delegating to the
|
||||
// instrument after it is registered, with a sync.Once initializer to
|
||||
// protect against races with Release().
|
||||
//
|
||||
// Metric uniqueness checking is implemented by calling the exported
|
||||
// methods of the api/metric/registry package.
|
||||
|
||||
@ -108,19 +104,9 @@ type AsyncImpler interface {
|
||||
AsyncImpl() sdkapi.AsyncImpl
|
||||
}
|
||||
|
||||
type syncHandle struct {
|
||||
delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
|
||||
|
||||
inst *syncImpl
|
||||
labels []attribute.KeyValue
|
||||
|
||||
initialize sync.Once
|
||||
}
|
||||
|
||||
var _ metric.MeterProvider = &meterProvider{}
|
||||
var _ sdkapi.MeterImpl = &meterImpl{}
|
||||
var _ sdkapi.InstrumentImpl = &syncImpl{}
|
||||
var _ sdkapi.BoundSyncImpl = &syncHandle{}
|
||||
var _ sdkapi.AsyncImpl = &asyncImpl{}
|
||||
|
||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
|
||||
@ -241,28 +227,6 @@ func (inst *syncImpl) Implementation() interface{} {
|
||||
return inst
|
||||
}
|
||||
|
||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
|
||||
return (*implPtr).Bind(labels)
|
||||
}
|
||||
return &syncHandle{
|
||||
inst: inst,
|
||||
labels: labels,
|
||||
}
|
||||
}
|
||||
|
||||
func (bound *syncHandle) Unbind() {
|
||||
bound.initialize.Do(func() {})
|
||||
|
||||
implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
||||
|
||||
if implPtr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
(*implPtr).Unbind()
|
||||
}
|
||||
|
||||
// Async delegation
|
||||
|
||||
func (m *meterImpl) NewAsyncInstrument(
|
||||
@ -325,37 +289,11 @@ func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, label
|
||||
}
|
||||
}
|
||||
|
||||
// Bound instrument initialization
|
||||
|
||||
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
|
||||
instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
|
||||
if instPtr == nil {
|
||||
return
|
||||
}
|
||||
var implPtr *sdkapi.BoundSyncImpl
|
||||
bound.initialize.Do(func() {
|
||||
implPtr = new(sdkapi.BoundSyncImpl)
|
||||
*implPtr = (*instPtr).Bind(bound.labels)
|
||||
atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
|
||||
})
|
||||
if implPtr == nil {
|
||||
implPtr = (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
||||
}
|
||||
// This may still be nil if instrument was created and bound
|
||||
// without a delegate, then the instrument was set to have a
|
||||
// delegate and unbound.
|
||||
if implPtr == nil {
|
||||
return
|
||||
}
|
||||
(*implPtr).RecordOne(ctx, number)
|
||||
}
|
||||
|
||||
func AtomicFieldOffsets() map[string]uintptr {
|
||||
return map[string]uintptr{
|
||||
"meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate),
|
||||
"meterImpl.delegate": unsafe.Offsetof(meterImpl{}.delegate),
|
||||
"syncImpl.delegate": unsafe.Offsetof(syncImpl{}.delegate),
|
||||
"asyncImpl.delegate": unsafe.Offsetof(asyncImpl{}.delegate),
|
||||
"syncHandle.delegate": unsafe.Offsetof(syncHandle{}.delegate),
|
||||
}
|
||||
}
|
||||
|
@ -137,97 +137,6 @@ func TestDirect(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
func TestBound(t *testing.T) {
|
||||
global.ResetForTest()
|
||||
|
||||
// Note: this test uses opposite Float64/Int64 number kinds
|
||||
// vs. the above, to cover all the instruments.
|
||||
ctx := context.Background()
|
||||
glob := metricglobal.Meter(
|
||||
"test",
|
||||
metric.WithInstrumentationVersion("semver:test-1.0"),
|
||||
metric.WithSchemaURL("schema://url"),
|
||||
)
|
||||
labels1 := []attribute.KeyValue{attribute.String("A", "B")}
|
||||
|
||||
counter := Must(glob).NewFloat64Counter("test.counter")
|
||||
boundC := counter.Bind(labels1...)
|
||||
boundC.Add(ctx, 1)
|
||||
boundC.Add(ctx, 1)
|
||||
|
||||
histogram := Must(glob).NewInt64Histogram("test.histogram")
|
||||
boundM := histogram.Bind(labels1...)
|
||||
boundM.Record(ctx, 1)
|
||||
boundM.Record(ctx, 2)
|
||||
|
||||
provider := metrictest.NewMeterProvider()
|
||||
metricglobal.SetMeterProvider(provider)
|
||||
|
||||
boundC.Add(ctx, 1)
|
||||
boundM.Record(ctx, 3)
|
||||
|
||||
library := metrictest.Library{
|
||||
InstrumentationName: "test",
|
||||
InstrumentationVersion: "semver:test-1.0",
|
||||
SchemaURL: "schema://url",
|
||||
}
|
||||
|
||||
require.EqualValues(t,
|
||||
[]metrictest.Measured{
|
||||
{
|
||||
Name: "test.counter",
|
||||
Library: library,
|
||||
Labels: metrictest.LabelsToMap(labels1...),
|
||||
Number: asFloat(1),
|
||||
},
|
||||
{
|
||||
Name: "test.histogram",
|
||||
Library: library,
|
||||
Labels: metrictest.LabelsToMap(labels1...),
|
||||
Number: asInt(3),
|
||||
},
|
||||
},
|
||||
metrictest.AsStructs(provider.MeasurementBatches))
|
||||
|
||||
boundC.Unbind()
|
||||
boundM.Unbind()
|
||||
}
|
||||
|
||||
func TestUnbind(t *testing.T) {
|
||||
// Tests Unbind with SDK never installed.
|
||||
global.ResetForTest()
|
||||
|
||||
glob := metricglobal.Meter("test")
|
||||
labels1 := []attribute.KeyValue{attribute.String("A", "B")}
|
||||
|
||||
counter := Must(glob).NewFloat64Counter("test.counter")
|
||||
boundC := counter.Bind(labels1...)
|
||||
|
||||
histogram := Must(glob).NewInt64Histogram("test.histogram")
|
||||
boundM := histogram.Bind(labels1...)
|
||||
|
||||
boundC.Unbind()
|
||||
boundM.Unbind()
|
||||
}
|
||||
|
||||
func TestUnbindThenRecordOne(t *testing.T) {
|
||||
global.ResetForTest()
|
||||
|
||||
ctx := context.Background()
|
||||
provider := metrictest.NewMeterProvider()
|
||||
|
||||
meter := metricglobal.Meter("test")
|
||||
counter := Must(meter).NewInt64Counter("test.counter")
|
||||
boundC := counter.Bind()
|
||||
metricglobal.SetMeterProvider(provider)
|
||||
boundC.Unbind()
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
boundC.Add(ctx, 1)
|
||||
})
|
||||
require.Equal(t, 0, len(provider.MeasurementBatches))
|
||||
}
|
||||
|
||||
type meterProviderWithConstructorError struct {
|
||||
metric.MeterProvider
|
||||
}
|
||||
|
@ -260,11 +260,6 @@ type syncInstrument struct {
|
||||
instrument sdkapi.SyncImpl
|
||||
}
|
||||
|
||||
// syncBoundInstrument contains a BoundSyncImpl.
|
||||
type syncBoundInstrument struct {
|
||||
boundInstrument sdkapi.BoundSyncImpl
|
||||
}
|
||||
|
||||
// asyncInstrument contains a AsyncImpl.
|
||||
type asyncInstrument struct {
|
||||
instrument sdkapi.AsyncImpl
|
||||
@ -280,10 +275,6 @@ func (s syncInstrument) SyncImpl() sdkapi.SyncImpl {
|
||||
return s.instrument
|
||||
}
|
||||
|
||||
func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument {
|
||||
return newSyncBoundInstrument(s.instrument.Bind(labels))
|
||||
}
|
||||
|
||||
func (s syncInstrument) float64Measurement(value float64) Measurement {
|
||||
return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value))
|
||||
}
|
||||
@ -296,15 +287,6 @@ func (s syncInstrument) directRecord(ctx context.Context, number number.Number,
|
||||
s.instrument.RecordOne(ctx, number, labels)
|
||||
}
|
||||
|
||||
func (h syncBoundInstrument) directRecord(ctx context.Context, number number.Number) {
|
||||
h.boundInstrument.RecordOne(ctx, number)
|
||||
}
|
||||
|
||||
// Unbind calls SyncImpl.Unbind.
|
||||
func (h syncBoundInstrument) Unbind() {
|
||||
h.boundInstrument.Unbind()
|
||||
}
|
||||
|
||||
// checkNewAsync receives an AsyncImpl and potential
|
||||
// error, and returns the same types, checking for and ensuring that
|
||||
// the returned interface is not nil.
|
||||
@ -340,12 +322,6 @@ func checkNewSync(instrument sdkapi.SyncImpl, err error) (syncInstrument, error)
|
||||
}, err
|
||||
}
|
||||
|
||||
func newSyncBoundInstrument(boundInstrument sdkapi.BoundSyncImpl) syncBoundInstrument {
|
||||
return syncBoundInstrument{
|
||||
boundInstrument: boundInstrument,
|
||||
}
|
||||
}
|
||||
|
||||
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
|
||||
func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) {
|
||||
common, err := checkNewSync(syncInst, err)
|
||||
@ -392,34 +368,6 @@ type Int64Counter struct {
|
||||
syncInstrument
|
||||
}
|
||||
|
||||
// BoundFloat64Counter is a bound instrument for Float64Counter.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundFloat64Counter struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// BoundInt64Counter is a boundInstrument for Int64Counter.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundInt64Counter struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this counter. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Float64Counter) Bind(labels ...attribute.KeyValue) (h BoundFloat64Counter) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this counter. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Int64Counter) Bind(labels ...attribute.KeyValue) (h BoundInt64Counter) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Measurement creates a Measurement object to use with batch
|
||||
// recording.
|
||||
func (c Float64Counter) Measurement(value float64) Measurement {
|
||||
@ -444,18 +392,6 @@ func (c Int64Counter) Add(ctx context.Context, value int64, labels ...attribute.
|
||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||
}
|
||||
|
||||
// Add adds the value to the counter's sum using the labels
|
||||
// previously bound to this counter via Bind()
|
||||
func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
|
||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
||||
}
|
||||
|
||||
// Add adds the value to the counter's sum using the labels
|
||||
// previously bound to this counter via Bind()
|
||||
func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
|
||||
b.directRecord(ctx, number.NewInt64Number(value))
|
||||
}
|
||||
|
||||
// Float64UpDownCounter is a metric instrument that sums floating
|
||||
// point values.
|
||||
type Float64UpDownCounter struct {
|
||||
@ -467,34 +403,6 @@ type Int64UpDownCounter struct {
|
||||
syncInstrument
|
||||
}
|
||||
|
||||
// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundFloat64UpDownCounter struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundInt64UpDownCounter struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this counter. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Float64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundFloat64UpDownCounter) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this counter. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Int64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundInt64UpDownCounter) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Measurement creates a Measurement object to use with batch
|
||||
// recording.
|
||||
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
|
||||
@ -519,18 +427,6 @@ func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...attr
|
||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||
}
|
||||
|
||||
// Add adds the value to the counter's sum using the labels
|
||||
// previously bound to this counter via Bind()
|
||||
func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
|
||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
||||
}
|
||||
|
||||
// Add adds the value to the counter's sum using the labels
|
||||
// previously bound to this counter via Bind()
|
||||
func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
|
||||
b.directRecord(ctx, number.NewInt64Number(value))
|
||||
}
|
||||
|
||||
// Float64Histogram is a metric that records float64 values.
|
||||
type Float64Histogram struct {
|
||||
syncInstrument
|
||||
@ -541,34 +437,6 @@ type Int64Histogram struct {
|
||||
syncInstrument
|
||||
}
|
||||
|
||||
// BoundFloat64Histogram is a bound instrument for Float64Histogram.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundFloat64Histogram struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// BoundInt64Histogram is a bound instrument for Int64Histogram.
|
||||
//
|
||||
// It inherits the Unbind function from syncBoundInstrument.
|
||||
type BoundInt64Histogram struct {
|
||||
syncBoundInstrument
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this Histogram. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Float64Histogram) Bind(labels ...attribute.KeyValue) (h BoundFloat64Histogram) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Bind creates a bound instrument for this Histogram. The labels are
|
||||
// associated with values recorded via subsequent calls to Record.
|
||||
func (c Int64Histogram) Bind(labels ...attribute.KeyValue) (h BoundInt64Histogram) {
|
||||
h.syncBoundInstrument = c.bind(labels)
|
||||
return
|
||||
}
|
||||
|
||||
// Measurement creates a Measurement object to use with batch
|
||||
// recording.
|
||||
func (c Float64Histogram) Measurement(value float64) Measurement {
|
||||
@ -594,15 +462,3 @@ func (c Float64Histogram) Record(ctx context.Context, value float64, labels ...a
|
||||
func (c Int64Histogram) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) {
|
||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||
}
|
||||
|
||||
// Record adds a new value to the Histogram's distribution using the labels
|
||||
// previously bound to the Histogram via Bind().
|
||||
func (b BoundFloat64Histogram) Record(ctx context.Context, value float64) {
|
||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
||||
}
|
||||
|
||||
// Record adds a new value to the Histogram's distribution using the labels
|
||||
// previously bound to the Histogram via Bind().
|
||||
func (b BoundInt64Histogram) Record(ctx context.Context, value int64) {
|
||||
b.directRecord(ctx, number.NewInt64Number(value))
|
||||
}
|
||||
|
@ -250,11 +250,9 @@ func TestCounter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{attribute.String("A", "B")}
|
||||
c.Add(ctx, 1994.1, labels...)
|
||||
boundInstrument := c.Bind(labels...)
|
||||
boundInstrument.Add(ctx, -742)
|
||||
meter.RecordBatch(ctx, labels, c.Measurement(42))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.CounterInstrumentKind, c.SyncImpl(),
|
||||
1994.1, -742, 42,
|
||||
1994.1, 42,
|
||||
)
|
||||
})
|
||||
t.Run("int64 counter", func(t *testing.T) {
|
||||
@ -263,11 +261,9 @@ func TestCounter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")}
|
||||
c.Add(ctx, 42, labels...)
|
||||
boundInstrument := c.Bind(labels...)
|
||||
boundInstrument.Add(ctx, 4200)
|
||||
meter.RecordBatch(ctx, labels, c.Measurement(420000))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.CounterInstrumentKind, c.SyncImpl(),
|
||||
42, 4200, 420000,
|
||||
42, 420000,
|
||||
)
|
||||
|
||||
})
|
||||
@ -277,11 +273,9 @@ func TestCounter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")}
|
||||
c.Add(ctx, 100, labels...)
|
||||
boundInstrument := c.Bind(labels...)
|
||||
boundInstrument.Add(ctx, -100)
|
||||
meter.RecordBatch(ctx, labels, c.Measurement(42))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.UpDownCounterInstrumentKind, c.SyncImpl(),
|
||||
100, -100, 42,
|
||||
100, 42,
|
||||
)
|
||||
})
|
||||
t.Run("float64 updowncounter", func(t *testing.T) {
|
||||
@ -290,11 +284,9 @@ func TestCounter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{attribute.String("A", "B"), attribute.String("C", "D")}
|
||||
c.Add(ctx, 100.1, labels...)
|
||||
boundInstrument := c.Bind(labels...)
|
||||
boundInstrument.Add(ctx, -76)
|
||||
meter.RecordBatch(ctx, labels, c.Measurement(-100.1))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.UpDownCounterInstrumentKind, c.SyncImpl(),
|
||||
100.1, -76, -100.1,
|
||||
100.1, -100.1,
|
||||
)
|
||||
})
|
||||
}
|
||||
@ -306,11 +298,9 @@ func TestHistogram(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{}
|
||||
m.Record(ctx, 42, labels...)
|
||||
boundInstrument := m.Bind(labels...)
|
||||
boundInstrument.Record(ctx, 0)
|
||||
meter.RecordBatch(ctx, labels, m.Measurement(-100.5))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Float64Kind, sdkapi.HistogramInstrumentKind, m.SyncImpl(),
|
||||
42, 0, -100.5,
|
||||
42, -100.5,
|
||||
)
|
||||
})
|
||||
t.Run("int64 histogram", func(t *testing.T) {
|
||||
@ -319,11 +309,9 @@ func TestHistogram(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
labels := []attribute.KeyValue{attribute.Int("I", 1)}
|
||||
m.Record(ctx, 173, labels...)
|
||||
boundInstrument := m.Bind(labels...)
|
||||
boundInstrument.Record(ctx, 80)
|
||||
meter.RecordBatch(ctx, labels, m.Measurement(0))
|
||||
checkSyncBatches(ctx, t, labels, provider, number.Int64Kind, sdkapi.HistogramInstrumentKind, m.SyncImpl(),
|
||||
173, 80, 0,
|
||||
173, 0,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -86,10 +86,9 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdkapi.SyncImpl = &Sync{}
|
||||
_ sdkapi.BoundSyncImpl = &Handle{}
|
||||
_ sdkapi.MeterImpl = &MeterImpl{}
|
||||
_ sdkapi.AsyncImpl = &Async{}
|
||||
_ sdkapi.SyncImpl = &Sync{}
|
||||
_ sdkapi.MeterImpl = &MeterImpl{}
|
||||
_ sdkapi.AsyncImpl = &Async{}
|
||||
)
|
||||
|
||||
// NewDescriptor is a test helper for constructing test metric
|
||||
@ -111,13 +110,6 @@ func (s *Sync) Implementation() interface{} {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Sync) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
return &Handle{
|
||||
Instrument: s,
|
||||
Labels: labels,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sync) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
|
||||
s.meter.doRecordSingle(ctx, labels, s, number)
|
||||
}
|
||||
|
@ -22,12 +22,10 @@ import (
|
||||
)
|
||||
|
||||
type noopInstrument struct{}
|
||||
type noopBoundInstrument struct{}
|
||||
type noopSyncInstrument struct{ noopInstrument }
|
||||
type noopAsyncInstrument struct{ noopInstrument }
|
||||
|
||||
var _ SyncImpl = noopSyncInstrument{}
|
||||
var _ BoundSyncImpl = noopBoundInstrument{}
|
||||
var _ AsyncImpl = noopAsyncInstrument{}
|
||||
|
||||
// NewNoopSyncInstrument returns a No-op implementation of the
|
||||
@ -50,15 +48,5 @@ func (noopInstrument) Descriptor() Descriptor {
|
||||
return Descriptor{}
|
||||
}
|
||||
|
||||
func (noopBoundInstrument) RecordOne(context.Context, number.Number) {
|
||||
}
|
||||
|
||||
func (noopBoundInstrument) Unbind() {
|
||||
}
|
||||
|
||||
func (noopSyncInstrument) Bind([]attribute.KeyValue) BoundSyncImpl {
|
||||
return noopBoundInstrument{}
|
||||
}
|
||||
|
||||
func (noopSyncInstrument) RecordOne(context.Context, number.Number, []attribute.KeyValue) {
|
||||
}
|
||||
|
@ -58,26 +58,10 @@ type InstrumentImpl interface {
|
||||
type SyncImpl interface {
|
||||
InstrumentImpl
|
||||
|
||||
// Bind creates an implementation-level bound instrument,
|
||||
// binding a label set with this instrument implementation.
|
||||
Bind(labels []attribute.KeyValue) BoundSyncImpl
|
||||
|
||||
// RecordOne captures a single synchronous metric event.
|
||||
RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue)
|
||||
}
|
||||
|
||||
// BoundSyncImpl is the implementation-level interface to a
|
||||
// generic bound synchronous instrument
|
||||
type BoundSyncImpl interface {
|
||||
|
||||
// RecordOne captures a single synchronous metric event.
|
||||
RecordOne(ctx context.Context, number number.Number)
|
||||
|
||||
// Unbind frees the resources associated with this bound instrument. It
|
||||
// does not affect the metric this bound instrument was created through.
|
||||
Unbind()
|
||||
}
|
||||
|
||||
// AsyncImpl is an implementation-level interface to an
|
||||
// asynchronous instrument (e.g., Observer instruments).
|
||||
type AsyncImpl interface {
|
||||
|
@ -60,16 +60,6 @@ func (f *benchFixture) meterMust() metric.MeterMust {
|
||||
return metric.Must(f.meter)
|
||||
}
|
||||
|
||||
func makeManyLabels(n int) [][]attribute.KeyValue {
|
||||
r := make([][]attribute.KeyValue, n)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
r[i] = makeLabels(1)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func makeLabels(n int) []attribute.KeyValue {
|
||||
used := map[string]bool{}
|
||||
l := make([]attribute.KeyValue, n)
|
||||
@ -123,50 +113,6 @@ func BenchmarkInt64CounterAddWithLabels_16(b *testing.B) {
|
||||
// Note: performance does not depend on label set size for the
|
||||
// benchmarks below--all are benchmarked for a single attribute.
|
||||
|
||||
func BenchmarkAcquireNewHandle(b *testing.B) {
|
||||
fix := newFixture(b)
|
||||
labelSets := makeManyLabels(b.N)
|
||||
cnt := fix.meterMust().NewInt64Counter("int64.sum")
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cnt.Bind(labelSets[i]...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAcquireExistingHandle(b *testing.B) {
|
||||
fix := newFixture(b)
|
||||
labelSets := makeManyLabels(b.N)
|
||||
cnt := fix.meterMust().NewInt64Counter("int64.sum")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cnt.Bind(labelSets[i]...).Unbind()
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cnt.Bind(labelSets[i]...)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAcquireReleaseExistingHandle(b *testing.B) {
|
||||
fix := newFixture(b)
|
||||
labelSets := makeManyLabels(b.N)
|
||||
cnt := fix.meterMust().NewInt64Counter("int64.sum")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cnt.Bind(labelSets[i]...).Unbind()
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
cnt.Bind(labelSets[i]...).Unbind()
|
||||
}
|
||||
}
|
||||
|
||||
// Iterators
|
||||
|
||||
var benchmarkIteratorVar attribute.KeyValue
|
||||
@ -241,20 +187,6 @@ func BenchmarkInt64CounterAdd(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInt64CounterHandleAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
cnt := fix.meterMust().NewInt64Counter("int64.sum")
|
||||
handle := cnt.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Add(ctx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFloat64CounterAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
@ -268,20 +200,6 @@ func BenchmarkFloat64CounterAdd(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFloat64CounterHandleAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
cnt := fix.meterMust().NewFloat64Counter("float64.sum")
|
||||
handle := cnt.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Add(ctx, 1.1)
|
||||
}
|
||||
}
|
||||
|
||||
// LastValue
|
||||
|
||||
func BenchmarkInt64LastValueAdd(b *testing.B) {
|
||||
@ -297,20 +215,6 @@ func BenchmarkInt64LastValueAdd(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInt64LastValueHandleAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
mea := fix.meterMust().NewInt64Histogram("int64.lastvalue")
|
||||
handle := mea.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Record(ctx, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFloat64LastValueAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
@ -324,20 +228,6 @@ func BenchmarkFloat64LastValueAdd(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFloat64LastValueHandleAdd(b *testing.B) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
mea := fix.meterMust().NewFloat64Histogram("float64.lastvalue")
|
||||
handle := mea.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Record(ctx, float64(i))
|
||||
}
|
||||
}
|
||||
|
||||
// Histograms
|
||||
|
||||
func benchmarkInt64HistogramAdd(b *testing.B, name string) {
|
||||
@ -353,20 +243,6 @@ func benchmarkInt64HistogramAdd(b *testing.B, name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkInt64HistogramHandleAdd(b *testing.B, name string) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
mea := fix.meterMust().NewInt64Histogram(name)
|
||||
handle := mea.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Record(ctx, int64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkFloat64HistogramAdd(b *testing.B, name string) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
@ -380,20 +256,6 @@ func benchmarkFloat64HistogramAdd(b *testing.B, name string) {
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkFloat64HistogramHandleAdd(b *testing.B, name string) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(1)
|
||||
mea := fix.meterMust().NewFloat64Histogram(name)
|
||||
handle := mea.Bind(labs...)
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
handle.Record(ctx, float64(i))
|
||||
}
|
||||
}
|
||||
|
||||
// Observers
|
||||
|
||||
func BenchmarkObserverRegistration(b *testing.B) {
|
||||
@ -447,36 +309,20 @@ func BenchmarkInt64MaxSumCountAdd(b *testing.B) {
|
||||
benchmarkInt64HistogramAdd(b, "int64.minmaxsumcount")
|
||||
}
|
||||
|
||||
func BenchmarkInt64MaxSumCountHandleAdd(b *testing.B) {
|
||||
benchmarkInt64HistogramHandleAdd(b, "int64.minmaxsumcount")
|
||||
}
|
||||
|
||||
func BenchmarkFloat64MaxSumCountAdd(b *testing.B) {
|
||||
benchmarkFloat64HistogramAdd(b, "float64.minmaxsumcount")
|
||||
}
|
||||
|
||||
func BenchmarkFloat64MaxSumCountHandleAdd(b *testing.B) {
|
||||
benchmarkFloat64HistogramHandleAdd(b, "float64.minmaxsumcount")
|
||||
}
|
||||
|
||||
// Exact
|
||||
|
||||
func BenchmarkInt64ExactAdd(b *testing.B) {
|
||||
benchmarkInt64HistogramAdd(b, "int64.exact")
|
||||
}
|
||||
|
||||
func BenchmarkInt64ExactHandleAdd(b *testing.B) {
|
||||
benchmarkInt64HistogramHandleAdd(b, "int64.exact")
|
||||
}
|
||||
|
||||
func BenchmarkFloat64ExactAdd(b *testing.B) {
|
||||
benchmarkFloat64HistogramAdd(b, "float64.exact")
|
||||
}
|
||||
|
||||
func BenchmarkFloat64ExactHandleAdd(b *testing.B) {
|
||||
benchmarkFloat64HistogramHandleAdd(b, "float64.exact")
|
||||
}
|
||||
|
||||
// BatchRecord
|
||||
|
||||
func benchmarkBatchRecord8Labels(b *testing.B, numInst int) {
|
||||
|
@ -483,16 +483,14 @@ func TestRecordPersistence(t *testing.T) {
|
||||
meter, sdk, selector, _ := newSDK(t)
|
||||
|
||||
c := Must(meter).NewFloat64Counter("name.sum")
|
||||
b := c.Bind(attribute.String("bound", "true"))
|
||||
uk := attribute.String("bound", "false")
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
c.Add(ctx, 1, uk)
|
||||
b.Add(ctx, 1)
|
||||
sdk.Collect(ctx)
|
||||
}
|
||||
|
||||
require.Equal(t, 4, selector.newAggCount)
|
||||
require.Equal(t, 2, selector.newAggCount)
|
||||
}
|
||||
|
||||
func TestIncorrectInstruments(t *testing.T) {
|
||||
|
@ -28,9 +28,7 @@ and asynchronous instruments. There are two constructors per instrument for
|
||||
the two kinds of number (int64, float64).
|
||||
|
||||
Synchronous instruments are managed by a sync.Map containing a *record
|
||||
with the current state for each synchronous instrument. A bound
|
||||
instrument encapsulates a direct pointer to the record, allowing
|
||||
bound metric events to bypass a sync.Map lookup. A lock-free
|
||||
with the current state for each synchronous instrument. A lock-free
|
||||
algorithm is used to protect against races when adding and removing
|
||||
items from the sync.Map.
|
||||
|
||||
@ -45,7 +43,7 @@ record contains a set of recorders for every specific label set used in the
|
||||
callback.
|
||||
|
||||
A sync.Map maintains the mapping of current instruments and label sets to
|
||||
internal records. To create a new bound instrument, the SDK consults the Map to
|
||||
internal records. To find a record, the SDK consults the Map to
|
||||
locate an existing record, otherwise it constructs a new record. The SDK
|
||||
maintains a count of the number of references to each record, ensuring
|
||||
that records are not reclaimed from the Map while they are still active
|
||||
|
@ -138,10 +138,9 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdkapi.MeterImpl = &Accumulator{}
|
||||
_ sdkapi.AsyncImpl = &asyncInstrument{}
|
||||
_ sdkapi.SyncImpl = &syncInstrument{}
|
||||
_ sdkapi.BoundSyncImpl = &record{}
|
||||
_ sdkapi.MeterImpl = &Accumulator{}
|
||||
_ sdkapi.AsyncImpl = &asyncInstrument{}
|
||||
_ sdkapi.SyncImpl = &syncInstrument{}
|
||||
|
||||
// ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
|
||||
ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
|
||||
@ -279,15 +278,10 @@ func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attri
|
||||
}
|
||||
}
|
||||
|
||||
// The order of the input array `kvs` may be sorted after the function is called.
|
||||
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
return s.acquireHandle(kvs, nil)
|
||||
}
|
||||
|
||||
// The order of the input array `kvs` may be sorted after the function is called.
|
||||
func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) {
|
||||
h := s.acquireHandle(kvs, nil)
|
||||
defer h.Unbind()
|
||||
defer h.unbind()
|
||||
h.RecordOne(ctx, num)
|
||||
}
|
||||
|
||||
@ -490,7 +484,7 @@ func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue,
|
||||
labelsPtr = h.labels
|
||||
}
|
||||
|
||||
defer h.Unbind()
|
||||
defer h.unbind()
|
||||
h.RecordOne(ctx, meas.Number())
|
||||
}
|
||||
}
|
||||
@ -514,8 +508,7 @@ func (r *record) RecordOne(ctx context.Context, num number.Number) {
|
||||
atomic.AddInt64(&r.updateCount, 1)
|
||||
}
|
||||
|
||||
// Unbind implements sdkapi.SyncImpl.
|
||||
func (r *record) Unbind() {
|
||||
func (r *record) unbind() {
|
||||
r.refMapped.unref()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user