1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-03 00:27:03 +02:00

Metrics: Move the non-API types into sdkapi (#2271)

* move Descriptor to sdkapi, add test

* rename Descriptor to sdkapi

* precommit

* Move the rest of the sdkapi

* use alias for Observation and Measurement

* Changelog

* pr num

* comment Measurement and Observation

* swap comments

* move->moved
This commit is contained in:
Joshua MacDonald
2021-10-14 09:06:22 -07:00
committed by GitHub
parent 8ba6da8f3e
commit 478dc4fe40
51 changed files with 703 additions and 615 deletions

View File

@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## Changed ## Changed
- Skip links with invalid span context. (#2275) - Skip links with invalid span context. (#2275)
- Metrics API cleanup. The `metric/sdkapi` package has been created to relocate the API-to-SDK interface:
- The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner`
- The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`.
- The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271)
### Added ### Added

View File

@ -147,7 +147,7 @@ func convertResource(res *ocresource.Resource) *resource.Resource {
} }
// convertDescriptor converts an OpenCensus Descriptor to an OpenTelemetry Descriptor // convertDescriptor converts an OpenCensus Descriptor to an OpenTelemetry Descriptor
func convertDescriptor(ocDescriptor metricdata.Descriptor) (metric.Descriptor, error) { func convertDescriptor(ocDescriptor metricdata.Descriptor) (sdkapi.Descriptor, error) {
var ( var (
nkind number.Kind nkind number.Kind
ikind sdkapi.InstrumentKind ikind sdkapi.InstrumentKind
@ -167,7 +167,7 @@ func convertDescriptor(ocDescriptor metricdata.Descriptor) (metric.Descriptor, e
ikind = sdkapi.CounterObserverInstrumentKind ikind = sdkapi.CounterObserverInstrumentKind
default: default:
// Includes TypeGaugeDistribution, TypeCumulativeDistribution, TypeSummary // Includes TypeGaugeDistribution, TypeCumulativeDistribution, TypeSummary
return metric.Descriptor{}, fmt.Errorf("%w; descriptor type: %v", errConversion, ocDescriptor.Type) return sdkapi.Descriptor{}, fmt.Errorf("%w; descriptor type: %v", errConversion, ocDescriptor.Type)
} }
opts := []metric.InstrumentOption{ opts := []metric.InstrumentOption{
metric.WithDescription(ocDescriptor.Description), metric.WithDescription(ocDescriptor.Description),
@ -181,5 +181,5 @@ func convertDescriptor(ocDescriptor metricdata.Descriptor) (metric.Descriptor, e
opts = append(opts, metric.WithUnit(unit.Milliseconds)) opts = append(opts, metric.WithUnit(unit.Milliseconds))
} }
cfg := metric.NewInstrumentConfig(opts...) cfg := metric.NewInstrumentConfig(opts...)
return metric.NewDescriptor(ocDescriptor.Name, ikind, nkind, cfg.Description(), cfg.Unit()), nil return sdkapi.NewDescriptor(ocDescriptor.Name, ikind, nkind, cfg.Description(), cfg.Unit()), nil
} }

View File

@ -391,7 +391,7 @@ func TestConvertDescriptor(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
desc string desc string
input metricdata.Descriptor input metricdata.Descriptor
expected metric.Descriptor expected sdkapi.Descriptor
expectedErr error expectedErr error
}{ }{
{ {

View File

@ -20,7 +20,7 @@ import (
"sync" "sync"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/metrictransform" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/metrictransform"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric" metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
@ -96,7 +96,7 @@ func (e *Exporter) Shutdown(ctx context.Context) error {
return err return err
} }
func (e *Exporter) ExportKindFor(descriptor *metric.Descriptor, aggregatorKind aggregation.Kind) metricsdk.ExportKind { func (e *Exporter) ExportKindFor(descriptor *sdkapi.Descriptor, aggregatorKind aggregation.Kind) metricsdk.ExportKind {
return e.exportKindSelector.ExportKindFor(descriptor, aggregatorKind) return e.exportKindSelector.ExportKindFor(descriptor, aggregatorKind)
} }

View File

@ -25,7 +25,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
@ -101,18 +100,18 @@ func TestStringKeyValues(t *testing.T) {
} }
func TestMinMaxSumCountValue(t *testing.T) { func TestMinMaxSumCountValue(t *testing.T) {
mmscs := minmaxsumcount.New(2, &metric.Descriptor{}) mmscs := minmaxsumcount.New(2, &sdkapi.Descriptor{})
mmsc, ckpt := &mmscs[0], &mmscs[1] mmsc, ckpt := &mmscs[0], &mmscs[1]
assert.NoError(t, mmsc.Update(context.Background(), 1, &metric.Descriptor{})) assert.NoError(t, mmsc.Update(context.Background(), 1, &sdkapi.Descriptor{}))
assert.NoError(t, mmsc.Update(context.Background(), 10, &metric.Descriptor{})) assert.NoError(t, mmsc.Update(context.Background(), 10, &sdkapi.Descriptor{}))
// Prior to checkpointing ErrNoData should be returned. // Prior to checkpointing ErrNoData should be returned.
_, _, _, _, err := minMaxSumCountValues(ckpt) _, _, _, _, err := minMaxSumCountValues(ckpt)
assert.EqualError(t, err, aggregation.ErrNoData.Error()) assert.EqualError(t, err, aggregation.ErrNoData.Error())
// Checkpoint to set non-zero values // Checkpoint to set non-zero values
require.NoError(t, mmsc.SynchronizedMove(ckpt, &metric.Descriptor{})) require.NoError(t, mmsc.SynchronizedMove(ckpt, &sdkapi.Descriptor{}))
min, max, sum, count, err := minMaxSumCountValues(ckpt) min, max, sum, count, err := minMaxSumCountValues(ckpt)
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, min, number.NewInt64Number(1)) assert.Equal(t, min, number.NewInt64Number(1))
@ -125,7 +124,7 @@ func TestMinMaxSumCountValue(t *testing.T) {
func TestMinMaxSumCountDatapoints(t *testing.T) { func TestMinMaxSumCountDatapoints(t *testing.T) {
desc := metrictest.NewDescriptor("", sdkapi.HistogramInstrumentKind, number.Int64Kind) desc := metrictest.NewDescriptor("", sdkapi.HistogramInstrumentKind, number.Int64Kind)
labels := attribute.NewSet(attribute.String("one", "1")) labels := attribute.NewSet(attribute.String("one", "1"))
mmscs := minmaxsumcount.New(2, &metric.Descriptor{}) mmscs := minmaxsumcount.New(2, &sdkapi.Descriptor{})
mmsc, ckpt := &mmscs[0], &mmscs[1] mmsc, ckpt := &mmscs[0], &mmscs[1]
assert.NoError(t, mmsc.Update(context.Background(), 1, &desc)) assert.NoError(t, mmsc.Update(context.Background(), 1, &desc))
@ -172,7 +171,7 @@ func TestMinMaxSumCountPropagatesErrors(t *testing.T) {
// ErrNoData should be returned by both the Min and Max values of // ErrNoData should be returned by both the Min and Max values of
// a MinMaxSumCount Aggregator. Use this fact to check the error is // a MinMaxSumCount Aggregator. Use this fact to check the error is
// correctly returned. // correctly returned.
mmsc := &minmaxsumcount.New(1, &metric.Descriptor{})[0] mmsc := &minmaxsumcount.New(1, &sdkapi.Descriptor{})[0]
_, _, _, _, err := minMaxSumCountValues(mmsc) _, _, _, _, err := minMaxSumCountValues(mmsc)
assert.Error(t, err) assert.Error(t, err)
assert.Equal(t, aggregation.ErrNoData, err) assert.Equal(t, aggregation.ErrNoData, err)
@ -390,13 +389,13 @@ func (t *testAgg) Aggregation() aggregation.Aggregation {
// None of these three are used: // None of these three are used:
func (t *testAgg) Update(ctx context.Context, number number.Number, descriptor *metric.Descriptor) error { func (t *testAgg) Update(ctx context.Context, number number.Number, descriptor *sdkapi.Descriptor) error {
return nil return nil
} }
func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *metric.Descriptor) error { func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *sdkapi.Descriptor) error {
return nil return nil
} }
func (t *testAgg) Merge(aggregator export.Aggregator, descriptor *metric.Descriptor) error { func (t *testAgg) Merge(aggregator export.Aggregator, descriptor *sdkapi.Descriptor) error {
return nil return nil
} }

View File

@ -30,6 +30,7 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
@ -132,7 +133,7 @@ func (e *Exporter) Controller() *controller.Controller {
} }
// ExportKindFor implements ExportKindSelector. // ExportKindFor implements ExportKindSelector.
func (e *Exporter) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) export.ExportKind { func (e *Exporter) ExportKindFor(desc *sdkapi.Descriptor, kind aggregation.Kind) export.ExportKind {
return export.CumulativeExportKindSelector().ExportKindFor(desc, kind) return export.CumulativeExportKindSelector().ExportKindFor(desc, kind)
} }

View File

@ -22,7 +22,7 @@ import (
"time" "time"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
exportmetric "go.opentelemetry.io/otel/sdk/export/metric" exportmetric "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
@ -47,7 +47,7 @@ type line struct {
Timestamp *time.Time `json:"Timestamp,omitempty"` Timestamp *time.Time `json:"Timestamp,omitempty"`
} }
func (e *metricExporter) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) exportmetric.ExportKind { func (e *metricExporter) ExportKindFor(desc *sdkapi.Descriptor, kind aggregation.Kind) exportmetric.ExportKind {
return exportmetric.StatelessExportKindSelector().ExportKindFor(desc, kind) return exportmetric.StatelessExportKindSelector().ExportKindFor(desc, kind)
} }

View File

@ -22,7 +22,7 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
) )
//nolint:revive // ignoring missing comments for exported error in an internal package //nolint:revive // ignoring missing comments for exported error in an internal package
@ -33,7 +33,7 @@ var ErrInvalidAsyncRunner = errors.New("unknown async runner type")
// the SDK to provide support for running observer callbacks. // the SDK to provide support for running observer callbacks.
type AsyncCollector interface { type AsyncCollector interface {
// CollectAsync passes a batch of observations to the MeterImpl. // CollectAsync passes a batch of observations to the MeterImpl.
CollectAsync(labels []attribute.KeyValue, observation ...metric.Observation) CollectAsync(labels []attribute.KeyValue, observation ...sdkapi.Observation)
} }
// AsyncInstrumentState manages an ordered set of asynchronous // AsyncInstrumentState manages an ordered set of asynchronous
@ -61,18 +61,18 @@ type AsyncInstrumentState struct {
// instruments maintains the set of instruments in the order // instruments maintains the set of instruments in the order
// they were registered. // they were registered.
instruments []metric.AsyncImpl instruments []sdkapi.AsyncImpl
} }
// asyncRunnerPair is a map entry for Observer callback runners. // asyncRunnerPair is a map entry for Observer callback runners.
type asyncRunnerPair struct { type asyncRunnerPair struct {
// runner is used as a map key here. The API ensures // runner is used as a map key here. The API ensures
// that all callbacks are pointers for this reason. // that all callbacks are pointers for this reason.
runner metric.AsyncRunner runner sdkapi.AsyncRunner
// inst refers to a non-nil instrument when `runner` is a // inst refers to a non-nil instrument when `runner` is a
// AsyncSingleRunner. // AsyncSingleRunner.
inst metric.AsyncImpl inst sdkapi.AsyncImpl
} }
// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for // NewAsyncInstrumentState returns a new *AsyncInstrumentState, for
@ -87,7 +87,7 @@ func NewAsyncInstrumentState() *AsyncInstrumentState {
// Instruments returns the asynchronous instruments managed by this // Instruments returns the asynchronous instruments managed by this
// object, the set that should be checkpointed after observers are // object, the set that should be checkpointed after observers are
// run. // run.
func (a *AsyncInstrumentState) Instruments() []metric.AsyncImpl { func (a *AsyncInstrumentState) Instruments() []sdkapi.AsyncImpl {
a.lock.Lock() a.lock.Lock()
defer a.lock.Unlock() defer a.lock.Unlock()
return a.instruments return a.instruments
@ -97,7 +97,7 @@ func (a *AsyncInstrumentState) Instruments() []metric.AsyncImpl {
// object. This should be called during NewAsyncInstrument() and // object. This should be called during NewAsyncInstrument() and
// assumes that errors (e.g., duplicate registration) have already // assumes that errors (e.g., duplicate registration) have already
// been checked. // been checked.
func (a *AsyncInstrumentState) Register(inst metric.AsyncImpl, runner metric.AsyncRunner) { func (a *AsyncInstrumentState) Register(inst sdkapi.AsyncImpl, runner sdkapi.AsyncRunner) {
a.lock.Lock() a.lock.Lock()
defer a.lock.Unlock() defer a.lock.Unlock()
@ -111,7 +111,7 @@ func (a *AsyncInstrumentState) Register(inst metric.AsyncImpl, runner metric.Asy
rp := asyncRunnerPair{ rp := asyncRunnerPair{
runner: runner, runner: runner,
} }
if _, ok := runner.(metric.AsyncSingleRunner); ok { if _, ok := runner.(sdkapi.AsyncSingleRunner); ok {
rp.inst = inst rp.inst = inst
} }
@ -132,12 +132,12 @@ func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector
// other implementations are possible because the // other implementations are possible because the
// interface has un-exported methods. // interface has un-exported methods.
if singleRunner, ok := rp.runner.(metric.AsyncSingleRunner); ok { if singleRunner, ok := rp.runner.(sdkapi.AsyncSingleRunner); ok {
singleRunner.Run(ctx, rp.inst, collector.CollectAsync) singleRunner.Run(ctx, rp.inst, collector.CollectAsync)
continue continue
} }
if multiRunner, ok := rp.runner.(metric.AsyncBatchRunner); ok { if multiRunner, ok := rp.runner.(sdkapi.AsyncBatchRunner); ok {
multiRunner.Run(ctx, collector.CollectAsync) multiRunner.Run(ctx, collector.CollectAsync)
continue continue
} }

View File

@ -24,6 +24,7 @@ import (
"go.opentelemetry.io/otel/internal/metric/registry" "go.opentelemetry.io/otel/internal/metric/registry"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
) )
// This file contains the forwarding implementation of MeterProvider used as // This file contains the forwarding implementation of MeterProvider used as
@ -73,42 +74,42 @@ type meterImpl struct {
} }
type meterEntry struct { type meterEntry struct {
unique metric.MeterImpl unique sdkapi.MeterImpl
impl meterImpl impl meterImpl
} }
type instrument struct { type instrument struct {
descriptor metric.Descriptor descriptor sdkapi.Descriptor
} }
type syncImpl struct { type syncImpl struct {
delegate unsafe.Pointer // (*metric.SyncImpl) delegate unsafe.Pointer // (*sdkapi.SyncImpl)
instrument instrument
} }
type asyncImpl struct { type asyncImpl struct {
delegate unsafe.Pointer // (*metric.AsyncImpl) delegate unsafe.Pointer // (*sdkapi.AsyncImpl)
instrument instrument
runner metric.AsyncRunner runner sdkapi.AsyncRunner
} }
// SyncImpler is implemented by all of the sync metric // SyncImpler is implemented by all of the sync metric
// instruments. // instruments.
type SyncImpler interface { type SyncImpler interface {
SyncImpl() metric.SyncImpl SyncImpl() sdkapi.SyncImpl
} }
// AsyncImpler is implemented by all of the async // AsyncImpler is implemented by all of the async
// metric instruments. // metric instruments.
type AsyncImpler interface { type AsyncImpler interface {
AsyncImpl() metric.AsyncImpl AsyncImpl() sdkapi.AsyncImpl
} }
type syncHandle struct { type syncHandle struct {
delegate unsafe.Pointer // (*metric.BoundInstrumentImpl) delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
inst *syncImpl inst *syncImpl
labels []attribute.KeyValue labels []attribute.KeyValue
@ -117,12 +118,12 @@ type syncHandle struct {
} }
var _ metric.MeterProvider = &meterProvider{} var _ metric.MeterProvider = &meterProvider{}
var _ metric.MeterImpl = &meterImpl{} var _ sdkapi.MeterImpl = &meterImpl{}
var _ metric.InstrumentImpl = &syncImpl{} var _ sdkapi.InstrumentImpl = &syncImpl{}
var _ metric.BoundSyncImpl = &syncHandle{} var _ sdkapi.BoundSyncImpl = &syncHandle{}
var _ metric.AsyncImpl = &asyncImpl{} var _ sdkapi.AsyncImpl = &asyncImpl{}
func (inst *instrument) Descriptor() metric.Descriptor { func (inst *instrument) Descriptor() sdkapi.Descriptor {
return inst.descriptor return inst.descriptor
} }
@ -179,7 +180,7 @@ func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
d := new(metric.MeterImpl) d := new(sdkapi.MeterImpl)
*d = provider.Meter( *d = provider.Meter(
key.InstrumentationName, key.InstrumentationName,
metric.WithInstrumentationVersion(key.InstrumentationVersion), metric.WithInstrumentationVersion(key.InstrumentationVersion),
@ -197,11 +198,11 @@ func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
m.asyncInsts = nil m.asyncInsts = nil
} }
func (m *meterImpl) NewSyncInstrument(desc metric.Descriptor) (metric.SyncImpl, error) { func (m *meterImpl) NewSyncInstrument(desc sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).NewSyncInstrument(desc) return (*meterPtr).NewSyncInstrument(desc)
} }
@ -216,8 +217,8 @@ func (m *meterImpl) NewSyncInstrument(desc metric.Descriptor) (metric.SyncImpl,
// Synchronous delegation // Synchronous delegation
func (inst *syncImpl) setDelegate(d metric.MeterImpl) { func (inst *syncImpl) setDelegate(d sdkapi.MeterImpl) {
implPtr := new(metric.SyncImpl) implPtr := new(sdkapi.SyncImpl)
var err error var err error
*implPtr, err = d.NewSyncInstrument(inst.descriptor) *implPtr, err = d.NewSyncInstrument(inst.descriptor)
@ -234,14 +235,14 @@ func (inst *syncImpl) setDelegate(d metric.MeterImpl) {
} }
func (inst *syncImpl) Implementation() interface{} { func (inst *syncImpl) Implementation() interface{} {
if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil { if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
return (*implPtr).Implementation() return (*implPtr).Implementation()
} }
return inst return inst
} }
func (inst *syncImpl) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl { func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil { if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
return (*implPtr).Bind(labels) return (*implPtr).Bind(labels)
} }
return &syncHandle{ return &syncHandle{
@ -253,7 +254,7 @@ func (inst *syncImpl) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl {
func (bound *syncHandle) Unbind() { func (bound *syncHandle) Unbind() {
bound.initialize.Do(func() {}) bound.initialize.Do(func() {})
implPtr := (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate)) implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
if implPtr == nil { if implPtr == nil {
return return
@ -265,14 +266,14 @@ func (bound *syncHandle) Unbind() {
// Async delegation // Async delegation
func (m *meterImpl) NewAsyncInstrument( func (m *meterImpl) NewAsyncInstrument(
desc metric.Descriptor, desc sdkapi.Descriptor,
runner metric.AsyncRunner, runner sdkapi.AsyncRunner,
) (metric.AsyncImpl, error) { ) (sdkapi.AsyncImpl, error) {
m.lock.Lock() m.lock.Lock()
defer m.lock.Unlock() defer m.lock.Unlock()
if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil { if meterPtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).NewAsyncInstrument(desc, runner) return (*meterPtr).NewAsyncInstrument(desc, runner)
} }
@ -287,14 +288,14 @@ func (m *meterImpl) NewAsyncInstrument(
} }
func (obs *asyncImpl) Implementation() interface{} { func (obs *asyncImpl) Implementation() interface{} {
if implPtr := (*metric.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil { if implPtr := (*sdkapi.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil {
return (*implPtr).Implementation() return (*implPtr).Implementation()
} }
return obs return obs
} }
func (obs *asyncImpl) setDelegate(d metric.MeterImpl) { func (obs *asyncImpl) setDelegate(d sdkapi.MeterImpl) {
implPtr := new(metric.AsyncImpl) implPtr := new(sdkapi.AsyncImpl)
var err error var err error
*implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner) *implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner)
@ -312,14 +313,14 @@ func (obs *asyncImpl) setDelegate(d metric.MeterImpl) {
// Metric updates // Metric updates
func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...metric.Measurement) { func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
if delegatePtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil { if delegatePtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
(*delegatePtr).RecordBatch(ctx, labels, measurements...) (*delegatePtr).RecordBatch(ctx, labels, measurements...)
} }
} }
func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) { func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
if instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil { if instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
(*instPtr).RecordOne(ctx, number, labels) (*instPtr).RecordOne(ctx, number, labels)
} }
} }
@ -327,18 +328,18 @@ func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, label
// Bound instrument initialization // Bound instrument initialization
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) { func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate)) instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
if instPtr == nil { if instPtr == nil {
return return
} }
var implPtr *metric.BoundSyncImpl var implPtr *sdkapi.BoundSyncImpl
bound.initialize.Do(func() { bound.initialize.Do(func() {
implPtr = new(metric.BoundSyncImpl) implPtr = new(sdkapi.BoundSyncImpl)
*implPtr = (*instPtr).Bind(bound.labels) *implPtr = (*instPtr).Bind(bound.labels)
atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr)) atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
}) })
if implPtr == nil { if implPtr == nil {
implPtr = (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate)) implPtr = (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
} }
// This may still be nil if instrument was created and bound // This may still be nil if instrument was created and bound
// without a delegate, then the instrument was set to have a // without a delegate, then the instrument was set to have a

View File

@ -27,6 +27,7 @@ import (
metricglobal "go.opentelemetry.io/otel/metric/global" metricglobal "go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
) )
var Must = metric.Must var Must = metric.Must
@ -232,15 +233,15 @@ type meterProviderWithConstructorError struct {
} }
type meterWithConstructorError struct { type meterWithConstructorError struct {
metric.MeterImpl sdkapi.MeterImpl
} }
func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter { func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter {
return metric.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()}) return metric.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()})
} }
func (m *meterWithConstructorError) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) { func (m *meterWithConstructorError) NewSyncInstrument(_ sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
return metric.NoopSync{}, errors.New("constructor error") return sdkapi.NewNoopSyncInstrument(), errors.New("constructor error")
} }
func TestErrorInDeferredConstructor(t *testing.T) { func TestErrorInDeferredConstructor(t *testing.T) {

View File

@ -24,46 +24,47 @@ import (
"go.opentelemetry.io/otel/internal/metric/registry" "go.opentelemetry.io/otel/internal/metric/registry"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/sdkapi"
) )
type ( type (
newFunc func(name, libraryName string) (metric.InstrumentImpl, error) newFunc func(name, libraryName string) (sdkapi.InstrumentImpl, error)
) )
var ( var (
allNew = map[string]newFunc{ allNew = map[string]newFunc{
"counter.int64": func(name, libraryName string) (metric.InstrumentImpl, error) { "counter.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64Counter(name)) return unwrap(MeterProvider().Meter(libraryName).NewInt64Counter(name))
}, },
"counter.float64": func(name, libraryName string) (metric.InstrumentImpl, error) { "counter.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64Counter(name)) return unwrap(MeterProvider().Meter(libraryName).NewFloat64Counter(name))
}, },
"histogram.int64": func(name, libraryName string) (metric.InstrumentImpl, error) { "histogram.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64Histogram(name)) return unwrap(MeterProvider().Meter(libraryName).NewInt64Histogram(name))
}, },
"histogram.float64": func(name, libraryName string) (metric.InstrumentImpl, error) { "histogram.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64Histogram(name)) return unwrap(MeterProvider().Meter(libraryName).NewFloat64Histogram(name))
}, },
"gauge.int64": func(name, libraryName string) (metric.InstrumentImpl, error) { "gauge.int64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {})) return unwrap(MeterProvider().Meter(libraryName).NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {}))
}, },
"gauge.float64": func(name, libraryName string) (metric.InstrumentImpl, error) { "gauge.float64": func(name, libraryName string) (sdkapi.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {})) return unwrap(MeterProvider().Meter(libraryName).NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {}))
}, },
} }
) )
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) { func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) {
if impl == nil { if impl == nil {
return nil, err return nil, err
} }
if s, ok := impl.(interface { if s, ok := impl.(interface {
SyncImpl() metric.SyncImpl SyncImpl() sdkapi.SyncImpl
}); ok { }); ok {
return s.SyncImpl(), err return s.SyncImpl(), err
} }
if a, ok := impl.(interface { if a, ok := impl.(interface {
AsyncImpl() metric.AsyncImpl AsyncImpl() sdkapi.AsyncImpl
}); ok { }); ok {
return a.AsyncImpl(), err return a.AsyncImpl(), err
} }

View File

@ -20,18 +20,18 @@ import (
"sync" "sync"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
) )
// UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding // UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding
// uniqueness checking for instrument descriptors. // uniqueness checking for instrument descriptors.
type UniqueInstrumentMeterImpl struct { type UniqueInstrumentMeterImpl struct {
lock sync.Mutex lock sync.Mutex
impl metric.MeterImpl impl sdkapi.MeterImpl
state map[string]metric.InstrumentImpl state map[string]sdkapi.InstrumentImpl
} }
var _ metric.MeterImpl = (*UniqueInstrumentMeterImpl)(nil) var _ sdkapi.MeterImpl = (*UniqueInstrumentMeterImpl)(nil)
// ErrMetricKindMismatch is the standard error for mismatched metric // ErrMetricKindMismatch is the standard error for mismatched metric
// instrument definitions. // instrument definitions.
@ -40,27 +40,27 @@ var ErrMetricKindMismatch = fmt.Errorf(
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl // NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl
// with the addition of instrument name uniqueness checking. // with the addition of instrument name uniqueness checking.
func NewUniqueInstrumentMeterImpl(impl metric.MeterImpl) *UniqueInstrumentMeterImpl { func NewUniqueInstrumentMeterImpl(impl sdkapi.MeterImpl) *UniqueInstrumentMeterImpl {
return &UniqueInstrumentMeterImpl{ return &UniqueInstrumentMeterImpl{
impl: impl, impl: impl,
state: map[string]metric.InstrumentImpl{}, state: map[string]sdkapi.InstrumentImpl{},
} }
} }
// MeterImpl gives the caller access to the underlying MeterImpl // MeterImpl gives the caller access to the underlying MeterImpl
// used by this UniqueInstrumentMeterImpl. // used by this UniqueInstrumentMeterImpl.
func (u *UniqueInstrumentMeterImpl) MeterImpl() metric.MeterImpl { func (u *UniqueInstrumentMeterImpl) MeterImpl() sdkapi.MeterImpl {
return u.impl return u.impl
} }
// RecordBatch implements metric.MeterImpl. // RecordBatch implements sdkapi.MeterImpl.
func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...metric.Measurement) { func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...sdkapi.Measurement) {
u.impl.RecordBatch(ctx, labels, ms...) u.impl.RecordBatch(ctx, labels, ms...)
} }
// NewMetricKindMismatchError formats an error that describes a // NewMetricKindMismatchError formats an error that describes a
// mismatched metric instrument definition. // mismatched metric instrument definition.
func NewMetricKindMismatchError(desc metric.Descriptor) error { func NewMetricKindMismatchError(desc sdkapi.Descriptor) error {
return fmt.Errorf("metric %s registered as %s %s: %w", return fmt.Errorf("metric %s registered as %s %s: %w",
desc.Name(), desc.Name(),
desc.NumberKind(), desc.NumberKind(),
@ -68,9 +68,9 @@ func NewMetricKindMismatchError(desc metric.Descriptor) error {
ErrMetricKindMismatch) ErrMetricKindMismatch)
} }
// Compatible determines whether two metric.Descriptors are considered // Compatible determines whether two sdkapi.Descriptors are considered
// the same for the purpose of uniqueness checking. // the same for the purpose of uniqueness checking.
func Compatible(candidate, existing metric.Descriptor) bool { func Compatible(candidate, existing sdkapi.Descriptor) bool {
return candidate.InstrumentKind() == existing.InstrumentKind() && return candidate.InstrumentKind() == existing.InstrumentKind() &&
candidate.NumberKind() == existing.NumberKind() candidate.NumberKind() == existing.NumberKind()
} }
@ -80,7 +80,7 @@ func Compatible(candidate, existing metric.Descriptor) bool {
// `descriptor` argument. If there is an existing compatible // `descriptor` argument. If there is an existing compatible
// registration, this returns the already-registered instrument. If // registration, this returns the already-registered instrument. If
// there is no conflict and no prior registration, returns (nil, nil). // there is no conflict and no prior registration, returns (nil, nil).
func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor metric.Descriptor) (metric.InstrumentImpl, error) { func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor sdkapi.Descriptor) (sdkapi.InstrumentImpl, error) {
impl, ok := u.state[descriptor.Name()] impl, ok := u.state[descriptor.Name()]
if !ok { if !ok {
return nil, nil return nil, nil
@ -93,8 +93,8 @@ func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor metric.Descriptor
return impl, nil return impl, nil
} }
// NewSyncInstrument implements metric.MeterImpl. // NewSyncInstrument implements sdkapi.MeterImpl.
func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) { func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
u.lock.Lock() u.lock.Lock()
defer u.lock.Unlock() defer u.lock.Unlock()
@ -103,7 +103,7 @@ func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descript
if err != nil { if err != nil {
return nil, err return nil, err
} else if impl != nil { } else if impl != nil {
return impl.(metric.SyncImpl), nil return impl.(sdkapi.SyncImpl), nil
} }
syncInst, err := u.impl.NewSyncInstrument(descriptor) syncInst, err := u.impl.NewSyncInstrument(descriptor)
@ -114,11 +114,11 @@ func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descript
return syncInst, nil return syncInst, nil
} }
// NewAsyncInstrument implements metric.MeterImpl. // NewAsyncInstrument implements sdkapi.MeterImpl.
func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument( func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
descriptor metric.Descriptor, descriptor sdkapi.Descriptor,
runner metric.AsyncRunner, runner sdkapi.AsyncRunner,
) (metric.AsyncImpl, error) { ) (sdkapi.AsyncImpl, error) {
u.lock.Lock() u.lock.Lock()
defer u.lock.Unlock() defer u.lock.Unlock()
@ -127,7 +127,7 @@ func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
if err != nil { if err != nil {
return nil, err return nil, err
} else if impl != nil { } else if impl != nil {
return impl.(metric.AsyncImpl), nil return impl.(sdkapi.AsyncImpl), nil
} }
asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner) asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner)

View File

@ -24,46 +24,47 @@ import (
"go.opentelemetry.io/otel/internal/metric/registry" "go.opentelemetry.io/otel/internal/metric/registry"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/sdkapi"
) )
type ( type (
newFunc func(m metric.Meter, name string) (metric.InstrumentImpl, error) newFunc func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error)
) )
var ( var (
allNew = map[string]newFunc{ allNew = map[string]newFunc{
"counter.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "counter.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewInt64Counter(name)) return unwrap(m.NewInt64Counter(name))
}, },
"counter.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "counter.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewFloat64Counter(name)) return unwrap(m.NewFloat64Counter(name))
}, },
"histogram.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "histogram.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewInt64Histogram(name)) return unwrap(m.NewInt64Histogram(name))
}, },
"histogram.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "histogram.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewFloat64Histogram(name)) return unwrap(m.NewFloat64Histogram(name))
}, },
"gaugeobserver.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "gaugeobserver.int64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {})) return unwrap(m.NewInt64GaugeObserver(name, func(context.Context, metric.Int64ObserverResult) {}))
}, },
"gaugeobserver.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) { "gaugeobserver.float64": func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error) {
return unwrap(m.NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {})) return unwrap(m.NewFloat64GaugeObserver(name, func(context.Context, metric.Float64ObserverResult) {}))
}, },
} }
) )
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) { func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) {
if impl == nil { if impl == nil {
return nil, err return nil, err
} }
if s, ok := impl.(interface { if s, ok := impl.(interface {
SyncImpl() metric.SyncImpl SyncImpl() sdkapi.SyncImpl
}); ok { }); ok {
return s.SyncImpl(), err return s.SyncImpl(), err
} }
if a, ok := impl.(interface { if a, ok := impl.(interface {
AsyncImpl() metric.AsyncImpl AsyncImpl() sdkapi.AsyncImpl
}); ok { }); ok {
return a.AsyncImpl(), err return a.AsyncImpl(), err
} }

View File

@ -20,7 +20,6 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
"go.opentelemetry.io/otel/metric/unit"
) )
// MeterProvider supports named Meter instances. // MeterProvider supports named Meter instances.
@ -38,9 +37,33 @@ type MeterProvider interface {
// //
// An uninitialized Meter is a no-op implementation. // An uninitialized Meter is a no-op implementation.
type Meter struct { type Meter struct {
impl MeterImpl impl sdkapi.MeterImpl
} }
// WrapMeterImpl constructs a `Meter` implementation from a
// `MeterImpl` implementation.
func WrapMeterImpl(impl sdkapi.MeterImpl) Meter {
return Meter{
impl: impl,
}
}
// Measurement is used for reporting a synchronous batch of metric
// values. Instances of this type should be created by synchronous
// instruments (e.g., Int64Counter.Measurement()).
//
// Note: This is an alias because it is a first-class member of the
// API but is also part of the lower-level sdkapi interface.
type Measurement = sdkapi.Measurement
// Observation is used for reporting an asynchronous batch of metric
// values. Instances of this type should be created by asynchronous
// instruments (e.g., Int64GaugeObserver.Observation()).
//
// Note: This is an alias because it is a first-class member of the
// API but is also part of the lower-level sdkapi interface.
type Observation = sdkapi.Observation
// RecordBatch atomically records a batch of measurements. // RecordBatch atomically records a batch of measurements.
func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) { func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) {
if m.impl == nil { if m.impl == nil {
@ -118,7 +141,7 @@ func (m Meter) NewFloat64Histogram(name string, opts ...InstrumentOption) (Float
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64GaugeObserver, error) { func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64GaugeObserver, error) {
if callback == nil { if callback == nil {
return wrapInt64GaugeObserverInstrument(NoopAsync{}, nil) return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64GaugeObserverInstrument( return wrapInt64GaugeObserverInstrument(
m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts,
@ -131,7 +154,7 @@ func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, op
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64GaugeObserver, error) { func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64GaugeObserver, error) {
if callback == nil { if callback == nil {
return wrapFloat64GaugeObserverInstrument(NoopAsync{}, nil) return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64GaugeObserverInstrument( return wrapFloat64GaugeObserverInstrument(
m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts, m.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts,
@ -144,7 +167,7 @@ func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64CounterObserver, error) { func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64CounterObserver, error) {
if callback == nil { if callback == nil {
return wrapInt64CounterObserverInstrument(NoopAsync{}, nil) return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64CounterObserverInstrument( return wrapInt64CounterObserverInstrument(
m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts,
@ -157,7 +180,7 @@ func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc,
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64CounterObserver, error) { func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64CounterObserver, error) {
if callback == nil { if callback == nil {
return wrapFloat64CounterObserverInstrument(NoopAsync{}, nil) return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64CounterObserverInstrument( return wrapFloat64CounterObserverInstrument(
m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts, m.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts,
@ -170,7 +193,7 @@ func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFu
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) { func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
if callback == nil { if callback == nil {
return wrapInt64UpDownCounterObserverInstrument(NoopAsync{}, nil) return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64UpDownCounterObserverInstrument( return wrapInt64UpDownCounterObserverInstrument(
m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts,
@ -183,7 +206,7 @@ func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64Observer
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) { func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
if callback == nil { if callback == nil {
return wrapFloat64UpDownCounterObserverInstrument(NoopAsync{}, nil) return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64UpDownCounterObserverInstrument( return wrapFloat64UpDownCounterObserverInstrument(
m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts, m.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts,
@ -196,7 +219,7 @@ func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64Obse
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOption) (Int64GaugeObserver, error) { func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOption) (Int64GaugeObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapInt64GaugeObserverInstrument(NoopAsync{}, nil) return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64GaugeObserverInstrument( return wrapInt64GaugeObserverInstrument(
b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, b.runner)) b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Int64Kind, opts, b.runner))
@ -208,7 +231,7 @@ func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOpti
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOption) (Float64GaugeObserver, error) { func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOption) (Float64GaugeObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapFloat64GaugeObserverInstrument(NoopAsync{}, nil) return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64GaugeObserverInstrument( return wrapFloat64GaugeObserverInstrument(
b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts, b.meter.newAsync(name, sdkapi.GaugeObserverInstrumentKind, number.Float64Kind, opts,
@ -221,7 +244,7 @@ func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOp
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOption) (Int64CounterObserver, error) { func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOption) (Int64CounterObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapInt64CounterObserverInstrument(NoopAsync{}, nil) return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64CounterObserverInstrument( return wrapInt64CounterObserverInstrument(
b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, b.runner)) b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Int64Kind, opts, b.runner))
@ -233,7 +256,7 @@ func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOp
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...InstrumentOption) (Float64CounterObserver, error) { func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...InstrumentOption) (Float64CounterObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapFloat64CounterObserverInstrument(NoopAsync{}, nil) return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64CounterObserverInstrument( return wrapFloat64CounterObserverInstrument(
b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts, b.meter.newAsync(name, sdkapi.CounterObserverInstrumentKind, number.Float64Kind, opts,
@ -246,7 +269,7 @@ func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...Instrument
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) { func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapInt64UpDownCounterObserverInstrument(NoopAsync{}, nil) return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapInt64UpDownCounterObserverInstrument( return wrapInt64UpDownCounterObserverInstrument(
b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, b.runner)) b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Int64Kind, opts, b.runner))
@ -258,7 +281,7 @@ func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...Instru
// or improperly registered (e.g., duplicate registration). // or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) { func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
if b.runner == nil { if b.runner == nil {
return wrapFloat64UpDownCounterObserverInstrument(NoopAsync{}, nil) return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
} }
return wrapFloat64UpDownCounterObserverInstrument( return wrapFloat64UpDownCounterObserverInstrument(
b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts, b.meter.newAsync(name, sdkapi.UpDownCounterObserverInstrumentKind, number.Float64Kind, opts,
@ -266,7 +289,7 @@ func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...Inst
} }
// MeterImpl returns the underlying MeterImpl of this Meter. // MeterImpl returns the underlying MeterImpl of this Meter.
func (m Meter) MeterImpl() MeterImpl { func (m Meter) MeterImpl() sdkapi.MeterImpl {
return m.impl return m.impl
} }
@ -276,16 +299,16 @@ func (m Meter) newAsync(
mkind sdkapi.InstrumentKind, mkind sdkapi.InstrumentKind,
nkind number.Kind, nkind number.Kind,
opts []InstrumentOption, opts []InstrumentOption,
runner AsyncRunner, runner sdkapi.AsyncRunner,
) ( ) (
AsyncImpl, sdkapi.AsyncImpl,
error, error,
) { ) {
if m.impl == nil { if m.impl == nil {
return NoopAsync{}, nil return sdkapi.NewNoopAsyncInstrument(), nil
} }
cfg := NewInstrumentConfig(opts...) cfg := NewInstrumentConfig(opts...)
desc := NewDescriptor(name, mkind, nkind, cfg.description, cfg.unit) desc := sdkapi.NewDescriptor(name, mkind, nkind, cfg.description, cfg.unit)
return m.impl.NewAsyncInstrument(desc, runner) return m.impl.NewAsyncInstrument(desc, runner)
} }
@ -296,14 +319,14 @@ func (m Meter) newSync(
numberKind number.Kind, numberKind number.Kind,
opts []InstrumentOption, opts []InstrumentOption,
) ( ) (
SyncImpl, sdkapi.SyncImpl,
error, error,
) { ) {
if m.impl == nil { if m.impl == nil {
return NoopSync{}, nil return sdkapi.NewNoopSyncInstrument(), nil
} }
cfg := NewInstrumentConfig(opts...) cfg := NewInstrumentConfig(opts...)
desc := NewDescriptor(name, metricKind, numberKind, cfg.description, cfg.unit) desc := sdkapi.NewDescriptor(name, metricKind, numberKind, cfg.description, cfg.unit)
return m.impl.NewSyncInstrument(desc) return m.impl.NewSyncInstrument(desc)
} }
@ -513,53 +536,3 @@ func (bm BatchObserverMust) NewFloat64UpDownCounterObserver(name string, oos ...
return inst return inst
} }
} }
// Descriptor contains all the settings that describe an instrument,
// including its name, metric kind, number kind, and the configurable
// options.
type Descriptor struct {
name string
instrumentKind sdkapi.InstrumentKind
numberKind number.Kind
description string
unit unit.Unit
}
// NewDescriptor returns a Descriptor with the given contents.
func NewDescriptor(name string, ikind sdkapi.InstrumentKind, nkind number.Kind, description string, unit unit.Unit) Descriptor {
return Descriptor{
name: name,
instrumentKind: ikind,
numberKind: nkind,
description: description,
unit: unit,
}
}
// Name returns the metric instrument's name.
func (d Descriptor) Name() string {
return d.name
}
// InstrumentKind returns the specific kind of instrument.
func (d Descriptor) InstrumentKind() sdkapi.InstrumentKind {
return d.instrumentKind
}
// Description provides a human-readable description of the metric
// instrument.
func (d Descriptor) Description() string {
return d.description
}
// Unit describes the units of the metric instrument. Unitless
// metrics return the empty string.
func (d Descriptor) Unit() unit.Unit {
return d.unit
}
// NumberKind returns whether this instrument is declared over int64,
// float64, or uint64 values.
func (d Descriptor) NumberKind() number.Kind {
return d.numberKind
}

View File

@ -20,20 +20,12 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
) )
// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil. // ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation") var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation")
// Observation is used for reporting an asynchronous batch of metric
// values. Instances of this type should be created by asynchronous
// instruments (e.g., Int64GaugeObserver.Observation()).
type Observation struct {
// number needs to be aligned for 64-bit atomic operations.
number number.Number
instrument AsyncImpl
}
// Int64ObserverFunc is a type of callback that integral // Int64ObserverFunc is a type of callback that integral
// observers run. // observers run.
type Int64ObserverFunc func(context.Context, Int64ObserverResult) type Int64ObserverFunc func(context.Context, Int64ObserverResult)
@ -50,14 +42,14 @@ type BatchObserverFunc func(context.Context, BatchObserverResult)
// Int64ObserverResult is passed to an observer callback to capture // Int64ObserverResult is passed to an observer callback to capture
// observations for one asynchronous integer metric instrument. // observations for one asynchronous integer metric instrument.
type Int64ObserverResult struct { type Int64ObserverResult struct {
instrument AsyncImpl instrument sdkapi.AsyncImpl
function func([]attribute.KeyValue, ...Observation) function func([]attribute.KeyValue, ...Observation)
} }
// Float64ObserverResult is passed to an observer callback to capture // Float64ObserverResult is passed to an observer callback to capture
// observations for one asynchronous floating point metric instrument. // observations for one asynchronous floating point metric instrument.
type Float64ObserverResult struct { type Float64ObserverResult struct {
instrument AsyncImpl instrument sdkapi.AsyncImpl
function func([]attribute.KeyValue, ...Observation) function func([]attribute.KeyValue, ...Observation)
} }
@ -70,19 +62,13 @@ type BatchObserverResult struct {
// Observe captures a single integer value from the associated // Observe captures a single integer value from the associated
// instrument callback, with the given labels. // instrument callback, with the given labels.
func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) { func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) {
ir.function(labels, Observation{ ir.function(labels, sdkapi.NewObservation(ir.instrument, number.NewInt64Number(value)))
instrument: ir.instrument,
number: number.NewInt64Number(value),
})
} }
// Observe captures a single floating point value from the associated // Observe captures a single floating point value from the associated
// instrument callback, with the given labels. // instrument callback, with the given labels.
func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) { func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) {
fr.function(labels, Observation{ fr.function(labels, sdkapi.NewObservation(fr.instrument, number.NewFloat64Number(value)))
instrument: fr.instrument,
number: number.NewFloat64Number(value),
})
} }
// Observe captures a multiple observations from the associated batch // Observe captures a multiple observations from the associated batch
@ -91,54 +77,22 @@ func (br BatchObserverResult) Observe(labels []attribute.KeyValue, obs ...Observ
br.function(labels, obs...) br.function(labels, obs...)
} }
// AsyncRunner is expected to convert into an AsyncSingleRunner or an var _ sdkapi.AsyncSingleRunner = (*Int64ObserverFunc)(nil)
// AsyncBatchRunner. SDKs will encounter an error if the AsyncRunner var _ sdkapi.AsyncSingleRunner = (*Float64ObserverFunc)(nil)
// does not satisfy one of these interfaces. var _ sdkapi.AsyncBatchRunner = (*BatchObserverFunc)(nil)
type AsyncRunner interface {
// AnyRunner() is a non-exported method with no functional use
// other than to make this a non-empty interface.
AnyRunner()
}
// AsyncSingleRunner is an interface implemented by single-observer
// callbacks.
type AsyncSingleRunner interface {
// Run accepts a single instrument and function for capturing
// observations of that instrument. Each call to the function
// receives one captured observation. (The function accepts
// multiple observations so the same implementation can be
// used for batch runners.)
Run(ctx context.Context, single AsyncImpl, capture func([]attribute.KeyValue, ...Observation))
AsyncRunner
}
// AsyncBatchRunner is an interface implemented by batch-observer
// callbacks.
type AsyncBatchRunner interface {
// Run accepts a function for capturing observations of
// multiple instruments.
Run(ctx context.Context, capture func([]attribute.KeyValue, ...Observation))
AsyncRunner
}
var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil)
var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil)
var _ AsyncBatchRunner = (*BatchObserverFunc)(nil)
// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments. // newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner { func newInt64AsyncRunner(c Int64ObserverFunc) sdkapi.AsyncSingleRunner {
return &c return &c
} }
// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments. // newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner { func newFloat64AsyncRunner(c Float64ObserverFunc) sdkapi.AsyncSingleRunner {
return &c return &c
} }
// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments. // newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner { func newBatchAsyncRunner(c BatchObserverFunc) sdkapi.AsyncBatchRunner {
return &c return &c
} }
@ -152,7 +106,7 @@ func (*Float64ObserverFunc) AnyRunner() {}
func (*BatchObserverFunc) AnyRunner() {} func (*BatchObserverFunc) AnyRunner() {}
// Run implements AsyncSingleRunner. // Run implements AsyncSingleRunner.
func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { func (i *Int64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) {
(*i)(ctx, Int64ObserverResult{ (*i)(ctx, Int64ObserverResult{
instrument: impl, instrument: impl,
function: function, function: function,
@ -160,7 +114,7 @@ func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function fu
} }
// Run implements AsyncSingleRunner. // Run implements AsyncSingleRunner.
func (f *Float64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]attribute.KeyValue, ...Observation)) { func (f *Float64ObserverFunc) Run(ctx context.Context, impl sdkapi.AsyncImpl, function func([]attribute.KeyValue, ...Observation)) {
(*f)(ctx, Float64ObserverResult{ (*f)(ctx, Float64ObserverResult{
instrument: impl, instrument: impl,
function: function, function: function,
@ -175,37 +129,37 @@ func (b *BatchObserverFunc) Run(ctx context.Context, function func([]attribute.K
} }
// wrapInt64GaugeObserverInstrument converts an AsyncImpl into Int64GaugeObserver. // wrapInt64GaugeObserverInstrument converts an AsyncImpl into Int64GaugeObserver.
func wrapInt64GaugeObserverInstrument(asyncInst AsyncImpl, err error) (Int64GaugeObserver, error) { func wrapInt64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64GaugeObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Int64GaugeObserver{asyncInstrument: common}, err return Int64GaugeObserver{asyncInstrument: common}, err
} }
// wrapFloat64GaugeObserverInstrument converts an AsyncImpl into Float64GaugeObserver. // wrapFloat64GaugeObserverInstrument converts an AsyncImpl into Float64GaugeObserver.
func wrapFloat64GaugeObserverInstrument(asyncInst AsyncImpl, err error) (Float64GaugeObserver, error) { func wrapFloat64GaugeObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64GaugeObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Float64GaugeObserver{asyncInstrument: common}, err return Float64GaugeObserver{asyncInstrument: common}, err
} }
// wrapInt64CounterObserverInstrument converts an AsyncImpl into Int64CounterObserver. // wrapInt64CounterObserverInstrument converts an AsyncImpl into Int64CounterObserver.
func wrapInt64CounterObserverInstrument(asyncInst AsyncImpl, err error) (Int64CounterObserver, error) { func wrapInt64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64CounterObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Int64CounterObserver{asyncInstrument: common}, err return Int64CounterObserver{asyncInstrument: common}, err
} }
// wrapFloat64CounterObserverInstrument converts an AsyncImpl into Float64CounterObserver. // wrapFloat64CounterObserverInstrument converts an AsyncImpl into Float64CounterObserver.
func wrapFloat64CounterObserverInstrument(asyncInst AsyncImpl, err error) (Float64CounterObserver, error) { func wrapFloat64CounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64CounterObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Float64CounterObserver{asyncInstrument: common}, err return Float64CounterObserver{asyncInstrument: common}, err
} }
// wrapInt64UpDownCounterObserverInstrument converts an AsyncImpl into Int64UpDownCounterObserver. // wrapInt64UpDownCounterObserverInstrument converts an AsyncImpl into Int64UpDownCounterObserver.
func wrapInt64UpDownCounterObserverInstrument(asyncInst AsyncImpl, err error) (Int64UpDownCounterObserver, error) { func wrapInt64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Int64UpDownCounterObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Int64UpDownCounterObserver{asyncInstrument: common}, err return Int64UpDownCounterObserver{asyncInstrument: common}, err
} }
// wrapFloat64UpDownCounterObserverInstrument converts an AsyncImpl into Float64UpDownCounterObserver. // wrapFloat64UpDownCounterObserverInstrument converts an AsyncImpl into Float64UpDownCounterObserver.
func wrapFloat64UpDownCounterObserverInstrument(asyncInst AsyncImpl, err error) (Float64UpDownCounterObserver, error) { func wrapFloat64UpDownCounterObserverInstrument(asyncInst sdkapi.AsyncImpl, err error) (Float64UpDownCounterObserver, error) {
common, err := checkNewAsync(asyncInst, err) common, err := checkNewAsync(asyncInst, err)
return Float64UpDownCounterObserver{asyncInstrument: common}, err return Float64UpDownCounterObserver{asyncInstrument: common}, err
} }
@ -214,7 +168,7 @@ func wrapFloat64UpDownCounterObserverInstrument(asyncInst AsyncImpl, err error)
// observations for multiple instruments. // observations for multiple instruments.
type BatchObserver struct { type BatchObserver struct {
meter Meter meter Meter
runner AsyncBatchRunner runner sdkapi.AsyncBatchRunner
} }
// Int64GaugeObserver is a metric that captures a set of int64 values at a // Int64GaugeObserver is a metric that captures a set of int64 values at a
@ -258,10 +212,7 @@ type Float64UpDownCounterObserver struct {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (i Int64GaugeObserver) Observation(v int64) Observation { func (i Int64GaugeObserver) Observation(v int64) Observation {
return Observation{ return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
number: number.NewInt64Number(v),
instrument: i.instrument,
}
} }
// Observation returns an Observation, a BatchObserverFunc // Observation returns an Observation, a BatchObserverFunc
@ -269,10 +220,7 @@ func (i Int64GaugeObserver) Observation(v int64) Observation {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (f Float64GaugeObserver) Observation(v float64) Observation { func (f Float64GaugeObserver) Observation(v float64) Observation {
return Observation{ return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
number: number.NewFloat64Number(v),
instrument: f.instrument,
}
} }
// Observation returns an Observation, a BatchObserverFunc // Observation returns an Observation, a BatchObserverFunc
@ -280,10 +228,7 @@ func (f Float64GaugeObserver) Observation(v float64) Observation {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (i Int64CounterObserver) Observation(v int64) Observation { func (i Int64CounterObserver) Observation(v int64) Observation {
return Observation{ return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
number: number.NewInt64Number(v),
instrument: i.instrument,
}
} }
// Observation returns an Observation, a BatchObserverFunc // Observation returns an Observation, a BatchObserverFunc
@ -291,10 +236,7 @@ func (i Int64CounterObserver) Observation(v int64) Observation {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (f Float64CounterObserver) Observation(v float64) Observation { func (f Float64CounterObserver) Observation(v float64) Observation {
return Observation{ return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
number: number.NewFloat64Number(v),
instrument: f.instrument,
}
} }
// Observation returns an Observation, a BatchObserverFunc // Observation returns an Observation, a BatchObserverFunc
@ -302,10 +244,7 @@ func (f Float64CounterObserver) Observation(v float64) Observation {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (i Int64UpDownCounterObserver) Observation(v int64) Observation { func (i Int64UpDownCounterObserver) Observation(v int64) Observation {
return Observation{ return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
number: number.NewInt64Number(v),
instrument: i.instrument,
}
} }
// Observation returns an Observation, a BatchObserverFunc // Observation returns an Observation, a BatchObserverFunc
@ -313,67 +252,31 @@ func (i Int64UpDownCounterObserver) Observation(v int64) Observation {
// This returns an implementation-level object for use by the SDK, // This returns an implementation-level object for use by the SDK,
// users should not refer to this. // users should not refer to this.
func (f Float64UpDownCounterObserver) Observation(v float64) Observation { func (f Float64UpDownCounterObserver) Observation(v float64) Observation {
return Observation{ return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
number: number.NewFloat64Number(v),
instrument: f.instrument,
}
}
// Measurement is used for reporting a synchronous batch of metric
// values. Instances of this type should be created by synchronous
// instruments (e.g., Int64Counter.Measurement()).
type Measurement struct {
// number needs to be aligned for 64-bit atomic operations.
number number.Number
instrument SyncImpl
} }
// syncInstrument contains a SyncImpl. // syncInstrument contains a SyncImpl.
type syncInstrument struct { type syncInstrument struct {
instrument SyncImpl instrument sdkapi.SyncImpl
} }
// syncBoundInstrument contains a BoundSyncImpl. // syncBoundInstrument contains a BoundSyncImpl.
type syncBoundInstrument struct { type syncBoundInstrument struct {
boundInstrument BoundSyncImpl boundInstrument sdkapi.BoundSyncImpl
} }
// asyncInstrument contains a AsyncImpl. // asyncInstrument contains a AsyncImpl.
type asyncInstrument struct { type asyncInstrument struct {
instrument AsyncImpl instrument sdkapi.AsyncImpl
}
// SyncImpl returns the instrument that created this measurement.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (m Measurement) SyncImpl() SyncImpl {
return m.instrument
}
// Number returns a number recorded in this measurement.
func (m Measurement) Number() number.Number {
return m.number
}
// AsyncImpl returns the instrument that created this observation.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (m Observation) AsyncImpl() AsyncImpl {
return m.instrument
}
// Number returns a number recorded in this observation.
func (m Observation) Number() number.Number {
return m.number
} }
// AsyncImpl implements AsyncImpl. // AsyncImpl implements AsyncImpl.
func (a asyncInstrument) AsyncImpl() AsyncImpl { func (a asyncInstrument) AsyncImpl() sdkapi.AsyncImpl {
return a.instrument return a.instrument
} }
// SyncImpl returns the implementation object for synchronous instruments. // SyncImpl returns the implementation object for synchronous instruments.
func (s syncInstrument) SyncImpl() SyncImpl { func (s syncInstrument) SyncImpl() sdkapi.SyncImpl {
return s.instrument return s.instrument
} }
@ -382,11 +285,11 @@ func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument {
} }
func (s syncInstrument) float64Measurement(value float64) Measurement { func (s syncInstrument) float64Measurement(value float64) Measurement {
return newMeasurement(s.instrument, number.NewFloat64Number(value)) return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value))
} }
func (s syncInstrument) int64Measurement(value int64) Measurement { func (s syncInstrument) int64Measurement(value int64) Measurement {
return newMeasurement(s.instrument, number.NewInt64Number(value)) return sdkapi.NewMeasurement(s.instrument, number.NewInt64Number(value))
} }
func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []attribute.KeyValue) { func (s syncInstrument) directRecord(ctx context.Context, number number.Number, labels []attribute.KeyValue) {
@ -405,12 +308,12 @@ func (h syncBoundInstrument) Unbind() {
// checkNewAsync receives an AsyncImpl and potential // checkNewAsync receives an AsyncImpl and potential
// error, and returns the same types, checking for and ensuring that // error, and returns the same types, checking for and ensuring that
// the returned interface is not nil. // the returned interface is not nil.
func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) { func checkNewAsync(instrument sdkapi.AsyncImpl, err error) (asyncInstrument, error) {
if instrument == nil { if instrument == nil {
if err == nil { if err == nil {
err = ErrSDKReturnedNilImpl err = ErrSDKReturnedNilImpl
} }
instrument = NoopAsync{} instrument = sdkapi.NewNoopAsyncInstrument()
} }
return asyncInstrument{ return asyncInstrument{
instrument: instrument, instrument: instrument,
@ -420,7 +323,7 @@ func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) {
// checkNewSync receives an SyncImpl and potential // checkNewSync receives an SyncImpl and potential
// error, and returns the same types, checking for and ensuring that // error, and returns the same types, checking for and ensuring that
// the returned interface is not nil. // the returned interface is not nil.
func checkNewSync(instrument SyncImpl, err error) (syncInstrument, error) { func checkNewSync(instrument sdkapi.SyncImpl, err error) (syncInstrument, error) {
if instrument == nil { if instrument == nil {
if err == nil { if err == nil {
err = ErrSDKReturnedNilImpl err = ErrSDKReturnedNilImpl
@ -430,58 +333,51 @@ func checkNewSync(instrument SyncImpl, err error) (syncInstrument, error) {
// together and use a tag for the original name, e.g., // together and use a tag for the original name, e.g.,
// name = 'invalid.counter.int64' // name = 'invalid.counter.int64'
// label = 'original-name=duplicate-counter-name' // label = 'original-name=duplicate-counter-name'
instrument = NoopSync{} instrument = sdkapi.NewNoopSyncInstrument()
} }
return syncInstrument{ return syncInstrument{
instrument: instrument, instrument: instrument,
}, err }, err
} }
func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument { func newSyncBoundInstrument(boundInstrument sdkapi.BoundSyncImpl) syncBoundInstrument {
return syncBoundInstrument{ return syncBoundInstrument{
boundInstrument: boundInstrument, boundInstrument: boundInstrument,
} }
} }
func newMeasurement(instrument SyncImpl, number number.Number) Measurement {
return Measurement{
instrument: instrument,
number: number,
}
}
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter. // wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
func wrapInt64CounterInstrument(syncInst SyncImpl, err error) (Int64Counter, error) { func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Int64Counter{syncInstrument: common}, err return Int64Counter{syncInstrument: common}, err
} }
// wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter. // wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter.
func wrapFloat64CounterInstrument(syncInst SyncImpl, err error) (Float64Counter, error) { func wrapFloat64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Counter, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Float64Counter{syncInstrument: common}, err return Float64Counter{syncInstrument: common}, err
} }
// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter. // wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter.
func wrapInt64UpDownCounterInstrument(syncInst SyncImpl, err error) (Int64UpDownCounter, error) { func wrapInt64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64UpDownCounter, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Int64UpDownCounter{syncInstrument: common}, err return Int64UpDownCounter{syncInstrument: common}, err
} }
// wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter. // wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter.
func wrapFloat64UpDownCounterInstrument(syncInst SyncImpl, err error) (Float64UpDownCounter, error) { func wrapFloat64UpDownCounterInstrument(syncInst sdkapi.SyncImpl, err error) (Float64UpDownCounter, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Float64UpDownCounter{syncInstrument: common}, err return Float64UpDownCounter{syncInstrument: common}, err
} }
// wrapInt64HistogramInstrument converts a SyncImpl into Int64Histogram. // wrapInt64HistogramInstrument converts a SyncImpl into Int64Histogram.
func wrapInt64HistogramInstrument(syncInst SyncImpl, err error) (Int64Histogram, error) { func wrapInt64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Histogram, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Int64Histogram{syncInstrument: common}, err return Int64Histogram{syncInstrument: common}, err
} }
// wrapFloat64HistogramInstrument converts a SyncImpl into Float64Histogram. // wrapFloat64HistogramInstrument converts a SyncImpl into Float64Histogram.
func wrapFloat64HistogramInstrument(syncInst SyncImpl, err error) (Float64Histogram, error) { func wrapFloat64HistogramInstrument(syncInst sdkapi.SyncImpl, err error) (Float64Histogram, error) {
common, err := checkNewSync(syncInst, err) common, err := checkNewSync(syncInst, err)
return Float64Histogram{syncInstrument: common}, err return Float64Histogram{syncInstrument: common}, err
} }

View File

@ -1,93 +0,0 @@
// Copyright The 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 "go.opentelemetry.io/otel/metric"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number"
)
// MeterImpl is the interface an SDK must implement to supply a Meter
// implementation.
type MeterImpl interface {
// RecordBatch atomically records a batch of measurements.
RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurement ...Measurement)
// NewSyncInstrument returns a newly constructed
// synchronous instrument implementation or an error, should
// one occur.
NewSyncInstrument(descriptor Descriptor) (SyncImpl, error)
// NewAsyncInstrument returns a newly constructed
// asynchronous instrument implementation or an error, should
// one occur.
NewAsyncInstrument(
descriptor Descriptor,
runner AsyncRunner,
) (AsyncImpl, error)
}
// InstrumentImpl is a common interface for synchronous and
// asynchronous instruments.
type InstrumentImpl interface {
// Implementation returns the underlying implementation of the
// instrument, which allows the implementation to gain access
// to its own representation especially from a `Measurement`.
Implementation() interface{}
// Descriptor returns a copy of the instrument's Descriptor.
Descriptor() Descriptor
}
// SyncImpl is the implementation-level interface to a generic
// synchronous instrument (e.g., Histogram and Counter instruments).
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 {
InstrumentImpl
}
// WrapMeterImpl constructs a `Meter` implementation from a
// `MeterImpl` implementation.
func WrapMeterImpl(impl MeterImpl) Meter {
return Meter{
impl: impl,
}
}

View File

@ -120,7 +120,7 @@ func TestPrecomputedSum(t *testing.T) {
} }
} }
func checkSyncBatches(ctx context.Context, t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, instrument metric.InstrumentImpl, expected ...float64) { func checkSyncBatches(ctx context.Context, t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, instrument sdkapi.InstrumentImpl, expected ...float64) {
t.Helper() t.Helper()
batchesCount := len(provider.MeasurementBatches) batchesCount := len(provider.MeasurementBatches)
@ -442,7 +442,7 @@ func TestBatchObserverInstruments(t *testing.T) {
require.Equal(t, 0, m2.Number.CompareNumber(number.Float64Kind, metrictest.ResolveNumberByKind(t, number.Float64Kind, 42))) require.Equal(t, 0, m2.Number.CompareNumber(number.Float64Kind, metrictest.ResolveNumberByKind(t, number.Float64Kind, 42)))
} }
func checkObserverBatch(t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, observer metric.AsyncImpl, expected float64) { func checkObserverBatch(t *testing.T, labels []attribute.KeyValue, provider *metrictest.MeterProvider, nkind number.Kind, mkind sdkapi.InstrumentKind, observer sdkapi.AsyncImpl, expected float64) {
t.Helper() t.Helper()
assert.Len(t, provider.MeasurementBatches, 1) assert.Len(t, provider.MeasurementBatches, 1)
if len(provider.MeasurementBatches) < 1 { if len(provider.MeasurementBatches) < 1 {
@ -468,16 +468,16 @@ func checkObserverBatch(t *testing.T, labels []attribute.KeyValue, provider *met
type testWrappedMeter struct { type testWrappedMeter struct {
} }
var _ metric.MeterImpl = testWrappedMeter{} var _ sdkapi.MeterImpl = testWrappedMeter{}
func (testWrappedMeter) RecordBatch(context.Context, []attribute.KeyValue, ...metric.Measurement) { func (testWrappedMeter) RecordBatch(context.Context, []attribute.KeyValue, ...sdkapi.Measurement) {
} }
func (testWrappedMeter) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) { func (testWrappedMeter) NewSyncInstrument(_ sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
return nil, nil return nil, nil
} }
func (testWrappedMeter) NewAsyncInstrument(_ metric.Descriptor, _ metric.AsyncRunner) (metric.AsyncImpl, error) { func (testWrappedMeter) NewAsyncInstrument(_ sdkapi.Descriptor, _ sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
return nil, errors.New("Test wrap error") return nil, errors.New("Test wrap error")
} }
@ -502,6 +502,8 @@ func TestNilCallbackObserverNoop(t *testing.T) {
observer := Must(meter).NewInt64GaugeObserver("test.observer", nil) observer := Must(meter).NewInt64GaugeObserver("test.observer", nil)
_, ok := observer.AsyncImpl().(metric.NoopAsync) impl := observer.AsyncImpl().Implementation()
require.True(t, ok) desc := observer.AsyncImpl().Descriptor()
require.Equal(t, nil, impl)
require.Equal(t, "", desc.Name())
} }

View File

@ -66,18 +66,18 @@ type (
Measurement struct { Measurement struct {
// Number needs to be aligned for 64-bit atomic operations. // Number needs to be aligned for 64-bit atomic operations.
Number number.Number Number number.Number
Instrument metric.InstrumentImpl Instrument sdkapi.InstrumentImpl
} }
Instrument struct { Instrument struct {
meter *MeterImpl meter *MeterImpl
descriptor metric.Descriptor descriptor sdkapi.Descriptor
} }
Async struct { Async struct {
Instrument Instrument
runner metric.AsyncRunner runner sdkapi.AsyncRunner
} }
Sync struct { Sync struct {
@ -86,20 +86,20 @@ type (
) )
var ( var (
_ metric.SyncImpl = &Sync{} _ sdkapi.SyncImpl = &Sync{}
_ metric.BoundSyncImpl = &Handle{} _ sdkapi.BoundSyncImpl = &Handle{}
_ metric.MeterImpl = &MeterImpl{} _ sdkapi.MeterImpl = &MeterImpl{}
_ metric.AsyncImpl = &Async{} _ sdkapi.AsyncImpl = &Async{}
) )
// NewDescriptor is a test helper for constructing test metric // NewDescriptor is a test helper for constructing test metric
// descriptors using standard options. // descriptors using standard options.
func NewDescriptor(name string, ikind sdkapi.InstrumentKind, nkind number.Kind, opts ...metric.InstrumentOption) metric.Descriptor { func NewDescriptor(name string, ikind sdkapi.InstrumentKind, nkind number.Kind, opts ...metric.InstrumentOption) sdkapi.Descriptor {
cfg := metric.NewInstrumentConfig(opts...) cfg := metric.NewInstrumentConfig(opts...)
return metric.NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit()) return sdkapi.NewDescriptor(name, ikind, nkind, cfg.Description(), cfg.Unit())
} }
func (i Instrument) Descriptor() metric.Descriptor { func (i Instrument) Descriptor() sdkapi.Descriptor {
return i.descriptor return i.descriptor
} }
@ -111,7 +111,7 @@ func (s *Sync) Implementation() interface{} {
return s return s
} }
func (s *Sync) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl { func (s *Sync) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
return &Handle{ return &Handle{
Instrument: s, Instrument: s,
Labels: labels, Labels: labels,
@ -129,7 +129,7 @@ func (h *Handle) RecordOne(ctx context.Context, number number.Number) {
func (h *Handle) Unbind() { func (h *Handle) Unbind() {
} }
func (m *MeterImpl) doRecordSingle(ctx context.Context, labels []attribute.KeyValue, instrument metric.InstrumentImpl, number number.Number) { func (m *MeterImpl) doRecordSingle(ctx context.Context, labels []attribute.KeyValue, instrument sdkapi.InstrumentImpl, number number.Number) {
m.collect(ctx, labels, []Measurement{{ m.collect(ctx, labels, []Measurement{{
Instrument: instrument, Instrument: instrument,
Number: number, Number: number,
@ -160,8 +160,8 @@ func (p *MeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Me
return metric.WrapMeterImpl(impl) return metric.WrapMeterImpl(impl)
} }
// NewSyncInstrument implements metric.MeterImpl. // NewSyncInstrument implements sdkapi.MeterImpl.
func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) { func (m *MeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
return &Sync{ return &Sync{
Instrument{ Instrument{
descriptor: descriptor, descriptor: descriptor,
@ -170,8 +170,8 @@ func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.Sync
}, nil }, nil
} }
// NewAsyncInstrument implements metric.MeterImpl. // NewAsyncInstrument implements sdkapi.MeterImpl.
func (m *MeterImpl) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (metric.AsyncImpl, error) { func (m *MeterImpl) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
a := &Async{ a := &Async{
Instrument: Instrument{ Instrument: Instrument{
descriptor: descriptor, descriptor: descriptor,
@ -183,8 +183,8 @@ func (m *MeterImpl) NewAsyncInstrument(descriptor metric.Descriptor, runner metr
return a, nil return a, nil
} }
// RecordBatch implements metric.MeterImpl. // RecordBatch implements sdkapi.MeterImpl.
func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...metric.Measurement) { func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
mm := make([]Measurement, len(measurements)) mm := make([]Measurement, len(measurements))
for i := 0; i < len(measurements); i++ { for i := 0; i < len(measurements); i++ {
m := measurements[i] m := measurements[i]
@ -197,7 +197,7 @@ func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue
} }
// CollectAsync is called from asyncInstruments.Run() with the lock held. // CollectAsync is called from asyncInstruments.Run() with the lock held.
func (m *MeterImpl) CollectAsync(labels []attribute.KeyValue, obs ...metric.Observation) { func (m *MeterImpl) CollectAsync(labels []attribute.KeyValue, obs ...sdkapi.Observation) {
mm := make([]Measurement, len(obs)) mm := make([]Measurement, len(obs))
for i := 0; i < len(obs); i++ { for i := 0; i < len(obs); i++ {
o := obs[i] o := obs[i]
@ -220,7 +220,7 @@ func (m *MeterImpl) collect(ctx context.Context, labels []attribute.KeyValue, me
} }
// registerAsyncInstrument locks the provider and registers the new Async instrument. // registerAsyncInstrument locks the provider and registers the new Async instrument.
func (p *MeterProvider) registerAsyncInstrument(a *Async, m *MeterImpl, runner metric.AsyncRunner) { func (p *MeterProvider) registerAsyncInstrument(a *Async, m *MeterImpl, runner sdkapi.AsyncRunner) {
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()

View File

@ -14,12 +14,7 @@
package metric // import "go.opentelemetry.io/otel/metric" package metric // import "go.opentelemetry.io/otel/metric"
import ( type noopMeterProvider struct{}
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number"
)
// NewNoopMeterProvider returns an implementation of MeterProvider that // NewNoopMeterProvider returns an implementation of MeterProvider that
// performs no operations. The Meter and Instrument created from the returned // performs no operations. The Meter and Instrument created from the returned
@ -28,39 +23,8 @@ func NewNoopMeterProvider() MeterProvider {
return noopMeterProvider{} return noopMeterProvider{}
} }
type noopMeterProvider struct{}
type noopInstrument struct{}
type noopBoundInstrument struct{}
type NoopSync struct{ noopInstrument }
type NoopAsync struct{ noopInstrument }
var _ MeterProvider = noopMeterProvider{} var _ MeterProvider = noopMeterProvider{}
var _ SyncImpl = NoopSync{}
var _ BoundSyncImpl = noopBoundInstrument{}
var _ AsyncImpl = NoopAsync{}
func (noopMeterProvider) Meter(instrumentationName string, opts ...MeterOption) Meter { func (noopMeterProvider) Meter(instrumentationName string, opts ...MeterOption) Meter {
return Meter{} return Meter{}
} }
func (noopInstrument) Implementation() interface{} {
return nil
}
func (noopInstrument) Descriptor() Descriptor {
return Descriptor{}
}
func (noopBoundInstrument) RecordOne(context.Context, number.Number) {
}
func (noopBoundInstrument) Unbind() {
}
func (NoopSync) Bind([]attribute.KeyValue) BoundSyncImpl {
return noopBoundInstrument{}
}
func (NoopSync) RecordOne(context.Context, number.Number, []attribute.KeyValue) {
}

View File

@ -0,0 +1,70 @@
// Copyright The 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 sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
import (
"go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/unit"
)
// Descriptor contains all the settings that describe an instrument,
// including its name, metric kind, number kind, and the configurable
// options.
type Descriptor struct {
name string
instrumentKind InstrumentKind
numberKind number.Kind
description string
unit unit.Unit
}
// NewDescriptor returns a Descriptor with the given contents.
func NewDescriptor(name string, ikind InstrumentKind, nkind number.Kind, description string, unit unit.Unit) Descriptor {
return Descriptor{
name: name,
instrumentKind: ikind,
numberKind: nkind,
description: description,
unit: unit,
}
}
// Name returns the metric instrument's name.
func (d Descriptor) Name() string {
return d.name
}
// InstrumentKind returns the specific kind of instrument.
func (d Descriptor) InstrumentKind() InstrumentKind {
return d.instrumentKind
}
// Description provides a human-readable description of the metric
// instrument.
func (d Descriptor) Description() string {
return d.description
}
// Unit describes the units of the metric instrument. Unitless
// metrics return the empty string.
func (d Descriptor) Unit() unit.Unit {
return d.unit
}
// NumberKind returns whether this instrument is declared over int64,
// float64, or uint64 values.
func (d Descriptor) NumberKind() number.Kind {
return d.numberKind
}

View File

@ -12,27 +12,22 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package metric package sdkapi
import ( import (
"os"
"testing" "testing"
"unsafe"
"go.opentelemetry.io/otel/internal/internaltest" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/unit"
) )
// Ensure struct alignment prior to running tests. func TestDescriptorGetters(t *testing.T) {
func TestMain(m *testing.M) { d := NewDescriptor("name", HistogramInstrumentKind, number.Int64Kind, "my description", "my unit")
fields := []internaltest.FieldOffset{ require.Equal(t, "name", d.Name())
{ require.Equal(t, HistogramInstrumentKind, d.InstrumentKind())
Name: "Measurement.number", require.Equal(t, number.Int64Kind, d.NumberKind())
Offset: unsafe.Offsetof(Measurement{}.number), require.Equal(t, "my description", d.Description())
}, require.Equal(t, unit.Unit("my unit"), d.Unit())
}
if !internaltest.Aligned8Byte(fields, os.Stderr) {
os.Exit(1)
}
os.Exit(m.Run())
} }

64
metric/sdkapi/noop.go Normal file
View File

@ -0,0 +1,64 @@
// Copyright The 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 sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number"
)
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
// synchronous instrument interface.
func NewNoopSyncInstrument() SyncImpl {
return noopSyncInstrument{}
}
// NewNoopSyncInstrument returns a No-op implementation of the
// asynchronous instrument interface.
func NewNoopAsyncInstrument() SyncImpl {
return noopSyncInstrument{}
}
func (noopInstrument) Implementation() interface{} {
return nil
}
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) {
}

175
metric/sdkapi/sdkapi.go Normal file
View File

@ -0,0 +1,175 @@
// Copyright The 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 sdkapi // import "go.opentelemetry.io/otel/metric/sdkapi"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/number"
)
// MeterImpl is the interface an SDK must implement to supply a Meter
// implementation.
type MeterImpl interface {
// RecordBatch atomically records a batch of measurements.
RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurement ...Measurement)
// NewSyncInstrument returns a newly constructed
// synchronous instrument implementation or an error, should
// one occur.
NewSyncInstrument(descriptor Descriptor) (SyncImpl, error)
// NewAsyncInstrument returns a newly constructed
// asynchronous instrument implementation or an error, should
// one occur.
NewAsyncInstrument(
descriptor Descriptor,
runner AsyncRunner,
) (AsyncImpl, error)
}
// InstrumentImpl is a common interface for synchronous and
// asynchronous instruments.
type InstrumentImpl interface {
// Implementation returns the underlying implementation of the
// instrument, which allows the implementation to gain access
// to its own representation especially from a `Measurement`.
Implementation() interface{}
// Descriptor returns a copy of the instrument's Descriptor.
Descriptor() Descriptor
}
// SyncImpl is the implementation-level interface to a generic
// synchronous instrument (e.g., Histogram and Counter instruments).
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 {
InstrumentImpl
}
// AsyncRunner is expected to convert into an AsyncSingleRunner or an
// AsyncBatchRunner. SDKs will encounter an error if the AsyncRunner
// does not satisfy one of these interfaces.
type AsyncRunner interface {
// AnyRunner() is a non-exported method with no functional use
// other than to make this a non-empty interface.
AnyRunner()
}
// AsyncSingleRunner is an interface implemented by single-observer
// callbacks.
type AsyncSingleRunner interface {
// Run accepts a single instrument and function for capturing
// observations of that instrument. Each call to the function
// receives one captured observation. (The function accepts
// multiple observations so the same implementation can be
// used for batch runners.)
Run(ctx context.Context, single AsyncImpl, capture func([]attribute.KeyValue, ...Observation))
AsyncRunner
}
// AsyncBatchRunner is an interface implemented by batch-observer
// callbacks.
type AsyncBatchRunner interface {
// Run accepts a function for capturing observations of
// multiple instruments.
Run(ctx context.Context, capture func([]attribute.KeyValue, ...Observation))
AsyncRunner
}
// NewMeasurement constructs a single observation, a binding between
// an asynchronous instrument and a number.
func NewMeasurement(instrument SyncImpl, number number.Number) Measurement {
return Measurement{
instrument: instrument,
number: number,
}
}
// Measurement is a low-level type used with synchronous instruments
// as a direct interface to the SDK via `RecordBatch`.
type Measurement struct {
// number needs to be aligned for 64-bit atomic operations.
number number.Number
instrument SyncImpl
}
// SyncImpl returns the instrument that created this measurement.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (m Measurement) SyncImpl() SyncImpl {
return m.instrument
}
// Number returns a number recorded in this measurement.
func (m Measurement) Number() number.Number {
return m.number
}
// NewObservation constructs a single observation, a binding between
// an asynchronous instrument and a number.
func NewObservation(instrument AsyncImpl, number number.Number) Observation {
return Observation{
instrument: instrument,
number: number,
}
}
// Observation is a low-level type used with asynchronous instruments
// as a direct interface to the SDK via `BatchObserver`.
type Observation struct {
// number needs to be aligned for 64-bit atomic operations.
number number.Number
instrument AsyncImpl
}
// AsyncImpl returns the instrument that created this observation.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (m Observation) AsyncImpl() AsyncImpl {
return m.instrument
}
// Number returns a number recorded in this observation.
func (m Observation) Number() number.Number {
return m.number
}

View File

@ -0,0 +1,41 @@
// Copyright The 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 sdkapi
import (
"testing"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric/number"
)
func TestMeasurementGetters(t *testing.T) {
num := number.NewFloat64Number(1.5)
si := NewNoopSyncInstrument()
meas := NewMeasurement(si, num)
require.Equal(t, si, meas.SyncImpl())
require.Equal(t, num, meas.Number())
}
func TestObservationGetters(t *testing.T) {
num := number.NewFloat64Number(1.5)
ai := NewNoopAsyncInstrument()
obs := NewObservation(ai, num)
require.Equal(t, ai, obs.AsyncImpl())
require.Equal(t, num, obs.Number())
}

View File

@ -22,7 +22,6 @@ import (
"time" "time"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -97,7 +96,7 @@ type AggregatorSelector interface {
// Note: This is context-free because the aggregator should // Note: This is context-free because the aggregator should
// not relate to the incoming context. This call should not // not relate to the incoming context. This call should not
// block. // block.
AggregatorFor(descriptor *metric.Descriptor, aggregator ...*Aggregator) AggregatorFor(descriptor *sdkapi.Descriptor, aggregator ...*Aggregator)
} }
// Checkpointer is the interface used by a Controller to coordinate // Checkpointer is the interface used by a Controller to coordinate
@ -161,7 +160,7 @@ type Aggregator interface {
// //
// The Context argument comes from user-level code and could be // The Context argument comes from user-level code and could be
// inspected for a `correlation.Map` or `trace.SpanContext`. // inspected for a `correlation.Map` or `trace.SpanContext`.
Update(ctx context.Context, number number.Number, descriptor *metric.Descriptor) error Update(ctx context.Context, number number.Number, descriptor *sdkapi.Descriptor) error
// SynchronizedMove is called during collection to finish one // SynchronizedMove is called during collection to finish one
// period of aggregation by atomically saving the // period of aggregation by atomically saving the
@ -185,7 +184,7 @@ type Aggregator interface {
// //
// When called with a nil `destination`, this Aggregator is reset // When called with a nil `destination`, this Aggregator is reset
// and the current value is discarded. // and the current value is discarded.
SynchronizedMove(destination Aggregator, descriptor *metric.Descriptor) error SynchronizedMove(destination Aggregator, descriptor *sdkapi.Descriptor) error
// Merge combines the checkpointed state from the argument // Merge combines the checkpointed state from the argument
// Aggregator into this Aggregator. Merge is not synchronized // Aggregator into this Aggregator. Merge is not synchronized
@ -193,7 +192,7 @@ type Aggregator interface {
// //
// The owner of an Aggregator being merged is responsible for // The owner of an Aggregator being merged is responsible for
// synchronization of both Aggregator states. // synchronization of both Aggregator states.
Merge(aggregator Aggregator, descriptor *metric.Descriptor) error Merge(aggregator Aggregator, descriptor *sdkapi.Descriptor) error
} }
// Subtractor is an optional interface implemented by some // Subtractor is an optional interface implemented by some
@ -203,7 +202,7 @@ type Aggregator interface {
type Subtractor interface { type Subtractor interface {
// Subtract subtracts the `operand` from this Aggregator and // Subtract subtracts the `operand` from this Aggregator and
// outputs the value in `result`. // outputs the value in `result`.
Subtract(operand, result Aggregator, descriptor *metric.Descriptor) error Subtract(operand, result Aggregator, descriptor *sdkapi.Descriptor) error
} }
// Exporter handles presentation of the checkpoint of aggregate // Exporter handles presentation of the checkpoint of aggregate
@ -233,7 +232,7 @@ type ExportKindSelector interface {
// ExportKindFor should return the correct ExportKind that // ExportKindFor should return the correct ExportKind that
// should be used when exporting data for the given metric // should be used when exporting data for the given metric
// instrument and Aggregator kind. // instrument and Aggregator kind.
ExportKindFor(descriptor *metric.Descriptor, aggregatorKind aggregation.Kind) ExportKind ExportKindFor(descriptor *sdkapi.Descriptor, aggregatorKind aggregation.Kind) ExportKind
} }
// InstrumentationLibraryReader is an interface for exporters to iterate // InstrumentationLibraryReader is an interface for exporters to iterate
@ -283,7 +282,7 @@ type Reader interface {
// are shared by the Accumulator->Processor and Processor->Exporter // are shared by the Accumulator->Processor and Processor->Exporter
// steps. // steps.
type Metadata struct { type Metadata struct {
descriptor *metric.Descriptor descriptor *sdkapi.Descriptor
labels *attribute.Set labels *attribute.Set
} }
@ -305,7 +304,7 @@ type Record struct {
} }
// Descriptor describes the metric instrument being exported. // Descriptor describes the metric instrument being exported.
func (m Metadata) Descriptor() *metric.Descriptor { func (m Metadata) Descriptor() *sdkapi.Descriptor {
return m.descriptor return m.descriptor
} }
@ -319,7 +318,7 @@ func (m Metadata) Labels() *attribute.Set {
// Accumulations to send to Processors. The Descriptor, Labels, // Accumulations to send to Processors. The Descriptor, Labels,
// and Aggregator represent aggregate metric events received over a single // and Aggregator represent aggregate metric events received over a single
// collection period. // collection period.
func NewAccumulation(descriptor *metric.Descriptor, labels *attribute.Set, aggregator Aggregator) Accumulation { func NewAccumulation(descriptor *sdkapi.Descriptor, labels *attribute.Set, aggregator Aggregator) Accumulation {
return Accumulation{ return Accumulation{
Metadata: Metadata{ Metadata: Metadata{
descriptor: descriptor, descriptor: descriptor,
@ -338,7 +337,7 @@ func (r Accumulation) Aggregator() Aggregator {
// NewRecord allows Processor implementations to construct export // NewRecord allows Processor implementations to construct export
// records. The Descriptor, Labels, and Aggregator represent // records. The Descriptor, Labels, and Aggregator represent
// aggregate metric events received over a single collection period. // aggregate metric events received over a single collection period.
func NewRecord(descriptor *metric.Descriptor, labels *attribute.Set, aggregation aggregation.Aggregation, start, end time.Time) Record { func NewRecord(descriptor *sdkapi.Descriptor, labels *attribute.Set, aggregation aggregation.Aggregation, start, end time.Time) Record {
return Record{ return Record{
Metadata: Metadata{ Metadata: Metadata{
descriptor: descriptor, descriptor: descriptor,
@ -441,12 +440,12 @@ func StatelessExportKindSelector() ExportKindSelector {
} }
// ExportKindFor implements ExportKindSelector. // ExportKindFor implements ExportKindSelector.
func (c constantExportKindSelector) ExportKindFor(_ *metric.Descriptor, _ aggregation.Kind) ExportKind { func (c constantExportKindSelector) ExportKindFor(_ *sdkapi.Descriptor, _ aggregation.Kind) ExportKind {
return ExportKind(c) return ExportKind(c)
} }
// ExportKindFor implements ExportKindSelector. // ExportKindFor implements ExportKindSelector.
func (s statelessExportKindSelector) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) ExportKind { func (s statelessExportKindSelector) ExportKindFor(desc *sdkapi.Descriptor, kind aggregation.Kind) ExportKind {
if kind == aggregation.SumKind && desc.InstrumentKind().PrecomputedSum() { if kind == aggregation.SumKind && desc.InstrumentKind().PrecomputedSum() {
return CumulativeExportKind return CumulativeExportKind
} }

View File

@ -18,7 +18,6 @@ import (
"fmt" "fmt"
"math" "math"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -36,7 +35,7 @@ func NewInconsistentAggregatorError(a1, a2 export.Aggregator) error {
// This rejects NaN values. This rejects negative values when the // This rejects NaN values. This rejects negative values when the
// metric instrument does not support negative values, including // metric instrument does not support negative values, including
// monotonic counter metrics and absolute Histogram metrics. // monotonic counter metrics and absolute Histogram metrics.
func RangeTest(num number.Number, descriptor *metric.Descriptor) error { func RangeTest(num number.Number, descriptor *sdkapi.Descriptor) error {
numberKind := descriptor.NumberKind() numberKind := descriptor.NumberKind()
if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) { if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) {

View File

@ -21,7 +21,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
@ -41,7 +40,7 @@ func TestInconsistentAggregatorErr(t *testing.T) {
require.True(t, errors.Is(err, aggregation.ErrInconsistentType)) require.True(t, errors.Is(err, aggregation.ErrInconsistentType))
} }
func testRangeNaN(t *testing.T, desc *metric.Descriptor) { func testRangeNaN(t *testing.T, desc *sdkapi.Descriptor) {
// If the descriptor uses int64 numbers, this won't register as NaN // If the descriptor uses int64 numbers, this won't register as NaN
nan := number.NewFloat64Number(math.NaN()) nan := number.NewFloat64Number(math.NaN())
err := aggregator.RangeTest(nan, desc) err := aggregator.RangeTest(nan, desc)
@ -53,7 +52,7 @@ func testRangeNaN(t *testing.T, desc *metric.Descriptor) {
} }
} }
func testRangeNegative(t *testing.T, desc *metric.Descriptor) { func testRangeNegative(t *testing.T, desc *sdkapi.Descriptor) {
var neg, pos number.Number var neg, pos number.Number
if desc.NumberKind() == number.Float64Kind { if desc.NumberKind() == number.Float64Kind {

View File

@ -26,7 +26,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ottest "go.opentelemetry.io/otel/internal/internaltest" ottest "go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
@ -66,7 +65,7 @@ func newProfiles() []Profile {
} }
} }
func NewAggregatorTest(mkind sdkapi.InstrumentKind, nkind number.Kind) *metric.Descriptor { func NewAggregatorTest(mkind sdkapi.InstrumentKind, nkind number.Kind) *sdkapi.Descriptor {
desc := metrictest.NewDescriptor("test.name", mkind, nkind) desc := metrictest.NewDescriptor("test.name", mkind, nkind)
return &desc return &desc
} }
@ -151,7 +150,7 @@ func (n *Numbers) Points() []number.Number {
} }
// CheckedUpdate performs the same range test the SDK does on behalf of the aggregator. // CheckedUpdate performs the same range test the SDK does on behalf of the aggregator.
func CheckedUpdate(t *testing.T, agg export.Aggregator, number number.Number, descriptor *metric.Descriptor) { func CheckedUpdate(t *testing.T, agg export.Aggregator, number number.Number, descriptor *sdkapi.Descriptor) {
ctx := context.Background() ctx := context.Background()
// Note: Aggregator tests are written assuming that the SDK // Note: Aggregator tests are written assuming that the SDK
@ -167,7 +166,7 @@ func CheckedUpdate(t *testing.T, agg export.Aggregator, number number.Number, de
} }
} }
func CheckedMerge(t *testing.T, aggInto, aggFrom export.Aggregator, descriptor *metric.Descriptor) { func CheckedMerge(t *testing.T, aggInto, aggFrom export.Aggregator, descriptor *sdkapi.Descriptor) {
if err := aggInto.Merge(aggFrom, descriptor); err != nil { if err := aggInto.Merge(aggFrom, descriptor); err != nil {
t.Error("Unexpected Merge failure", err) t.Error("Unexpected Merge failure", err)
} }
@ -181,19 +180,19 @@ func (NoopAggregator) Aggregation() aggregation.Aggregation {
return NoopAggregation{} return NoopAggregation{}
} }
func (NoopAggregator) Update(context.Context, number.Number, *metric.Descriptor) error { func (NoopAggregator) Update(context.Context, number.Number, *sdkapi.Descriptor) error {
return nil return nil
} }
func (NoopAggregator) SynchronizedMove(export.Aggregator, *metric.Descriptor) error { func (NoopAggregator) SynchronizedMove(export.Aggregator, *sdkapi.Descriptor) error {
return nil return nil
} }
func (NoopAggregator) Merge(export.Aggregator, *metric.Descriptor) error { func (NoopAggregator) Merge(export.Aggregator, *sdkapi.Descriptor) error {
return nil return nil
} }
func SynchronizedMoveResetTest(t *testing.T, mkind sdkapi.InstrumentKind, nf func(*metric.Descriptor) export.Aggregator) { func SynchronizedMoveResetTest(t *testing.T, mkind sdkapi.InstrumentKind, nf func(*sdkapi.Descriptor) export.Aggregator) {
t.Run("reset on nil", func(t *testing.T) { t.Run("reset on nil", func(t *testing.T) {
// Ensures that SynchronizedMove(nil, descriptor) discards and // Ensures that SynchronizedMove(nil, descriptor) discards and
// resets the aggregator. // resets the aggregator.

View File

@ -19,8 +19,8 @@ import (
"sync" "sync"
"time" "time"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -68,7 +68,7 @@ func (c *Aggregator) Points() ([]aggregation.Point, error) {
// SynchronizedMove saves the current state to oa and resets the current state to // SynchronizedMove saves the current state to oa and resets the current state to
// the empty set, taking a lock to prevent concurrent Update() calls. // the empty set, taking a lock to prevent concurrent Update() calls.
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if oa != nil && o == nil { if oa != nil && o == nil {
@ -89,7 +89,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descrip
// Update adds the recorded measurement to the current data set. // Update adds the recorded measurement to the current data set.
// Update takes a lock to prevent concurrent Update() and SynchronizedMove() // Update takes a lock to prevent concurrent Update() and SynchronizedMove()
// calls. // calls.
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
now := time.Now() now := time.Now()
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock() defer c.lock.Unlock()
@ -102,7 +102,7 @@ func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metri
} }
// Merge combines two data sets into one. // Merge combines two data sets into one.
func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if o == nil { if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa) return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -38,7 +37,7 @@ func requireNotAfter(t *testing.T, t1, t2 time.Time) {
require.False(t, t1.After(t2), "expected %v ≤ %v", t1, t2) require.False(t, t1.After(t2), "expected %v ≤ %v", t1, t2)
} }
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) { func checkZero(t *testing.T, agg *Aggregator, desc *sdkapi.Descriptor) {
count, err := agg.Count() count, err := agg.Count()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(0), count) require.Equal(t, uint64(0), count)
@ -312,7 +311,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
aggregatortest.SynchronizedMoveResetTest( aggregatortest.SynchronizedMoveResetTest(
t, t,
sdkapi.HistogramInstrumentKind, sdkapi.HistogramInstrumentKind,
func(desc *metric.Descriptor) export.Aggregator { func(desc *sdkapi.Descriptor) export.Aggregator {
return &New(1)[0] return &New(1)[0]
}, },
) )

View File

@ -19,8 +19,8 @@ import (
"sort" "sort"
"sync" "sync"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -110,7 +110,7 @@ var _ aggregation.Histogram = &Aggregator{}
// Note that this aggregator maintains each value using independent // Note that this aggregator maintains each value using independent
// atomic operations, which introduces the possibility that // atomic operations, which introduces the possibility that
// checkpoints are inconsistent. // checkpoints are inconsistent.
func New(cnt int, desc *metric.Descriptor, opts ...Option) []Aggregator { func New(cnt int, desc *sdkapi.Descriptor, opts ...Option) []Aggregator {
var cfg config var cfg config
if desc.NumberKind() == number.Int64Kind { if desc.NumberKind() == number.Int64Kind {
@ -174,7 +174,7 @@ func (c *Aggregator) Histogram() (aggregation.Buckets, error) {
// the empty set. Since no locks are taken, there is a chance that // the empty set. Since no locks are taken, there is a chance that
// the independent Sum, Count and Bucket Count are not consistent with each // the independent Sum, Count and Bucket Count are not consistent with each
// other. // other.
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if oa != nil && o == nil { if oa != nil && o == nil {
@ -220,7 +220,7 @@ func (c *Aggregator) clearState() {
} }
// Update adds the recorded measurement to the current data set. // Update adds the recorded measurement to the current data set.
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
kind := desc.NumberKind() kind := desc.NumberKind()
asFloat := number.CoerceToFloat64(kind) asFloat := number.CoerceToFloat64(kind)
@ -254,7 +254,7 @@ func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metri
} }
// Merge combines two histograms that have the same buckets into a single one. // Merge combines two histograms that have the same buckets into a single one.
func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if o == nil { if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa) return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -64,17 +63,17 @@ var (
testBoundaries = []float64{500, 250, 750} testBoundaries = []float64{500, 250, 750}
) )
func new2(desc *metric.Descriptor, options ...histogram.Option) (_, _ *histogram.Aggregator) { func new2(desc *sdkapi.Descriptor, options ...histogram.Option) (_, _ *histogram.Aggregator) {
alloc := histogram.New(2, desc, options...) alloc := histogram.New(2, desc, options...)
return &alloc[0], &alloc[1] return &alloc[0], &alloc[1]
} }
func new4(desc *metric.Descriptor, options ...histogram.Option) (_, _, _, _ *histogram.Aggregator) { func new4(desc *sdkapi.Descriptor, options ...histogram.Option) (_, _, _, _ *histogram.Aggregator) {
alloc := histogram.New(4, desc, options...) alloc := histogram.New(4, desc, options...)
return &alloc[0], &alloc[1], &alloc[2], &alloc[3] return &alloc[0], &alloc[1], &alloc[2], &alloc[3]
} }
func checkZero(t *testing.T, agg *histogram.Aggregator, desc *metric.Descriptor) { func checkZero(t *testing.T, agg *histogram.Aggregator, desc *sdkapi.Descriptor) {
asum, err := agg.Sum() asum, err := agg.Sum()
require.Equal(t, number.Number(0), asum, "Empty checkpoint sum = 0") require.Equal(t, number.Number(0), asum, "Empty checkpoint sum = 0")
require.NoError(t, err) require.NoError(t, err)
@ -241,7 +240,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
aggregatortest.SynchronizedMoveResetTest( aggregatortest.SynchronizedMoveResetTest(
t, t,
sdkapi.HistogramInstrumentKind, sdkapi.HistogramInstrumentKind,
func(desc *metric.Descriptor) export.Aggregator { func(desc *sdkapi.Descriptor) export.Aggregator {
return &histogram.New(1, desc, histogram.WithExplicitBoundaries(testBoundaries))[0] return &histogram.New(1, desc, histogram.WithExplicitBoundaries(testBoundaries))[0]
}, },
) )

View File

@ -20,8 +20,8 @@ import (
"time" "time"
"unsafe" "unsafe"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -92,7 +92,7 @@ func (g *Aggregator) LastValue() (number.Number, time.Time, error) {
} }
// SynchronizedMove atomically saves the current value. // SynchronizedMove atomically saves the current value.
func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error { func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *sdkapi.Descriptor) error {
if oa == nil { if oa == nil {
atomic.StorePointer(&g.value, unsafe.Pointer(unsetLastValue)) atomic.StorePointer(&g.value, unsafe.Pointer(unsetLastValue))
return nil return nil
@ -106,7 +106,7 @@ func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
} }
// Update atomically sets the current "last" value. // Update atomically sets the current "last" value.
func (g *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { func (g *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
ngd := &lastValueData{ ngd := &lastValueData{
value: number, value: number,
timestamp: time.Now(), timestamp: time.Now(),
@ -117,7 +117,7 @@ func (g *Aggregator) Update(_ context.Context, number number.Number, desc *metri
// Merge combines state from two aggregators. The most-recently set // Merge combines state from two aggregators. The most-recently set
// value is chosen. // value is chosen.
func (g *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { func (g *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if o == nil { if o == nil {
return aggregator.NewInconsistentAggregatorError(g, oa) return aggregator.NewInconsistentAggregatorError(g, oa)

View File

@ -25,7 +25,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ottest "go.opentelemetry.io/otel/internal/internaltest" ottest "go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -140,7 +139,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
aggregatortest.SynchronizedMoveResetTest( aggregatortest.SynchronizedMoveResetTest(
t, t,
sdkapi.GaugeObserverInstrumentKind, sdkapi.GaugeObserverInstrumentKind,
func(desc *metric.Descriptor) export.Aggregator { func(desc *sdkapi.Descriptor) export.Aggregator {
return &New(1)[0] return &New(1)[0]
}, },
) )

View File

@ -18,8 +18,8 @@ import (
"context" "context"
"sync" "sync"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -49,7 +49,7 @@ var _ aggregation.MinMaxSumCount = &Aggregator{}
// count. // count.
// //
// This type uses a mutex for Update() and SynchronizedMove() concurrency. // This type uses a mutex for Update() and SynchronizedMove() concurrency.
func New(cnt int, desc *metric.Descriptor) []Aggregator { func New(cnt int, desc *sdkapi.Descriptor) []Aggregator {
kind := desc.NumberKind() kind := desc.NumberKind()
aggs := make([]Aggregator, cnt) aggs := make([]Aggregator, cnt)
for i := range aggs { for i := range aggs {
@ -103,7 +103,7 @@ func (c *Aggregator) Max() (number.Number, error) {
// SynchronizedMove saves the current state into oa and resets the current state to // SynchronizedMove saves the current state into oa and resets the current state to
// the empty set. // the empty set.
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if oa != nil && o == nil { if oa != nil && o == nil {
@ -129,7 +129,7 @@ func emptyState(kind number.Kind) state {
} }
// Update adds the recorded measurement to the current data set. // Update adds the recorded measurement to the current data set.
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metric.Descriptor) error { func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
kind := desc.NumberKind() kind := desc.NumberKind()
c.lock.Lock() c.lock.Lock()
@ -146,7 +146,7 @@ func (c *Aggregator) Update(_ context.Context, number number.Number, desc *metri
} }
// Merge combines two data sets into one. // Merge combines two data sets into one.
func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if o == nil { if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa) return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -79,17 +78,17 @@ func TestMinMaxSumCountPositiveAndNegative(t *testing.T) {
}) })
} }
func new2(desc *metric.Descriptor) (_, _ *Aggregator) { func new2(desc *sdkapi.Descriptor) (_, _ *Aggregator) {
alloc := New(2, desc) alloc := New(2, desc)
return &alloc[0], &alloc[1] return &alloc[0], &alloc[1]
} }
func new4(desc *metric.Descriptor) (_, _, _, _ *Aggregator) { func new4(desc *sdkapi.Descriptor) (_, _, _, _ *Aggregator) {
alloc := New(4, desc) alloc := New(4, desc)
return &alloc[0], &alloc[1], &alloc[2], &alloc[3] return &alloc[0], &alloc[1], &alloc[2], &alloc[3]
} }
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) { func checkZero(t *testing.T, agg *Aggregator, desc *sdkapi.Descriptor) {
kind := desc.NumberKind() kind := desc.NumberKind()
sum, err := agg.Sum() sum, err := agg.Sum()
@ -242,7 +241,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
aggregatortest.SynchronizedMoveResetTest( aggregatortest.SynchronizedMoveResetTest(
t, t,
sdkapi.HistogramInstrumentKind, sdkapi.HistogramInstrumentKind,
func(desc *metric.Descriptor) export.Aggregator { func(desc *sdkapi.Descriptor) export.Aggregator {
return &New(1, desc)[0] return &New(1, desc)[0]
}, },
) )

View File

@ -17,8 +17,8 @@ package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
import ( import (
"context" "context"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -60,7 +60,7 @@ func (c *Aggregator) Sum() (number.Number, error) {
// SynchronizedMove atomically saves the current value into oa and resets the // SynchronizedMove atomically saves the current value into oa and resets the
// current sum to zero. // current sum to zero.
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error { func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *sdkapi.Descriptor) error {
if oa == nil { if oa == nil {
c.value.SetRawAtomic(0) c.value.SetRawAtomic(0)
return nil return nil
@ -74,13 +74,13 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
} }
// Update atomically adds to the current value. // Update atomically adds to the current value.
func (c *Aggregator) Update(_ context.Context, num number.Number, desc *metric.Descriptor) error { func (c *Aggregator) Update(_ context.Context, num number.Number, desc *sdkapi.Descriptor) error {
c.value.AddNumberAtomic(desc.NumberKind(), num) c.value.AddNumberAtomic(desc.NumberKind(), num)
return nil return nil
} }
// Merge combines two counters by adding their sums. // Merge combines two counters by adding their sums.
func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error { func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
o, _ := oa.(*Aggregator) o, _ := oa.(*Aggregator)
if o == nil { if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa) return aggregator.NewInconsistentAggregatorError(c, oa)
@ -89,7 +89,7 @@ func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error
return nil return nil
} }
func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *metric.Descriptor) error { func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *sdkapi.Descriptor) error {
op, _ := opAgg.(*Aggregator) op, _ := opAgg.(*Aggregator)
if op == nil { if op == nil {
return aggregator.NewInconsistentAggregatorError(c, opAgg) return aggregator.NewInconsistentAggregatorError(c, opAgg)

View File

@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ottest "go.opentelemetry.io/otel/internal/internaltest" ottest "go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
@ -56,7 +55,7 @@ func new4() (_, _, _, _ *Aggregator) {
return &alloc[0], &alloc[1], &alloc[2], &alloc[3] return &alloc[0], &alloc[1], &alloc[2], &alloc[3]
} }
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) { func checkZero(t *testing.T, agg *Aggregator, desc *sdkapi.Descriptor) {
kind := desc.NumberKind() kind := desc.NumberKind()
sum, err := agg.Sum() sum, err := agg.Sum()
@ -148,7 +147,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
aggregatortest.SynchronizedMoveResetTest( aggregatortest.SynchronizedMoveResetTest(
t, t,
sdkapi.CounterObserverInstrumentKind, sdkapi.CounterObserverInstrumentKind,
func(desc *metric.Descriptor) export.Aggregator { func(desc *sdkapi.Descriptor) export.Aggregator {
return &New(1)[0] return &New(1)[0]
}, },
) )

View File

@ -23,6 +23,7 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global" "go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric" sdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/processor/processortest" "go.opentelemetry.io/otel/sdk/metric/processor/processortest"
@ -483,7 +484,7 @@ func benchmarkBatchRecord8Labels(b *testing.B, numInst int) {
ctx := context.Background() ctx := context.Background()
fix := newFixture(b) fix := newFixture(b)
labs := makeLabels(numLabels) labs := makeLabels(numLabels)
var meas []metric.Measurement var meas []sdkapi.Measurement
for i := 0; i < numInst; i++ { for i := 0; i < numInst; i++ {
inst := fix.meterMust().NewInt64Counter(fmt.Sprintf("int64.%d.sum", i)) inst := fix.meterMust().NewInt64Counter(fmt.Sprintf("int64.%d.sum", i))

View File

@ -26,6 +26,7 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
ottest "go.opentelemetry.io/otel/internal/internaltest" ottest "go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
@ -296,7 +297,7 @@ func (b *blockingExporter) Export(ctx context.Context, res *resource.Resource, o
} }
func (*blockingExporter) ExportKindFor( func (*blockingExporter) ExportKindFor(
*metric.Descriptor, *sdkapi.Descriptor,
aggregation.Kind, aggregation.Kind,
) export.ExportKind { ) export.ExportKind {
return export.CumulativeExportKind return export.CumulativeExportKind

View File

@ -26,6 +26,7 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
metricsdk "go.opentelemetry.io/otel/sdk/metric" metricsdk "go.opentelemetry.io/otel/sdk/metric"
@ -71,7 +72,7 @@ type testSelector struct {
newAggCount int newAggCount int
} }
func (ts *testSelector) AggregatorFor(desc *metric.Descriptor, aggPtrs ...*export.Aggregator) { func (ts *testSelector) AggregatorFor(desc *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
ts.newAggCount += len(aggPtrs) ts.newAggCount += len(aggPtrs)
processortest.AggregatorSelector().AggregatorFor(desc, aggPtrs...) processortest.AggregatorSelector().AggregatorFor(desc, aggPtrs...)
} }

View File

@ -21,7 +21,7 @@ import (
"time" "time"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
) )
@ -40,13 +40,13 @@ type (
// data for the same instrument, and this code has // data for the same instrument, and this code has
// logic to combine data properly from multiple // logic to combine data properly from multiple
// accumulators. However, the use of // accumulators. However, the use of
// *metric.Descriptor in the stateKey makes such // *sdkapi.Descriptor in the stateKey makes such
// combination impossible, because each accumulator // combination impossible, because each accumulator
// allocates its own instruments. This can be fixed // allocates its own instruments. This can be fixed
// by using the instrument name and kind instead of // by using the instrument name and kind instead of
// the descriptor pointer. See // the descriptor pointer. See
// https://github.com/open-telemetry/opentelemetry-go/issues/862. // https://github.com/open-telemetry/opentelemetry-go/issues/862.
descriptor *metric.Descriptor descriptor *sdkapi.Descriptor
distinct attribute.Distinct distinct attribute.Distinct
} }

View File

@ -110,7 +110,7 @@ func asNumber(nkind number.Kind, value int64) number.Number {
return number.NewFloat64Number(float64(value)) return number.NewFloat64Number(float64(value))
} }
func updateFor(t *testing.T, desc *metric.Descriptor, selector export.AggregatorSelector, value int64, labs ...attribute.KeyValue) export.Accumulation { func updateFor(t *testing.T, desc *sdkapi.Descriptor, selector export.AggregatorSelector, value int64, labs ...attribute.KeyValue) export.Accumulation {
ls := attribute.NewSet(labs...) ls := attribute.NewSet(labs...)
var agg export.Aggregator var agg export.Aggregator
selector.AggregatorFor(desc, &agg) selector.AggregatorFor(desc, &agg)
@ -265,7 +265,7 @@ func testProcessor(
type bogusExporter struct{} type bogusExporter struct{}
func (bogusExporter) ExportKindFor(*metric.Descriptor, aggregation.Kind) export.ExportKind { func (bogusExporter) ExportKindFor(*sdkapi.Descriptor, aggregation.Kind) export.ExportKind {
return 1000000 return 1000000
} }

View File

@ -22,8 +22,8 @@ import (
"time" "time"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
@ -40,7 +40,7 @@ type (
// unique descriptor, distinct labels, and distinct resource // unique descriptor, distinct labels, and distinct resource
// attributes. // attributes.
mapKey struct { mapKey struct {
desc *metric.Descriptor desc *sdkapi.Descriptor
labels attribute.Distinct labels attribute.Distinct
resource attribute.Distinct resource attribute.Distinct
} }
@ -181,7 +181,7 @@ func AggregatorSelector() export.AggregatorSelector {
} }
// AggregatorFor implements export.AggregatorSelector. // AggregatorFor implements export.AggregatorSelector.
func (testAggregatorSelector) AggregatorFor(desc *metric.Descriptor, aggPtrs ...*export.Aggregator) { func (testAggregatorSelector) AggregatorFor(desc *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
switch { switch {
case strings.HasSuffix(desc.Name(), ".disabled"): case strings.HasSuffix(desc.Name(), ".disabled"):

View File

@ -33,7 +33,7 @@ type someFilter struct{
// ... // ...
} }
func (someFilter) LabelFilterFor(_ *metric.Descriptor) attribute.Filter { func (someFilter) LabelFilterFor(_ *sdkapi.Descriptor) attribute.Filter {
return func(label kv.KeyValue) bool { return func(label kv.KeyValue) bool {
// return true to keep this label, false to drop this label // return true to keep this label, false to drop this label
// ... // ...

View File

@ -16,7 +16,7 @@ package reducer // import "go.opentelemetry.io/otel/sdk/metric/processor/reducer
import ( import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
) )
@ -31,7 +31,7 @@ type (
// LabelFilterSelector is the interface used to configure a // LabelFilterSelector is the interface used to configure a
// specific Filter to an instrument. // specific Filter to an instrument.
LabelFilterSelector interface { LabelFilterSelector interface {
LabelFilterFor(descriptor *metric.Descriptor) attribute.Filter LabelFilterFor(descriptor *sdkapi.Descriptor) attribute.Filter
} }
) )

View File

@ -22,6 +22,7 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/instrumentation" "go.opentelemetry.io/otel/sdk/instrumentation"
metricsdk "go.opentelemetry.io/otel/sdk/metric" metricsdk "go.opentelemetry.io/otel/sdk/metric"
@ -47,13 +48,13 @@ var (
type testFilter struct{} type testFilter struct{}
func (testFilter) LabelFilterFor(_ *metric.Descriptor) attribute.Filter { func (testFilter) LabelFilterFor(_ *sdkapi.Descriptor) attribute.Filter {
return func(label attribute.KeyValue) bool { return func(label attribute.KeyValue) bool {
return label.Key == "A" || label.Key == "C" return label.Key == "A" || label.Key == "C"
} }
} }
func generateData(impl metric.MeterImpl) { func generateData(impl sdkapi.MeterImpl) {
ctx := context.Background() ctx := context.Background()
meter := metric.WrapMeterImpl(impl) meter := metric.WrapMeterImpl(impl)

View File

@ -24,8 +24,8 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
internal "go.opentelemetry.io/otel/internal/metric" internal "go.opentelemetry.io/otel/internal/metric"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator" "go.opentelemetry.io/otel/sdk/metric/aggregator"
) )
@ -72,7 +72,7 @@ type (
// mapkey uniquely describes a metric instrument in terms of // mapkey uniquely describes a metric instrument in terms of
// its InstrumentID and the encoded form of its labels. // its InstrumentID and the encoded form of its labels.
mapkey struct { mapkey struct {
descriptor *metric.Descriptor descriptor *sdkapi.Descriptor
ordered attribute.Distinct ordered attribute.Distinct
} }
@ -120,7 +120,7 @@ type (
instrument struct { instrument struct {
meter *Accumulator meter *Accumulator
descriptor metric.Descriptor descriptor sdkapi.Descriptor
} }
asyncInstrument struct { asyncInstrument struct {
@ -138,16 +138,16 @@ type (
) )
var ( var (
_ metric.MeterImpl = &Accumulator{} _ sdkapi.MeterImpl = &Accumulator{}
_ metric.AsyncImpl = &asyncInstrument{} _ sdkapi.AsyncImpl = &asyncInstrument{}
_ metric.SyncImpl = &syncInstrument{} _ sdkapi.SyncImpl = &syncInstrument{}
_ metric.BoundSyncImpl = &record{} _ sdkapi.BoundSyncImpl = &record{}
// ErrUninitializedInstrument is returned when an instrument is used when uninitialized. // ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument") ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
) )
func (inst *instrument) Descriptor() metric.Descriptor { func (inst *instrument) Descriptor() sdkapi.Descriptor {
return inst.descriptor return inst.descriptor
} }
@ -280,7 +280,7 @@ func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attri
} }
// The order of the input array `kvs` may be sorted after the function is called. // The order of the input array `kvs` may be sorted after the function is called.
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) metric.BoundSyncImpl { func (s *syncInstrument) Bind(kvs []attribute.KeyValue) sdkapi.BoundSyncImpl {
return s.acquireHandle(kvs, nil) return s.acquireHandle(kvs, nil)
} }
@ -307,8 +307,8 @@ func NewAccumulator(processor export.Processor) *Accumulator {
} }
} }
// NewSyncInstrument implements metric.MetricImpl. // NewSyncInstrument implements sdkapi.MetricImpl.
func (m *Accumulator) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) { func (m *Accumulator) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
return &syncInstrument{ return &syncInstrument{
instrument: instrument{ instrument: instrument{
descriptor: descriptor, descriptor: descriptor,
@ -317,8 +317,8 @@ func (m *Accumulator) NewSyncInstrument(descriptor metric.Descriptor) (metric.Sy
}, nil }, nil
} }
// NewAsyncInstrument implements metric.MetricImpl. // NewAsyncInstrument implements sdkapi.MetricImpl.
func (m *Accumulator) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (metric.AsyncImpl, error) { func (m *Accumulator) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
a := &asyncInstrument{ a := &asyncInstrument{
instrument: instrument{ instrument: instrument{
descriptor: descriptor, descriptor: descriptor,
@ -395,7 +395,7 @@ func (m *Accumulator) collectSyncInstruments() int {
// CollectAsync implements internal.AsyncCollector. // CollectAsync implements internal.AsyncCollector.
// The order of the input array `kvs` may be sorted after the function is called. // The order of the input array `kvs` may be sorted after the function is called.
func (m *Accumulator) CollectAsync(kv []attribute.KeyValue, obs ...metric.Observation) { func (m *Accumulator) CollectAsync(kv []attribute.KeyValue, obs ...sdkapi.Observation) {
labels := attribute.NewSetWithSortable(kv, &m.asyncSortSlice) labels := attribute.NewSetWithSortable(kv, &m.asyncSortSlice)
for _, ob := range obs { for _, ob := range obs {
@ -472,7 +472,7 @@ func (m *Accumulator) checkpointAsync(a *asyncInstrument) int {
// RecordBatch enters a batch of metric events. // RecordBatch enters a batch of metric events.
// The order of the input array `kvs` may be sorted after the function is called. // The order of the input array `kvs` may be sorted after the function is called.
func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue, measurements ...metric.Measurement) { func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue, measurements ...sdkapi.Measurement) {
// Labels will be computed the first time acquireHandle is // Labels will be computed the first time acquireHandle is
// called. Subsequent calls to acquireHandle will re-use the // called. Subsequent calls to acquireHandle will re-use the
// previously computed value instead of recomputing the // previously computed value instead of recomputing the
@ -495,7 +495,7 @@ func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue,
} }
} }
// RecordOne implements metric.SyncImpl. // RecordOne implements sdkapi.SyncImpl.
func (r *record) RecordOne(ctx context.Context, num number.Number) { func (r *record) RecordOne(ctx context.Context, num number.Number) {
if r.current == nil { if r.current == nil {
// The instrument is disabled according to the AggregatorSelector. // The instrument is disabled according to the AggregatorSelector.
@ -514,7 +514,7 @@ func (r *record) RecordOne(ctx context.Context, num number.Number) {
atomic.AddInt64(&r.updateCount, 1) atomic.AddInt64(&r.updateCount, 1)
} }
// Unbind implements metric.SyncImpl. // Unbind implements sdkapi.SyncImpl.
func (r *record) Unbind() { func (r *record) Unbind() {
r.refMapped.unref() r.refMapped.unref()
} }
@ -528,7 +528,7 @@ func (r *record) mapkey() mapkey {
// fromSync gets a sync implementation object, checking for // fromSync gets a sync implementation object, checking for
// uninitialized instruments and instruments created by another SDK. // uninitialized instruments and instruments created by another SDK.
func (m *Accumulator) fromSync(sync metric.SyncImpl) *syncInstrument { func (m *Accumulator) fromSync(sync sdkapi.SyncImpl) *syncInstrument {
if sync != nil { if sync != nil {
if inst, ok := sync.Implementation().(*syncInstrument); ok { if inst, ok := sync.Implementation().(*syncInstrument); ok {
return inst return inst
@ -540,7 +540,7 @@ func (m *Accumulator) fromSync(sync metric.SyncImpl) *syncInstrument {
// fromSync gets an async implementation object, checking for // fromSync gets an async implementation object, checking for
// uninitialized instruments and instruments created by another SDK. // uninitialized instruments and instruments created by another SDK.
func (m *Accumulator) fromAsync(async metric.AsyncImpl) *asyncInstrument { func (m *Accumulator) fromAsync(async sdkapi.AsyncImpl) *asyncInstrument {
if async != nil { if async != nil {
if inst, ok := async.Implementation().(*asyncInstrument); ok { if inst, ok := async.Implementation().(*asyncInstrument); ok {
return inst return inst

View File

@ -15,7 +15,6 @@
package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple" package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
import ( import (
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/exact" "go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
@ -78,7 +77,7 @@ func lastValueAggs(aggPtrs []*export.Aggregator) {
} }
} }
func (selectorInexpensive) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { func (selectorInexpensive) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() { switch descriptor.InstrumentKind() {
case sdkapi.GaugeObserverInstrumentKind: case sdkapi.GaugeObserverInstrumentKind:
lastValueAggs(aggPtrs) lastValueAggs(aggPtrs)
@ -92,7 +91,7 @@ func (selectorInexpensive) AggregatorFor(descriptor *metric.Descriptor, aggPtrs
} }
} }
func (selectorExact) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { func (selectorExact) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() { switch descriptor.InstrumentKind() {
case sdkapi.GaugeObserverInstrumentKind: case sdkapi.GaugeObserverInstrumentKind:
lastValueAggs(aggPtrs) lastValueAggs(aggPtrs)
@ -106,7 +105,7 @@ func (selectorExact) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*ex
} }
} }
func (s selectorHistogram) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) { func (s selectorHistogram) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() { switch descriptor.InstrumentKind() {
case sdkapi.GaugeObserverInstrumentKind: case sdkapi.GaugeObserverInstrumentKind:
lastValueAggs(aggPtrs) lastValueAggs(aggPtrs)

View File

@ -19,7 +19,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/metrictest" "go.opentelemetry.io/otel/metric/metrictest"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
"go.opentelemetry.io/otel/metric/sdkapi" "go.opentelemetry.io/otel/metric/sdkapi"
@ -41,7 +40,7 @@ var (
testGaugeObserverDesc = metrictest.NewDescriptor("gauge", sdkapi.GaugeObserverInstrumentKind, number.Int64Kind) testGaugeObserverDesc = metrictest.NewDescriptor("gauge", sdkapi.GaugeObserverInstrumentKind, number.Int64Kind)
) )
func oneAgg(sel export.AggregatorSelector, desc *metric.Descriptor) export.Aggregator { func oneAgg(sel export.AggregatorSelector, desc *sdkapi.Descriptor) export.Aggregator {
var agg export.Aggregator var agg export.Aggregator
sel.AggregatorFor(desc, &agg) sel.AggregatorFor(desc, &agg)
return agg return agg

View File

@ -71,7 +71,7 @@ type (
testKey struct { testKey struct {
labels string labels string
descriptor *metric.Descriptor descriptor *sdkapi.Descriptor
} }
testImpl struct { testImpl struct {
@ -90,7 +90,7 @@ type (
} }
SyncImpler interface { SyncImpler interface {
SyncImpl() metric.SyncImpl SyncImpl() sdkapi.SyncImpl
} }
// lastValueState supports merging lastValue values, for the case // lastValueState supports merging lastValue values, for the case
@ -163,7 +163,7 @@ func (f *testFixture) startWorker(impl *Accumulator, meter metric.Meter, wg *syn
ctx := context.Background() ctx := context.Background()
name := fmt.Sprint("test_", i) name := fmt.Sprint("test_", i)
instrument := f.impl.newInstrument(meter, name) instrument := f.impl.newInstrument(meter, name)
var descriptor *metric.Descriptor var descriptor *sdkapi.Descriptor
if ii, ok := instrument.SyncImpl().(*syncInstrument); ok { if ii, ok := instrument.SyncImpl().(*syncInstrument); ok {
descriptor = &ii.descriptor descriptor = &ii.descriptor
} }