You've already forked opentelemetry-go
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:
@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
## Changed
|
||||
|
||||
- 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
|
||||
|
||||
|
@ -147,7 +147,7 @@ func convertResource(res *ocresource.Resource) *resource.Resource {
|
||||
}
|
||||
|
||||
// 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 (
|
||||
nkind number.Kind
|
||||
ikind sdkapi.InstrumentKind
|
||||
@ -167,7 +167,7 @@ func convertDescriptor(ocDescriptor metricdata.Descriptor) (metric.Descriptor, e
|
||||
ikind = sdkapi.CounterObserverInstrumentKind
|
||||
default:
|
||||
// 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{
|
||||
metric.WithDescription(ocDescriptor.Description),
|
||||
@ -181,5 +181,5 @@ func convertDescriptor(ocDescriptor metricdata.Descriptor) (metric.Descriptor, e
|
||||
opts = append(opts, metric.WithUnit(unit.Milliseconds))
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ func TestConvertDescriptor(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
input metricdata.Descriptor
|
||||
expected metric.Descriptor
|
||||
expected sdkapi.Descriptor
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"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"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
@ -96,7 +96,7 @@ func (e *Exporter) Shutdown(ctx context.Context) error {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
@ -101,18 +100,18 @@ func TestStringKeyValues(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]
|
||||
|
||||
assert.NoError(t, mmsc.Update(context.Background(), 1, &metric.Descriptor{}))
|
||||
assert.NoError(t, mmsc.Update(context.Background(), 10, &metric.Descriptor{}))
|
||||
assert.NoError(t, mmsc.Update(context.Background(), 1, &sdkapi.Descriptor{}))
|
||||
assert.NoError(t, mmsc.Update(context.Background(), 10, &sdkapi.Descriptor{}))
|
||||
|
||||
// Prior to checkpointing ErrNoData should be returned.
|
||||
_, _, _, _, err := minMaxSumCountValues(ckpt)
|
||||
assert.EqualError(t, err, aggregation.ErrNoData.Error())
|
||||
|
||||
// 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)
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, min, number.NewInt64Number(1))
|
||||
@ -125,7 +124,7 @@ func TestMinMaxSumCountValue(t *testing.T) {
|
||||
func TestMinMaxSumCountDatapoints(t *testing.T) {
|
||||
desc := metrictest.NewDescriptor("", sdkapi.HistogramInstrumentKind, number.Int64Kind)
|
||||
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]
|
||||
|
||||
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
|
||||
// a MinMaxSumCount Aggregator. Use this fact to check the error is
|
||||
// correctly returned.
|
||||
mmsc := &minmaxsumcount.New(1, &metric.Descriptor{})[0]
|
||||
mmsc := &minmaxsumcount.New(1, &sdkapi.Descriptor{})[0]
|
||||
_, _, _, _, err := minMaxSumCountValues(mmsc)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, aggregation.ErrNoData, err)
|
||||
@ -390,13 +389,13 @@ func (t *testAgg) Aggregation() aggregation.Aggregation {
|
||||
|
||||
// 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
|
||||
}
|
||||
func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *metric.Descriptor) error {
|
||||
func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *sdkapi.Descriptor) error {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
@ -132,7 +133,7 @@ func (e *Exporter) Controller() *controller.Controller {
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
exportmetric "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
@ -47,7 +47,7 @@ type line struct {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"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
|
||||
@ -33,7 +33,7 @@ var ErrInvalidAsyncRunner = errors.New("unknown async runner type")
|
||||
// the SDK to provide support for running observer callbacks.
|
||||
type AsyncCollector interface {
|
||||
// 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
|
||||
@ -61,18 +61,18 @@ type AsyncInstrumentState struct {
|
||||
|
||||
// instruments maintains the set of instruments in the order
|
||||
// they were registered.
|
||||
instruments []metric.AsyncImpl
|
||||
instruments []sdkapi.AsyncImpl
|
||||
}
|
||||
|
||||
// asyncRunnerPair is a map entry for Observer callback runners.
|
||||
type asyncRunnerPair struct {
|
||||
// runner is used as a map key here. The API ensures
|
||||
// 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
|
||||
// AsyncSingleRunner.
|
||||
inst metric.AsyncImpl
|
||||
inst sdkapi.AsyncImpl
|
||||
}
|
||||
|
||||
// NewAsyncInstrumentState returns a new *AsyncInstrumentState, for
|
||||
@ -87,7 +87,7 @@ func NewAsyncInstrumentState() *AsyncInstrumentState {
|
||||
// Instruments returns the asynchronous instruments managed by this
|
||||
// object, the set that should be checkpointed after observers are
|
||||
// run.
|
||||
func (a *AsyncInstrumentState) Instruments() []metric.AsyncImpl {
|
||||
func (a *AsyncInstrumentState) Instruments() []sdkapi.AsyncImpl {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
return a.instruments
|
||||
@ -97,7 +97,7 @@ func (a *AsyncInstrumentState) Instruments() []metric.AsyncImpl {
|
||||
// object. This should be called during NewAsyncInstrument() and
|
||||
// assumes that errors (e.g., duplicate registration) have already
|
||||
// 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()
|
||||
defer a.lock.Unlock()
|
||||
|
||||
@ -111,7 +111,7 @@ func (a *AsyncInstrumentState) Register(inst metric.AsyncImpl, runner metric.Asy
|
||||
rp := asyncRunnerPair{
|
||||
runner: runner,
|
||||
}
|
||||
if _, ok := runner.(metric.AsyncSingleRunner); ok {
|
||||
if _, ok := runner.(sdkapi.AsyncSingleRunner); ok {
|
||||
rp.inst = inst
|
||||
}
|
||||
|
||||
@ -132,12 +132,12 @@ func (a *AsyncInstrumentState) Run(ctx context.Context, collector AsyncCollector
|
||||
// other implementations are possible because the
|
||||
// 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)
|
||||
continue
|
||||
}
|
||||
|
||||
if multiRunner, ok := rp.runner.(metric.AsyncBatchRunner); ok {
|
||||
if multiRunner, ok := rp.runner.(sdkapi.AsyncBatchRunner); ok {
|
||||
multiRunner.Run(ctx, collector.CollectAsync)
|
||||
continue
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"go.opentelemetry.io/otel/internal/metric/registry"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
// This file contains the forwarding implementation of MeterProvider used as
|
||||
@ -73,42 +74,42 @@ type meterImpl struct {
|
||||
}
|
||||
|
||||
type meterEntry struct {
|
||||
unique metric.MeterImpl
|
||||
unique sdkapi.MeterImpl
|
||||
impl meterImpl
|
||||
}
|
||||
|
||||
type instrument struct {
|
||||
descriptor metric.Descriptor
|
||||
descriptor sdkapi.Descriptor
|
||||
}
|
||||
|
||||
type syncImpl struct {
|
||||
delegate unsafe.Pointer // (*metric.SyncImpl)
|
||||
delegate unsafe.Pointer // (*sdkapi.SyncImpl)
|
||||
|
||||
instrument
|
||||
}
|
||||
|
||||
type asyncImpl struct {
|
||||
delegate unsafe.Pointer // (*metric.AsyncImpl)
|
||||
delegate unsafe.Pointer // (*sdkapi.AsyncImpl)
|
||||
|
||||
instrument
|
||||
|
||||
runner metric.AsyncRunner
|
||||
runner sdkapi.AsyncRunner
|
||||
}
|
||||
|
||||
// SyncImpler is implemented by all of the sync metric
|
||||
// instruments.
|
||||
type SyncImpler interface {
|
||||
SyncImpl() metric.SyncImpl
|
||||
SyncImpl() sdkapi.SyncImpl
|
||||
}
|
||||
|
||||
// AsyncImpler is implemented by all of the async
|
||||
// metric instruments.
|
||||
type AsyncImpler interface {
|
||||
AsyncImpl() metric.AsyncImpl
|
||||
AsyncImpl() sdkapi.AsyncImpl
|
||||
}
|
||||
|
||||
type syncHandle struct {
|
||||
delegate unsafe.Pointer // (*metric.BoundInstrumentImpl)
|
||||
delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
|
||||
|
||||
inst *syncImpl
|
||||
labels []attribute.KeyValue
|
||||
@ -117,12 +118,12 @@ type syncHandle struct {
|
||||
}
|
||||
|
||||
var _ metric.MeterProvider = &meterProvider{}
|
||||
var _ metric.MeterImpl = &meterImpl{}
|
||||
var _ metric.InstrumentImpl = &syncImpl{}
|
||||
var _ metric.BoundSyncImpl = &syncHandle{}
|
||||
var _ metric.AsyncImpl = &asyncImpl{}
|
||||
var _ sdkapi.MeterImpl = &meterImpl{}
|
||||
var _ sdkapi.InstrumentImpl = &syncImpl{}
|
||||
var _ sdkapi.BoundSyncImpl = &syncHandle{}
|
||||
var _ sdkapi.AsyncImpl = &asyncImpl{}
|
||||
|
||||
func (inst *instrument) Descriptor() metric.Descriptor {
|
||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
|
||||
return inst.descriptor
|
||||
}
|
||||
|
||||
@ -179,7 +180,7 @@ func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
|
||||
d := new(metric.MeterImpl)
|
||||
d := new(sdkapi.MeterImpl)
|
||||
*d = provider.Meter(
|
||||
key.InstrumentationName,
|
||||
metric.WithInstrumentationVersion(key.InstrumentationVersion),
|
||||
@ -197,11 +198,11 @@ func (m *meterImpl) setDelegate(key meterKey, provider metric.MeterProvider) {
|
||||
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()
|
||||
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)
|
||||
}
|
||||
|
||||
@ -216,8 +217,8 @@ func (m *meterImpl) NewSyncInstrument(desc metric.Descriptor) (metric.SyncImpl,
|
||||
|
||||
// Synchronous delegation
|
||||
|
||||
func (inst *syncImpl) setDelegate(d metric.MeterImpl) {
|
||||
implPtr := new(metric.SyncImpl)
|
||||
func (inst *syncImpl) setDelegate(d sdkapi.MeterImpl) {
|
||||
implPtr := new(sdkapi.SyncImpl)
|
||||
|
||||
var err error
|
||||
*implPtr, err = d.NewSyncInstrument(inst.descriptor)
|
||||
@ -234,14 +235,14 @@ func (inst *syncImpl) setDelegate(d metric.MeterImpl) {
|
||||
}
|
||||
|
||||
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 inst
|
||||
}
|
||||
|
||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl {
|
||||
if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
|
||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
|
||||
return (*implPtr).Bind(labels)
|
||||
}
|
||||
return &syncHandle{
|
||||
@ -253,7 +254,7 @@ func (inst *syncImpl) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl {
|
||||
func (bound *syncHandle) Unbind() {
|
||||
bound.initialize.Do(func() {})
|
||||
|
||||
implPtr := (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
||||
implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
||||
|
||||
if implPtr == nil {
|
||||
return
|
||||
@ -265,14 +266,14 @@ func (bound *syncHandle) Unbind() {
|
||||
// Async delegation
|
||||
|
||||
func (m *meterImpl) NewAsyncInstrument(
|
||||
desc metric.Descriptor,
|
||||
runner metric.AsyncRunner,
|
||||
) (metric.AsyncImpl, error) {
|
||||
desc sdkapi.Descriptor,
|
||||
runner sdkapi.AsyncRunner,
|
||||
) (sdkapi.AsyncImpl, error) {
|
||||
|
||||
m.lock.Lock()
|
||||
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)
|
||||
}
|
||||
|
||||
@ -287,14 +288,14 @@ func (m *meterImpl) NewAsyncInstrument(
|
||||
}
|
||||
|
||||
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 obs
|
||||
}
|
||||
|
||||
func (obs *asyncImpl) setDelegate(d metric.MeterImpl) {
|
||||
implPtr := new(metric.AsyncImpl)
|
||||
func (obs *asyncImpl) setDelegate(d sdkapi.MeterImpl) {
|
||||
implPtr := new(sdkapi.AsyncImpl)
|
||||
|
||||
var err error
|
||||
*implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner)
|
||||
@ -312,14 +313,14 @@ func (obs *asyncImpl) setDelegate(d metric.MeterImpl) {
|
||||
|
||||
// Metric updates
|
||||
|
||||
func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...metric.Measurement) {
|
||||
if delegatePtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
|
||||
func (m *meterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
|
||||
if delegatePtr := (*sdkapi.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
|
||||
(*delegatePtr).RecordBatch(ctx, labels, measurements...)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -327,18 +328,18 @@ func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, label
|
||||
// Bound instrument initialization
|
||||
|
||||
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
|
||||
instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
|
||||
instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
|
||||
if instPtr == nil {
|
||||
return
|
||||
}
|
||||
var implPtr *metric.BoundSyncImpl
|
||||
var implPtr *sdkapi.BoundSyncImpl
|
||||
bound.initialize.Do(func() {
|
||||
implPtr = new(metric.BoundSyncImpl)
|
||||
implPtr = new(sdkapi.BoundSyncImpl)
|
||||
*implPtr = (*instPtr).Bind(bound.labels)
|
||||
atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
|
||||
})
|
||||
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
|
||||
// without a delegate, then the instrument was set to have a
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
metricglobal "go.opentelemetry.io/otel/metric/global"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
var Must = metric.Must
|
||||
@ -232,15 +233,15 @@ type meterProviderWithConstructorError struct {
|
||||
}
|
||||
|
||||
type meterWithConstructorError struct {
|
||||
metric.MeterImpl
|
||||
sdkapi.MeterImpl
|
||||
}
|
||||
|
||||
func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter {
|
||||
return metric.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()})
|
||||
}
|
||||
|
||||
func (m *meterWithConstructorError) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) {
|
||||
return metric.NoopSync{}, errors.New("constructor error")
|
||||
func (m *meterWithConstructorError) NewSyncInstrument(_ sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
|
||||
return sdkapi.NewNoopSyncInstrument(), errors.New("constructor error")
|
||||
}
|
||||
|
||||
func TestErrorInDeferredConstructor(t *testing.T) {
|
||||
|
@ -24,46 +24,47 @@ import (
|
||||
"go.opentelemetry.io/otel/internal/metric/registry"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
type (
|
||||
newFunc func(name, libraryName string) (metric.InstrumentImpl, error)
|
||||
newFunc func(name, libraryName string) (sdkapi.InstrumentImpl, error)
|
||||
)
|
||||
|
||||
var (
|
||||
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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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) {}))
|
||||
},
|
||||
"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) {}))
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) {
|
||||
func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) {
|
||||
if impl == nil {
|
||||
return nil, err
|
||||
}
|
||||
if s, ok := impl.(interface {
|
||||
SyncImpl() metric.SyncImpl
|
||||
SyncImpl() sdkapi.SyncImpl
|
||||
}); ok {
|
||||
return s.SyncImpl(), err
|
||||
}
|
||||
if a, ok := impl.(interface {
|
||||
AsyncImpl() metric.AsyncImpl
|
||||
AsyncImpl() sdkapi.AsyncImpl
|
||||
}); ok {
|
||||
return a.AsyncImpl(), err
|
||||
}
|
||||
|
@ -20,18 +20,18 @@ import (
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
// UniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding
|
||||
// uniqueness checking for instrument descriptors.
|
||||
type UniqueInstrumentMeterImpl struct {
|
||||
lock sync.Mutex
|
||||
impl metric.MeterImpl
|
||||
state map[string]metric.InstrumentImpl
|
||||
impl sdkapi.MeterImpl
|
||||
state map[string]sdkapi.InstrumentImpl
|
||||
}
|
||||
|
||||
var _ metric.MeterImpl = (*UniqueInstrumentMeterImpl)(nil)
|
||||
var _ sdkapi.MeterImpl = (*UniqueInstrumentMeterImpl)(nil)
|
||||
|
||||
// ErrMetricKindMismatch is the standard error for mismatched metric
|
||||
// instrument definitions.
|
||||
@ -40,27 +40,27 @@ var ErrMetricKindMismatch = fmt.Errorf(
|
||||
|
||||
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl
|
||||
// with the addition of instrument name uniqueness checking.
|
||||
func NewUniqueInstrumentMeterImpl(impl metric.MeterImpl) *UniqueInstrumentMeterImpl {
|
||||
func NewUniqueInstrumentMeterImpl(impl sdkapi.MeterImpl) *UniqueInstrumentMeterImpl {
|
||||
return &UniqueInstrumentMeterImpl{
|
||||
impl: impl,
|
||||
state: map[string]metric.InstrumentImpl{},
|
||||
state: map[string]sdkapi.InstrumentImpl{},
|
||||
}
|
||||
}
|
||||
|
||||
// MeterImpl gives the caller access to the underlying MeterImpl
|
||||
// used by this UniqueInstrumentMeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) MeterImpl() metric.MeterImpl {
|
||||
func (u *UniqueInstrumentMeterImpl) MeterImpl() sdkapi.MeterImpl {
|
||||
return u.impl
|
||||
}
|
||||
|
||||
// RecordBatch implements metric.MeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...metric.Measurement) {
|
||||
// RecordBatch implements sdkapi.MeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, ms ...sdkapi.Measurement) {
|
||||
u.impl.RecordBatch(ctx, labels, ms...)
|
||||
}
|
||||
|
||||
// NewMetricKindMismatchError formats an error that describes a
|
||||
// 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",
|
||||
desc.Name(),
|
||||
desc.NumberKind(),
|
||||
@ -68,9 +68,9 @@ func NewMetricKindMismatchError(desc metric.Descriptor) error {
|
||||
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.
|
||||
func Compatible(candidate, existing metric.Descriptor) bool {
|
||||
func Compatible(candidate, existing sdkapi.Descriptor) bool {
|
||||
return candidate.InstrumentKind() == existing.InstrumentKind() &&
|
||||
candidate.NumberKind() == existing.NumberKind()
|
||||
}
|
||||
@ -80,7 +80,7 @@ func Compatible(candidate, existing metric.Descriptor) bool {
|
||||
// `descriptor` argument. If there is an existing compatible
|
||||
// registration, this returns the already-registered instrument. If
|
||||
// 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()]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
@ -93,8 +93,8 @@ func (u *UniqueInstrumentMeterImpl) checkUniqueness(descriptor metric.Descriptor
|
||||
return impl, nil
|
||||
}
|
||||
|
||||
// NewSyncInstrument implements metric.MeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) {
|
||||
// NewSyncInstrument implements sdkapi.MeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
|
||||
u.lock.Lock()
|
||||
defer u.lock.Unlock()
|
||||
|
||||
@ -103,7 +103,7 @@ func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descript
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if impl != nil {
|
||||
return impl.(metric.SyncImpl), nil
|
||||
return impl.(sdkapi.SyncImpl), nil
|
||||
}
|
||||
|
||||
syncInst, err := u.impl.NewSyncInstrument(descriptor)
|
||||
@ -114,11 +114,11 @@ func (u *UniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descript
|
||||
return syncInst, nil
|
||||
}
|
||||
|
||||
// NewAsyncInstrument implements metric.MeterImpl.
|
||||
// NewAsyncInstrument implements sdkapi.MeterImpl.
|
||||
func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
|
||||
descriptor metric.Descriptor,
|
||||
runner metric.AsyncRunner,
|
||||
) (metric.AsyncImpl, error) {
|
||||
descriptor sdkapi.Descriptor,
|
||||
runner sdkapi.AsyncRunner,
|
||||
) (sdkapi.AsyncImpl, error) {
|
||||
u.lock.Lock()
|
||||
defer u.lock.Unlock()
|
||||
|
||||
@ -127,7 +127,7 @@ func (u *UniqueInstrumentMeterImpl) NewAsyncInstrument(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if impl != nil {
|
||||
return impl.(metric.AsyncImpl), nil
|
||||
return impl.(sdkapi.AsyncImpl), nil
|
||||
}
|
||||
|
||||
asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner)
|
||||
|
@ -24,46 +24,47 @@ import (
|
||||
"go.opentelemetry.io/otel/internal/metric/registry"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
type (
|
||||
newFunc func(m metric.Meter, name string) (metric.InstrumentImpl, error)
|
||||
newFunc func(m metric.Meter, name string) (sdkapi.InstrumentImpl, error)
|
||||
)
|
||||
|
||||
var (
|
||||
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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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))
|
||||
},
|
||||
"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) {}))
|
||||
},
|
||||
"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) {}))
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) {
|
||||
func unwrap(impl interface{}, err error) (sdkapi.InstrumentImpl, error) {
|
||||
if impl == nil {
|
||||
return nil, err
|
||||
}
|
||||
if s, ok := impl.(interface {
|
||||
SyncImpl() metric.SyncImpl
|
||||
SyncImpl() sdkapi.SyncImpl
|
||||
}); ok {
|
||||
return s.SyncImpl(), err
|
||||
}
|
||||
if a, ok := impl.(interface {
|
||||
AsyncImpl() metric.AsyncImpl
|
||||
AsyncImpl() sdkapi.AsyncImpl
|
||||
}); ok {
|
||||
return a.AsyncImpl(), err
|
||||
}
|
||||
|
117
metric/metric.go
117
metric/metric.go
@ -20,7 +20,6 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
"go.opentelemetry.io/otel/metric/unit"
|
||||
)
|
||||
|
||||
// MeterProvider supports named Meter instances.
|
||||
@ -38,9 +37,33 @@ type MeterProvider interface {
|
||||
//
|
||||
// An uninitialized Meter is a no-op implementation.
|
||||
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.
|
||||
func (m Meter) RecordBatch(ctx context.Context, ls []attribute.KeyValue, ms ...Measurement) {
|
||||
if m.impl == nil {
|
||||
@ -118,7 +141,7 @@ func (m Meter) NewFloat64Histogram(name string, opts ...InstrumentOption) (Float
|
||||
// or improperly registered (e.g., duplicate registration).
|
||||
func (m Meter) NewInt64GaugeObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64GaugeObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapInt64GaugeObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64GaugeObserverInstrument(
|
||||
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).
|
||||
func (m Meter) NewFloat64GaugeObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64GaugeObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapFloat64GaugeObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64GaugeObserverInstrument(
|
||||
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).
|
||||
func (m Meter) NewInt64CounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64CounterObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapInt64CounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64CounterObserverInstrument(
|
||||
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).
|
||||
func (m Meter) NewFloat64CounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64CounterObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapFloat64CounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64CounterObserverInstrument(
|
||||
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).
|
||||
func (m Meter) NewInt64UpDownCounterObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapInt64UpDownCounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64UpDownCounterObserverInstrument(
|
||||
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).
|
||||
func (m Meter) NewFloat64UpDownCounterObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
|
||||
if callback == nil {
|
||||
return wrapFloat64UpDownCounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64UpDownCounterObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewInt64GaugeObserver(name string, opts ...InstrumentOption) (Int64GaugeObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapInt64GaugeObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64GaugeObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewFloat64GaugeObserver(name string, opts ...InstrumentOption) (Float64GaugeObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapFloat64GaugeObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64GaugeObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64GaugeObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewInt64CounterObserver(name string, opts ...InstrumentOption) (Int64CounterObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapInt64CounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64CounterObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewFloat64CounterObserver(name string, opts ...InstrumentOption) (Float64CounterObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapFloat64CounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64CounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64CounterObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewInt64UpDownCounterObserver(name string, opts ...InstrumentOption) (Int64UpDownCounterObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapInt64UpDownCounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapInt64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapInt64UpDownCounterObserverInstrument(
|
||||
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).
|
||||
func (b BatchObserver) NewFloat64UpDownCounterObserver(name string, opts ...InstrumentOption) (Float64UpDownCounterObserver, error) {
|
||||
if b.runner == nil {
|
||||
return wrapFloat64UpDownCounterObserverInstrument(NoopAsync{}, nil)
|
||||
return wrapFloat64UpDownCounterObserverInstrument(sdkapi.NewNoopAsyncInstrument(), nil)
|
||||
}
|
||||
return wrapFloat64UpDownCounterObserverInstrument(
|
||||
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.
|
||||
func (m Meter) MeterImpl() MeterImpl {
|
||||
func (m Meter) MeterImpl() sdkapi.MeterImpl {
|
||||
return m.impl
|
||||
}
|
||||
|
||||
@ -276,16 +299,16 @@ func (m Meter) newAsync(
|
||||
mkind sdkapi.InstrumentKind,
|
||||
nkind number.Kind,
|
||||
opts []InstrumentOption,
|
||||
runner AsyncRunner,
|
||||
runner sdkapi.AsyncRunner,
|
||||
) (
|
||||
AsyncImpl,
|
||||
sdkapi.AsyncImpl,
|
||||
error,
|
||||
) {
|
||||
if m.impl == nil {
|
||||
return NoopAsync{}, nil
|
||||
return sdkapi.NewNoopAsyncInstrument(), nil
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@ -296,14 +319,14 @@ func (m Meter) newSync(
|
||||
numberKind number.Kind,
|
||||
opts []InstrumentOption,
|
||||
) (
|
||||
SyncImpl,
|
||||
sdkapi.SyncImpl,
|
||||
error,
|
||||
) {
|
||||
if m.impl == nil {
|
||||
return NoopSync{}, nil
|
||||
return sdkapi.NewNoopSyncInstrument(), nil
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@ -513,53 +536,3 @@ func (bm BatchObserverMust) NewFloat64UpDownCounterObserver(name string, oos ...
|
||||
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
|
||||
}
|
||||
|
@ -20,20 +20,12 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
)
|
||||
|
||||
// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
|
||||
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
|
||||
// observers run.
|
||||
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
|
||||
// observations for one asynchronous integer metric instrument.
|
||||
type Int64ObserverResult struct {
|
||||
instrument AsyncImpl
|
||||
instrument sdkapi.AsyncImpl
|
||||
function func([]attribute.KeyValue, ...Observation)
|
||||
}
|
||||
|
||||
// Float64ObserverResult is passed to an observer callback to capture
|
||||
// observations for one asynchronous floating point metric instrument.
|
||||
type Float64ObserverResult struct {
|
||||
instrument AsyncImpl
|
||||
instrument sdkapi.AsyncImpl
|
||||
function func([]attribute.KeyValue, ...Observation)
|
||||
}
|
||||
|
||||
@ -70,19 +62,13 @@ type BatchObserverResult struct {
|
||||
// Observe captures a single integer value from the associated
|
||||
// instrument callback, with the given labels.
|
||||
func (ir Int64ObserverResult) Observe(value int64, labels ...attribute.KeyValue) {
|
||||
ir.function(labels, Observation{
|
||||
instrument: ir.instrument,
|
||||
number: number.NewInt64Number(value),
|
||||
})
|
||||
ir.function(labels, sdkapi.NewObservation(ir.instrument, number.NewInt64Number(value)))
|
||||
}
|
||||
|
||||
// Observe captures a single floating point value from the associated
|
||||
// instrument callback, with the given labels.
|
||||
func (fr Float64ObserverResult) Observe(value float64, labels ...attribute.KeyValue) {
|
||||
fr.function(labels, Observation{
|
||||
instrument: fr.instrument,
|
||||
number: number.NewFloat64Number(value),
|
||||
})
|
||||
fr.function(labels, sdkapi.NewObservation(fr.instrument, number.NewFloat64Number(value)))
|
||||
}
|
||||
|
||||
// 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...)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil)
|
||||
var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil)
|
||||
var _ AsyncBatchRunner = (*BatchObserverFunc)(nil)
|
||||
var _ sdkapi.AsyncSingleRunner = (*Int64ObserverFunc)(nil)
|
||||
var _ sdkapi.AsyncSingleRunner = (*Float64ObserverFunc)(nil)
|
||||
var _ sdkapi.AsyncBatchRunner = (*BatchObserverFunc)(nil)
|
||||
|
||||
// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
|
||||
func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner {
|
||||
func newInt64AsyncRunner(c Int64ObserverFunc) sdkapi.AsyncSingleRunner {
|
||||
return &c
|
||||
}
|
||||
|
||||
// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
|
||||
func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner {
|
||||
func newFloat64AsyncRunner(c Float64ObserverFunc) sdkapi.AsyncSingleRunner {
|
||||
return &c
|
||||
}
|
||||
|
||||
// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
|
||||
func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner {
|
||||
func newBatchAsyncRunner(c BatchObserverFunc) sdkapi.AsyncBatchRunner {
|
||||
return &c
|
||||
}
|
||||
|
||||
@ -152,7 +106,7 @@ func (*Float64ObserverFunc) AnyRunner() {}
|
||||
func (*BatchObserverFunc) AnyRunner() {}
|
||||
|
||||
// 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{
|
||||
instrument: impl,
|
||||
function: function,
|
||||
@ -160,7 +114,7 @@ func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function fu
|
||||
}
|
||||
|
||||
// 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{
|
||||
instrument: impl,
|
||||
function: function,
|
||||
@ -175,37 +129,37 @@ func (b *BatchObserverFunc) Run(ctx context.Context, function func([]attribute.K
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64GaugeObserver{asyncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64GaugeObserver{asyncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64CounterObserver{asyncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64CounterObserver{asyncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64UpDownCounterObserver{asyncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64UpDownCounterObserver{asyncInstrument: common}, err
|
||||
}
|
||||
@ -214,7 +168,7 @@ func wrapFloat64UpDownCounterObserverInstrument(asyncInst AsyncImpl, err error)
|
||||
// observations for multiple instruments.
|
||||
type BatchObserver struct {
|
||||
meter Meter
|
||||
runner AsyncBatchRunner
|
||||
runner sdkapi.AsyncBatchRunner
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (i Int64GaugeObserver) Observation(v int64) Observation {
|
||||
return Observation{
|
||||
number: number.NewInt64Number(v),
|
||||
instrument: i.instrument,
|
||||
}
|
||||
return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (f Float64GaugeObserver) Observation(v float64) Observation {
|
||||
return Observation{
|
||||
number: number.NewFloat64Number(v),
|
||||
instrument: f.instrument,
|
||||
}
|
||||
return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (i Int64CounterObserver) Observation(v int64) Observation {
|
||||
return Observation{
|
||||
number: number.NewInt64Number(v),
|
||||
instrument: i.instrument,
|
||||
}
|
||||
return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (f Float64CounterObserver) Observation(v float64) Observation {
|
||||
return Observation{
|
||||
number: number.NewFloat64Number(v),
|
||||
instrument: f.instrument,
|
||||
}
|
||||
return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (i Int64UpDownCounterObserver) Observation(v int64) Observation {
|
||||
return Observation{
|
||||
number: number.NewInt64Number(v),
|
||||
instrument: i.instrument,
|
||||
}
|
||||
return sdkapi.NewObservation(i.instrument, number.NewInt64Number(v))
|
||||
}
|
||||
|
||||
// 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,
|
||||
// users should not refer to this.
|
||||
func (f Float64UpDownCounterObserver) Observation(v float64) Observation {
|
||||
return Observation{
|
||||
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
|
||||
return sdkapi.NewObservation(f.instrument, number.NewFloat64Number(v))
|
||||
}
|
||||
|
||||
// syncInstrument contains a SyncImpl.
|
||||
type syncInstrument struct {
|
||||
instrument SyncImpl
|
||||
instrument sdkapi.SyncImpl
|
||||
}
|
||||
|
||||
// syncBoundInstrument contains a BoundSyncImpl.
|
||||
type syncBoundInstrument struct {
|
||||
boundInstrument BoundSyncImpl
|
||||
boundInstrument sdkapi.BoundSyncImpl
|
||||
}
|
||||
|
||||
// asyncInstrument contains a AsyncImpl.
|
||||
type asyncInstrument struct {
|
||||
instrument 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
|
||||
instrument sdkapi.AsyncImpl
|
||||
}
|
||||
|
||||
// AsyncImpl implements AsyncImpl.
|
||||
func (a asyncInstrument) AsyncImpl() AsyncImpl {
|
||||
func (a asyncInstrument) AsyncImpl() sdkapi.AsyncImpl {
|
||||
return a.instrument
|
||||
}
|
||||
|
||||
// SyncImpl returns the implementation object for synchronous instruments.
|
||||
func (s syncInstrument) SyncImpl() SyncImpl {
|
||||
func (s syncInstrument) SyncImpl() sdkapi.SyncImpl {
|
||||
return s.instrument
|
||||
}
|
||||
|
||||
@ -382,11 +285,11 @@ func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument {
|
||||
}
|
||||
|
||||
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 {
|
||||
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) {
|
||||
@ -405,12 +308,12 @@ func (h syncBoundInstrument) Unbind() {
|
||||
// checkNewAsync receives an AsyncImpl and potential
|
||||
// error, and returns the same types, checking for and ensuring that
|
||||
// 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 err == nil {
|
||||
err = ErrSDKReturnedNilImpl
|
||||
}
|
||||
instrument = NoopAsync{}
|
||||
instrument = sdkapi.NewNoopAsyncInstrument()
|
||||
}
|
||||
return asyncInstrument{
|
||||
instrument: instrument,
|
||||
@ -420,7 +323,7 @@ func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) {
|
||||
// checkNewSync receives an SyncImpl and potential
|
||||
// error, and returns the same types, checking for and ensuring that
|
||||
// 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 err == nil {
|
||||
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.,
|
||||
// name = 'invalid.counter.int64'
|
||||
// label = 'original-name=duplicate-counter-name'
|
||||
instrument = NoopSync{}
|
||||
instrument = sdkapi.NewNoopSyncInstrument()
|
||||
}
|
||||
return syncInstrument{
|
||||
instrument: instrument,
|
||||
}, err
|
||||
}
|
||||
|
||||
func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument {
|
||||
func newSyncBoundInstrument(boundInstrument sdkapi.BoundSyncImpl) syncBoundInstrument {
|
||||
return syncBoundInstrument{
|
||||
boundInstrument: boundInstrument,
|
||||
}
|
||||
}
|
||||
|
||||
func newMeasurement(instrument SyncImpl, number number.Number) Measurement {
|
||||
return Measurement{
|
||||
instrument: instrument,
|
||||
number: number,
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64Counter{syncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64Counter{syncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64UpDownCounter{syncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64UpDownCounter{syncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Int64Histogram{syncInstrument: common}, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
return Float64Histogram{syncInstrument: common}, err
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
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()
|
||||
assert.Len(t, 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 {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@ -502,6 +502,8 @@ func TestNilCallbackObserverNoop(t *testing.T) {
|
||||
|
||||
observer := Must(meter).NewInt64GaugeObserver("test.observer", nil)
|
||||
|
||||
_, ok := observer.AsyncImpl().(metric.NoopAsync)
|
||||
require.True(t, ok)
|
||||
impl := observer.AsyncImpl().Implementation()
|
||||
desc := observer.AsyncImpl().Descriptor()
|
||||
require.Equal(t, nil, impl)
|
||||
require.Equal(t, "", desc.Name())
|
||||
}
|
||||
|
@ -66,18 +66,18 @@ type (
|
||||
Measurement struct {
|
||||
// Number needs to be aligned for 64-bit atomic operations.
|
||||
Number number.Number
|
||||
Instrument metric.InstrumentImpl
|
||||
Instrument sdkapi.InstrumentImpl
|
||||
}
|
||||
|
||||
Instrument struct {
|
||||
meter *MeterImpl
|
||||
descriptor metric.Descriptor
|
||||
descriptor sdkapi.Descriptor
|
||||
}
|
||||
|
||||
Async struct {
|
||||
Instrument
|
||||
|
||||
runner metric.AsyncRunner
|
||||
runner sdkapi.AsyncRunner
|
||||
}
|
||||
|
||||
Sync struct {
|
||||
@ -86,20 +86,20 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
_ metric.SyncImpl = &Sync{}
|
||||
_ metric.BoundSyncImpl = &Handle{}
|
||||
_ metric.MeterImpl = &MeterImpl{}
|
||||
_ metric.AsyncImpl = &Async{}
|
||||
_ sdkapi.SyncImpl = &Sync{}
|
||||
_ sdkapi.BoundSyncImpl = &Handle{}
|
||||
_ sdkapi.MeterImpl = &MeterImpl{}
|
||||
_ sdkapi.AsyncImpl = &Async{}
|
||||
)
|
||||
|
||||
// NewDescriptor is a test helper for constructing test metric
|
||||
// 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...)
|
||||
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
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ func (s *Sync) Implementation() interface{} {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Sync) Bind(labels []attribute.KeyValue) metric.BoundSyncImpl {
|
||||
func (s *Sync) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
return &Handle{
|
||||
Instrument: s,
|
||||
Labels: labels,
|
||||
@ -129,7 +129,7 @@ func (h *Handle) RecordOne(ctx context.Context, number number.Number) {
|
||||
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{{
|
||||
Instrument: instrument,
|
||||
Number: number,
|
||||
@ -160,8 +160,8 @@ func (p *MeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Me
|
||||
return metric.WrapMeterImpl(impl)
|
||||
}
|
||||
|
||||
// NewSyncInstrument implements metric.MeterImpl.
|
||||
func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) {
|
||||
// NewSyncInstrument implements sdkapi.MeterImpl.
|
||||
func (m *MeterImpl) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
|
||||
return &Sync{
|
||||
Instrument{
|
||||
descriptor: descriptor,
|
||||
@ -170,8 +170,8 @@ func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (metric.Sync
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewAsyncInstrument implements metric.MeterImpl.
|
||||
func (m *MeterImpl) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (metric.AsyncImpl, error) {
|
||||
// NewAsyncInstrument implements sdkapi.MeterImpl.
|
||||
func (m *MeterImpl) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
|
||||
a := &Async{
|
||||
Instrument: Instrument{
|
||||
descriptor: descriptor,
|
||||
@ -183,8 +183,8 @@ func (m *MeterImpl) NewAsyncInstrument(descriptor metric.Descriptor, runner metr
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// RecordBatch implements metric.MeterImpl.
|
||||
func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...metric.Measurement) {
|
||||
// RecordBatch implements sdkapi.MeterImpl.
|
||||
func (m *MeterImpl) RecordBatch(ctx context.Context, labels []attribute.KeyValue, measurements ...sdkapi.Measurement) {
|
||||
mm := make([]Measurement, len(measurements))
|
||||
for i := 0; i < len(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.
|
||||
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))
|
||||
for i := 0; i < len(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.
|
||||
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()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
|
@ -14,12 +14,7 @@
|
||||
|
||||
package metric // import "go.opentelemetry.io/otel/metric"
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
)
|
||||
type noopMeterProvider struct{}
|
||||
|
||||
// NewNoopMeterProvider returns an implementation of MeterProvider that
|
||||
// performs no operations. The Meter and Instrument created from the returned
|
||||
@ -28,39 +23,8 @@ func NewNoopMeterProvider() MeterProvider {
|
||||
return noopMeterProvider{}
|
||||
}
|
||||
|
||||
type noopMeterProvider struct{}
|
||||
|
||||
type noopInstrument struct{}
|
||||
type noopBoundInstrument struct{}
|
||||
type NoopSync struct{ noopInstrument }
|
||||
type NoopAsync struct{ noopInstrument }
|
||||
|
||||
var _ MeterProvider = noopMeterProvider{}
|
||||
var _ SyncImpl = NoopSync{}
|
||||
var _ BoundSyncImpl = noopBoundInstrument{}
|
||||
var _ AsyncImpl = NoopAsync{}
|
||||
|
||||
func (noopMeterProvider) Meter(instrumentationName string, opts ...MeterOption) 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) {
|
||||
}
|
||||
|
70
metric/sdkapi/descriptor.go
Normal file
70
metric/sdkapi/descriptor.go
Normal 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
|
||||
}
|
@ -12,27 +12,22 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package metric
|
||||
package sdkapi
|
||||
|
||||
import (
|
||||
"os"
|
||||
"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 TestMain(m *testing.M) {
|
||||
fields := []internaltest.FieldOffset{
|
||||
{
|
||||
Name: "Measurement.number",
|
||||
Offset: unsafe.Offsetof(Measurement{}.number),
|
||||
},
|
||||
}
|
||||
if !internaltest.Aligned8Byte(fields, os.Stderr) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
func TestDescriptorGetters(t *testing.T) {
|
||||
d := NewDescriptor("name", HistogramInstrumentKind, number.Int64Kind, "my description", "my unit")
|
||||
require.Equal(t, "name", d.Name())
|
||||
require.Equal(t, HistogramInstrumentKind, d.InstrumentKind())
|
||||
require.Equal(t, number.Int64Kind, d.NumberKind())
|
||||
require.Equal(t, "my description", d.Description())
|
||||
require.Equal(t, unit.Unit("my unit"), d.Unit())
|
||||
}
|
64
metric/sdkapi/noop.go
Normal file
64
metric/sdkapi/noop.go
Normal 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
175
metric/sdkapi/sdkapi.go
Normal 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
|
||||
}
|
41
metric/sdkapi/sdkapi_test.go
Normal file
41
metric/sdkapi/sdkapi_test.go
Normal 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())
|
||||
}
|
@ -22,7 +22,6 @@ import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
@ -97,7 +96,7 @@ type AggregatorSelector interface {
|
||||
// Note: This is context-free because the aggregator should
|
||||
// not relate to the incoming context. This call should not
|
||||
// block.
|
||||
AggregatorFor(descriptor *metric.Descriptor, aggregator ...*Aggregator)
|
||||
AggregatorFor(descriptor *sdkapi.Descriptor, aggregator ...*Aggregator)
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// period of aggregation by atomically saving the
|
||||
@ -185,7 +184,7 @@ type Aggregator interface {
|
||||
//
|
||||
// When called with a nil `destination`, this Aggregator is reset
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
@ -203,7 +202,7 @@ type Aggregator interface {
|
||||
type Subtractor interface {
|
||||
// Subtract subtracts the `operand` from this Aggregator and
|
||||
// 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
|
||||
@ -233,7 +232,7 @@ type ExportKindSelector interface {
|
||||
// ExportKindFor should return the correct ExportKind that
|
||||
// should be used when exporting data for the given metric
|
||||
// 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
|
||||
@ -283,7 +282,7 @@ type Reader interface {
|
||||
// are shared by the Accumulator->Processor and Processor->Exporter
|
||||
// steps.
|
||||
type Metadata struct {
|
||||
descriptor *metric.Descriptor
|
||||
descriptor *sdkapi.Descriptor
|
||||
labels *attribute.Set
|
||||
}
|
||||
|
||||
@ -305,7 +304,7 @@ type Record struct {
|
||||
}
|
||||
|
||||
// Descriptor describes the metric instrument being exported.
|
||||
func (m Metadata) Descriptor() *metric.Descriptor {
|
||||
func (m Metadata) Descriptor() *sdkapi.Descriptor {
|
||||
return m.descriptor
|
||||
}
|
||||
|
||||
@ -319,7 +318,7 @@ func (m Metadata) Labels() *attribute.Set {
|
||||
// Accumulations to send to Processors. The Descriptor, Labels,
|
||||
// and Aggregator represent aggregate metric events received over a single
|
||||
// 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{
|
||||
Metadata: Metadata{
|
||||
descriptor: descriptor,
|
||||
@ -338,7 +337,7 @@ func (r Accumulation) Aggregator() Aggregator {
|
||||
// NewRecord allows Processor implementations to construct export
|
||||
// records. The Descriptor, Labels, and Aggregator represent
|
||||
// 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{
|
||||
Metadata: Metadata{
|
||||
descriptor: descriptor,
|
||||
@ -441,12 +440,12 @@ func StatelessExportKindSelector() 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)
|
||||
}
|
||||
|
||||
// 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() {
|
||||
return CumulativeExportKind
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
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
|
||||
// metric instrument does not support negative values, including
|
||||
// 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()
|
||||
|
||||
if numberKind == number.Float64Kind && math.IsNaN(num.AsFloat64()) {
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
@ -41,7 +40,7 @@ func TestInconsistentAggregatorErr(t *testing.T) {
|
||||
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
|
||||
nan := number.NewFloat64Number(math.NaN())
|
||||
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
|
||||
|
||||
if desc.NumberKind() == number.Float64Kind {
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ottest "go.opentelemetry.io/otel/internal/internaltest"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"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)
|
||||
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.
|
||||
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()
|
||||
|
||||
// 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 {
|
||||
t.Error("Unexpected Merge failure", err)
|
||||
}
|
||||
@ -181,19 +180,19 @@ func (NoopAggregator) Aggregation() aggregation.Aggregation {
|
||||
return NoopAggregation{}
|
||||
}
|
||||
|
||||
func (NoopAggregator) Update(context.Context, number.Number, *metric.Descriptor) error {
|
||||
func (NoopAggregator) Update(context.Context, number.Number, *sdkapi.Descriptor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NoopAggregator) SynchronizedMove(export.Aggregator, *metric.Descriptor) error {
|
||||
func (NoopAggregator) SynchronizedMove(export.Aggregator, *sdkapi.Descriptor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NoopAggregator) Merge(export.Aggregator, *metric.Descriptor) error {
|
||||
func (NoopAggregator) Merge(export.Aggregator, *sdkapi.Descriptor) error {
|
||||
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) {
|
||||
// Ensures that SynchronizedMove(nil, descriptor) discards and
|
||||
// resets the aggregator.
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"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
|
||||
// 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)
|
||||
|
||||
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 takes a lock to prevent concurrent Update() and SynchronizedMove()
|
||||
// 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()
|
||||
c.lock.Lock()
|
||||
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.
|
||||
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)
|
||||
if o == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
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)
|
||||
}
|
||||
|
||||
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) {
|
||||
func checkZero(t *testing.T, agg *Aggregator, desc *sdkapi.Descriptor) {
|
||||
count, err := agg.Count()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(0), count)
|
||||
@ -312,7 +311,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
|
||||
aggregatortest.SynchronizedMoveResetTest(
|
||||
t,
|
||||
sdkapi.HistogramInstrumentKind,
|
||||
func(desc *metric.Descriptor) export.Aggregator {
|
||||
func(desc *sdkapi.Descriptor) export.Aggregator {
|
||||
return &New(1)[0]
|
||||
},
|
||||
)
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/metric/aggregator"
|
||||
@ -110,7 +110,7 @@ var _ aggregation.Histogram = &Aggregator{}
|
||||
// Note that this aggregator maintains each value using independent
|
||||
// atomic operations, which introduces the possibility that
|
||||
// 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
|
||||
|
||||
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 independent Sum, Count and Bucket Count are not consistent with each
|
||||
// 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)
|
||||
|
||||
if oa != nil && o == nil {
|
||||
@ -220,7 +220,7 @@ func (c *Aggregator) clearState() {
|
||||
}
|
||||
|
||||
// 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()
|
||||
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.
|
||||
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)
|
||||
if o == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
@ -64,17 +63,17 @@ var (
|
||||
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...)
|
||||
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...)
|
||||
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()
|
||||
require.Equal(t, number.Number(0), asum, "Empty checkpoint sum = 0")
|
||||
require.NoError(t, err)
|
||||
@ -241,7 +240,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
|
||||
aggregatortest.SynchronizedMoveResetTest(
|
||||
t,
|
||||
sdkapi.HistogramInstrumentKind,
|
||||
func(desc *metric.Descriptor) export.Aggregator {
|
||||
func(desc *sdkapi.Descriptor) export.Aggregator {
|
||||
return &histogram.New(1, desc, histogram.WithExplicitBoundaries(testBoundaries))[0]
|
||||
},
|
||||
)
|
||||
|
@ -20,8 +20,8 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"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.
|
||||
func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error {
|
||||
func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *sdkapi.Descriptor) error {
|
||||
if oa == nil {
|
||||
atomic.StorePointer(&g.value, unsafe.Pointer(unsetLastValue))
|
||||
return nil
|
||||
@ -106,7 +106,7 @@ func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
|
||||
}
|
||||
|
||||
// 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{
|
||||
value: number,
|
||||
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
|
||||
// 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)
|
||||
if o == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(g, oa)
|
||||
|
@ -25,7 +25,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ottest "go.opentelemetry.io/otel/internal/internaltest"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
@ -140,7 +139,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
|
||||
aggregatortest.SynchronizedMoveResetTest(
|
||||
t,
|
||||
sdkapi.GaugeObserverInstrumentKind,
|
||||
func(desc *metric.Descriptor) export.Aggregator {
|
||||
func(desc *sdkapi.Descriptor) export.Aggregator {
|
||||
return &New(1)[0]
|
||||
},
|
||||
)
|
||||
|
@ -18,8 +18,8 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/metric/aggregator"
|
||||
@ -49,7 +49,7 @@ var _ aggregation.MinMaxSumCount = &Aggregator{}
|
||||
// count.
|
||||
//
|
||||
// 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()
|
||||
aggs := make([]Aggregator, cnt)
|
||||
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
|
||||
// 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)
|
||||
|
||||
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.
|
||||
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()
|
||||
|
||||
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.
|
||||
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)
|
||||
if o == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
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)
|
||||
return &alloc[0], &alloc[1]
|
||||
}
|
||||
|
||||
func new4(desc *metric.Descriptor) (_, _, _, _ *Aggregator) {
|
||||
func new4(desc *sdkapi.Descriptor) (_, _, _, _ *Aggregator) {
|
||||
alloc := New(4, desc)
|
||||
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()
|
||||
|
||||
sum, err := agg.Sum()
|
||||
@ -242,7 +241,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
|
||||
aggregatortest.SynchronizedMoveResetTest(
|
||||
t,
|
||||
sdkapi.HistogramInstrumentKind,
|
||||
func(desc *metric.Descriptor) export.Aggregator {
|
||||
func(desc *sdkapi.Descriptor) export.Aggregator {
|
||||
return &New(1, desc)[0]
|
||||
},
|
||||
)
|
||||
|
@ -17,8 +17,8 @@ package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"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
|
||||
// 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 {
|
||||
c.value.SetRawAtomic(0)
|
||||
return nil
|
||||
@ -74,13 +74,13 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
|
||||
}
|
||||
|
||||
// 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)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
if o == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
||||
@ -89,7 +89,7 @@ func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error
|
||||
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)
|
||||
if op == nil {
|
||||
return aggregator.NewInconsistentAggregatorError(c, opAgg)
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ottest "go.opentelemetry.io/otel/internal/internaltest"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
@ -56,7 +55,7 @@ func new4() (_, _, _, _ *Aggregator) {
|
||||
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()
|
||||
|
||||
sum, err := agg.Sum()
|
||||
@ -148,7 +147,7 @@ func TestSynchronizedMoveReset(t *testing.T) {
|
||||
aggregatortest.SynchronizedMoveResetTest(
|
||||
t,
|
||||
sdkapi.CounterObserverInstrumentKind,
|
||||
func(desc *metric.Descriptor) export.Aggregator {
|
||||
func(desc *sdkapi.Descriptor) export.Aggregator {
|
||||
return &New(1)[0]
|
||||
},
|
||||
)
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/global"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
sdk "go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/metric/processor/processortest"
|
||||
@ -483,7 +484,7 @@ func benchmarkBatchRecord8Labels(b *testing.B, numInst int) {
|
||||
ctx := context.Background()
|
||||
fix := newFixture(b)
|
||||
labs := makeLabels(numLabels)
|
||||
var meas []metric.Measurement
|
||||
var meas []sdkapi.Measurement
|
||||
|
||||
for i := 0; i < numInst; i++ {
|
||||
inst := fix.meterMust().NewInt64Counter(fmt.Sprintf("int64.%d.sum", i))
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
ottest "go.opentelemetry.io/otel/internal/internaltest"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
@ -296,7 +297,7 @@ func (b *blockingExporter) Export(ctx context.Context, res *resource.Resource, o
|
||||
}
|
||||
|
||||
func (*blockingExporter) ExportKindFor(
|
||||
*metric.Descriptor,
|
||||
*sdkapi.Descriptor,
|
||||
aggregation.Kind,
|
||||
) export.ExportKind {
|
||||
return export.CumulativeExportKind
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
metricsdk "go.opentelemetry.io/otel/sdk/metric"
|
||||
@ -71,7 +72,7 @@ type testSelector struct {
|
||||
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)
|
||||
processortest.AggregatorSelector().AggregatorFor(desc, aggPtrs...)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
)
|
||||
@ -40,13 +40,13 @@ type (
|
||||
// data for the same instrument, and this code has
|
||||
// logic to combine data properly from multiple
|
||||
// accumulators. However, the use of
|
||||
// *metric.Descriptor in the stateKey makes such
|
||||
// *sdkapi.Descriptor in the stateKey makes such
|
||||
// combination impossible, because each accumulator
|
||||
// allocates its own instruments. This can be fixed
|
||||
// by using the instrument name and kind instead of
|
||||
// the descriptor pointer. See
|
||||
// https://github.com/open-telemetry/opentelemetry-go/issues/862.
|
||||
descriptor *metric.Descriptor
|
||||
descriptor *sdkapi.Descriptor
|
||||
distinct attribute.Distinct
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ func asNumber(nkind number.Kind, value int64) number.Number {
|
||||
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...)
|
||||
var agg export.Aggregator
|
||||
selector.AggregatorFor(desc, &agg)
|
||||
@ -265,7 +265,7 @@ func testProcessor(
|
||||
|
||||
type bogusExporter struct{}
|
||||
|
||||
func (bogusExporter) ExportKindFor(*metric.Descriptor, aggregation.Kind) export.ExportKind {
|
||||
func (bogusExporter) ExportKindFor(*sdkapi.Descriptor, aggregation.Kind) export.ExportKind {
|
||||
return 1000000
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@ import (
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
@ -40,7 +40,7 @@ type (
|
||||
// unique descriptor, distinct labels, and distinct resource
|
||||
// attributes.
|
||||
mapKey struct {
|
||||
desc *metric.Descriptor
|
||||
desc *sdkapi.Descriptor
|
||||
labels attribute.Distinct
|
||||
resource attribute.Distinct
|
||||
}
|
||||
@ -181,7 +181,7 @@ func AggregatorSelector() 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 {
|
||||
case strings.HasSuffix(desc.Name(), ".disabled"):
|
||||
|
@ -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 true to keep this label, false to drop this label
|
||||
// ...
|
||||
|
@ -16,7 +16,7 @@ package reducer // import "go.opentelemetry.io/otel/sdk/metric/processor/reducer
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
)
|
||||
|
||||
@ -31,7 +31,7 @@ type (
|
||||
// LabelFilterSelector is the interface used to configure a
|
||||
// specific Filter to an instrument.
|
||||
LabelFilterSelector interface {
|
||||
LabelFilterFor(descriptor *metric.Descriptor) attribute.Filter
|
||||
LabelFilterFor(descriptor *sdkapi.Descriptor) attribute.Filter
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
metricsdk "go.opentelemetry.io/otel/sdk/metric"
|
||||
@ -47,13 +48,13 @@ var (
|
||||
|
||||
type testFilter struct{}
|
||||
|
||||
func (testFilter) LabelFilterFor(_ *metric.Descriptor) attribute.Filter {
|
||||
func (testFilter) LabelFilterFor(_ *sdkapi.Descriptor) attribute.Filter {
|
||||
return func(label attribute.KeyValue) bool {
|
||||
return label.Key == "A" || label.Key == "C"
|
||||
}
|
||||
}
|
||||
|
||||
func generateData(impl metric.MeterImpl) {
|
||||
func generateData(impl sdkapi.MeterImpl) {
|
||||
ctx := context.Background()
|
||||
meter := metric.WrapMeterImpl(impl)
|
||||
|
||||
|
@ -24,8 +24,8 @@ import (
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
internal "go.opentelemetry.io/otel/internal/metric"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"go.opentelemetry.io/otel/sdk/metric/aggregator"
|
||||
)
|
||||
@ -72,7 +72,7 @@ type (
|
||||
// mapkey uniquely describes a metric instrument in terms of
|
||||
// its InstrumentID and the encoded form of its labels.
|
||||
mapkey struct {
|
||||
descriptor *metric.Descriptor
|
||||
descriptor *sdkapi.Descriptor
|
||||
ordered attribute.Distinct
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ type (
|
||||
|
||||
instrument struct {
|
||||
meter *Accumulator
|
||||
descriptor metric.Descriptor
|
||||
descriptor sdkapi.Descriptor
|
||||
}
|
||||
|
||||
asyncInstrument struct {
|
||||
@ -138,16 +138,16 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
_ metric.MeterImpl = &Accumulator{}
|
||||
_ metric.AsyncImpl = &asyncInstrument{}
|
||||
_ metric.SyncImpl = &syncInstrument{}
|
||||
_ metric.BoundSyncImpl = &record{}
|
||||
_ sdkapi.MeterImpl = &Accumulator{}
|
||||
_ sdkapi.AsyncImpl = &asyncInstrument{}
|
||||
_ sdkapi.SyncImpl = &syncInstrument{}
|
||||
_ sdkapi.BoundSyncImpl = &record{}
|
||||
|
||||
// ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
|
||||
ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
|
||||
)
|
||||
|
||||
func (inst *instrument) Descriptor() metric.Descriptor {
|
||||
func (inst *instrument) Descriptor() sdkapi.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.
|
||||
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) metric.BoundSyncImpl {
|
||||
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
||||
return s.acquireHandle(kvs, nil)
|
||||
}
|
||||
|
||||
@ -307,8 +307,8 @@ func NewAccumulator(processor export.Processor) *Accumulator {
|
||||
}
|
||||
}
|
||||
|
||||
// NewSyncInstrument implements metric.MetricImpl.
|
||||
func (m *Accumulator) NewSyncInstrument(descriptor metric.Descriptor) (metric.SyncImpl, error) {
|
||||
// NewSyncInstrument implements sdkapi.MetricImpl.
|
||||
func (m *Accumulator) NewSyncInstrument(descriptor sdkapi.Descriptor) (sdkapi.SyncImpl, error) {
|
||||
return &syncInstrument{
|
||||
instrument: instrument{
|
||||
descriptor: descriptor,
|
||||
@ -317,8 +317,8 @@ func (m *Accumulator) NewSyncInstrument(descriptor metric.Descriptor) (metric.Sy
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewAsyncInstrument implements metric.MetricImpl.
|
||||
func (m *Accumulator) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (metric.AsyncImpl, error) {
|
||||
// NewAsyncInstrument implements sdkapi.MetricImpl.
|
||||
func (m *Accumulator) NewAsyncInstrument(descriptor sdkapi.Descriptor, runner sdkapi.AsyncRunner) (sdkapi.AsyncImpl, error) {
|
||||
a := &asyncInstrument{
|
||||
instrument: instrument{
|
||||
descriptor: descriptor,
|
||||
@ -395,7 +395,7 @@ func (m *Accumulator) collectSyncInstruments() int {
|
||||
|
||||
// CollectAsync implements internal.AsyncCollector.
|
||||
// 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)
|
||||
|
||||
for _, ob := range obs {
|
||||
@ -472,7 +472,7 @@ func (m *Accumulator) checkpointAsync(a *asyncInstrument) int {
|
||||
|
||||
// RecordBatch enters a batch of metric events.
|
||||
// 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
|
||||
// called. Subsequent calls to acquireHandle will re-use 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) {
|
||||
if r.current == nil {
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Unbind implements metric.SyncImpl.
|
||||
// Unbind implements sdkapi.SyncImpl.
|
||||
func (r *record) Unbind() {
|
||||
r.refMapped.unref()
|
||||
}
|
||||
@ -528,7 +528,7 @@ func (r *record) mapkey() mapkey {
|
||||
|
||||
// fromSync gets a sync implementation object, checking for
|
||||
// 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 inst, ok := sync.Implementation().(*syncInstrument); ok {
|
||||
return inst
|
||||
@ -540,7 +540,7 @@ func (m *Accumulator) fromSync(sync metric.SyncImpl) *syncInstrument {
|
||||
|
||||
// fromSync gets an async implementation object, checking for
|
||||
// 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 inst, ok := async.Implementation().(*asyncInstrument); ok {
|
||||
return inst
|
||||
|
@ -15,7 +15,6 @@
|
||||
package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
||||
|
||||
import (
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||
"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() {
|
||||
case sdkapi.GaugeObserverInstrumentKind:
|
||||
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() {
|
||||
case sdkapi.GaugeObserverInstrumentKind:
|
||||
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() {
|
||||
case sdkapi.GaugeObserverInstrumentKind:
|
||||
lastValueAggs(aggPtrs)
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/metric/metrictest"
|
||||
"go.opentelemetry.io/otel/metric/number"
|
||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||
@ -41,7 +40,7 @@ var (
|
||||
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
|
||||
sel.AggregatorFor(desc, &agg)
|
||||
return agg
|
||||
|
@ -71,7 +71,7 @@ type (
|
||||
|
||||
testKey struct {
|
||||
labels string
|
||||
descriptor *metric.Descriptor
|
||||
descriptor *sdkapi.Descriptor
|
||||
}
|
||||
|
||||
testImpl struct {
|
||||
@ -90,7 +90,7 @@ type (
|
||||
}
|
||||
|
||||
SyncImpler interface {
|
||||
SyncImpl() metric.SyncImpl
|
||||
SyncImpl() sdkapi.SyncImpl
|
||||
}
|
||||
|
||||
// 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()
|
||||
name := fmt.Sprint("test_", i)
|
||||
instrument := f.impl.newInstrument(meter, name)
|
||||
var descriptor *metric.Descriptor
|
||||
var descriptor *sdkapi.Descriptor
|
||||
if ii, ok := instrument.SyncImpl().(*syncInstrument); ok {
|
||||
descriptor = &ii.descriptor
|
||||
}
|
||||
|
Reference in New Issue
Block a user