1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-15 01:04:25 +02:00

Move metric api package into otel (#1252)

* Update metric Kind to InstrumentKind

* Update all the other modules with Kind rename

* Update metric Descriptor with instrument Kind rename

* Update other modules with Descriptor method rename

* Update OTLP exporter test field name

* Rename kind filenames

* Add changes to CHANGELOG

* Fix documentation for Grouping and PrecomputedSum

* Rename meter.go to metric.go

* Move descriptor.go into metric.go

* Move must.go into metric.go

* Move instruments into metric_instrument.go

* Rename metric api_test.go to metric_test.go

* Move instrumentkind_test.go into metric_test.go

* Rename sdkapi.go metric_sdkapi.go

* Move api/metric into otel

* Update to use moved packages

* Rename otel.go to error_handler.go

* Add changes to CHANGELOG

* Fix merge conflict resolution error
This commit is contained in:
Tyler Yahn
2020-10-17 09:48:21 -07:00
committed by GitHub
parent 90de306c25
commit 818c7b14b3
92 changed files with 2206 additions and 2507 deletions

View File

@ -28,6 +28,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
This matches the returned type and fixes misuse of the term metric. (#1240)
- Move test harness from the `go.opentelemetry.io/otel/api/apitest` package into `go.opentelemetry.io/otel/oteltest`. (#1241)
- Rename `MergeItererator` to `MergeIterator` in the `go.opentelemetry.io/otel/label` package. (#1244)
- Move the `go.opentelemetry.io/otel/api/metric`, `go.opentelemetry.io/otel/api/metric/metrictest`, and `go.opentelemetry.io/otel/api/metric/registry` packages into `go.opentelemetry.io/otel` as part of #964. (#1252)
- The function signature of the Span `AddEvent` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required name and a variable number of `EventOption`s. (#1254)
- The function signature of the Span `RecordError` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required error value and a variable number of `EventOption`s. (#1254)

View File

@ -12,25 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
import (
"os"
"testing"
"unsafe"
ottest "go.opentelemetry.io/otel/internal/testing"
internaltest "go.opentelemetry.io/otel/internal/testing"
)
// Ensure struct alignment prior to running tests.
func TestMain(m *testing.M) {
fields := []ottest.FieldOffset{
fields := []internaltest.FieldOffset{
{
Name: "Measurement.number",
Offset: unsafe.Offsetof(Measurement{}.number),
},
}
if !ottest.Aligned8Byte(fields, os.Stderr) {
if !internaltest.Aligned8Byte(fields, os.Stderr) {
os.Exit(1)
}

View File

@ -20,9 +20,9 @@ import (
"sync/atomic"
"unsafe"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/registry"
)
// This file contains the forwarding implementation of MeterProvider used as
@ -51,7 +51,7 @@ type meterKey struct {
}
type meterProvider struct {
delegate metric.MeterProvider
delegate otel.MeterProvider
// lock protects `delegate` and `meters`.
lock sync.Mutex
@ -62,7 +62,7 @@ type meterProvider struct {
}
type meterImpl struct {
delegate unsafe.Pointer // (*metric.MeterImpl)
delegate unsafe.Pointer // (*otel.MeterImpl)
lock sync.Mutex
syncInsts []*syncImpl
@ -70,42 +70,42 @@ type meterImpl struct {
}
type meterEntry struct {
unique metric.MeterImpl
unique otel.MeterImpl
impl meterImpl
}
type instrument struct {
descriptor metric.Descriptor
descriptor otel.Descriptor
}
type syncImpl struct {
delegate unsafe.Pointer // (*metric.SyncImpl)
delegate unsafe.Pointer // (*otel.SyncImpl)
instrument
}
type asyncImpl struct {
delegate unsafe.Pointer // (*metric.AsyncImpl)
delegate unsafe.Pointer // (*otel.AsyncImpl)
instrument
runner metric.AsyncRunner
runner otel.AsyncRunner
}
// SyncImpler is implemented by all of the sync metric
// instruments.
type SyncImpler interface {
SyncImpl() metric.SyncImpl
SyncImpl() otel.SyncImpl
}
// AsyncImpler is implemented by all of the async
// metric instruments.
type AsyncImpler interface {
AsyncImpl() metric.AsyncImpl
AsyncImpl() otel.AsyncImpl
}
type syncHandle struct {
delegate unsafe.Pointer // (*metric.HandleImpl)
delegate unsafe.Pointer // (*otel.HandleImpl)
inst *syncImpl
labels []label.KeyValue
@ -113,13 +113,13 @@ type syncHandle struct {
initialize sync.Once
}
var _ metric.MeterProvider = &meterProvider{}
var _ metric.MeterImpl = &meterImpl{}
var _ metric.InstrumentImpl = &syncImpl{}
var _ metric.BoundSyncImpl = &syncHandle{}
var _ metric.AsyncImpl = &asyncImpl{}
var _ otel.MeterProvider = &meterProvider{}
var _ otel.MeterImpl = &meterImpl{}
var _ otel.InstrumentImpl = &syncImpl{}
var _ otel.BoundSyncImpl = &syncHandle{}
var _ otel.AsyncImpl = &asyncImpl{}
func (inst *instrument) Descriptor() metric.Descriptor {
func (inst *instrument) Descriptor() otel.Descriptor {
return inst.descriptor
}
@ -131,7 +131,7 @@ func newMeterProvider() *meterProvider {
}
}
func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
func (p *meterProvider) setDelegate(provider otel.MeterProvider) {
p.lock.Lock()
defer p.lock.Unlock()
@ -142,7 +142,7 @@ func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
p.meters = nil
}
func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
func (p *meterProvider) Meter(instrumentationName string, opts ...otel.MeterOption) otel.Meter {
p.lock.Lock()
defer p.lock.Unlock()
@ -152,7 +152,7 @@ func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOp
key := meterKey{
Name: instrumentationName,
Version: metric.NewMeterConfig(opts...).InstrumentationVersion,
Version: otel.NewMeterConfig(opts...).InstrumentationVersion,
}
entry, ok := p.meters[key]
if !ok {
@ -161,17 +161,17 @@ func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOp
p.meters[key] = entry
}
return metric.WrapMeterImpl(entry.unique, key.Name, metric.WithInstrumentationVersion(key.Version))
return otel.WrapMeterImpl(entry.unique, key.Name, otel.WithInstrumentationVersion(key.Version))
}
// Meter interface and delegation
func (m *meterImpl) setDelegate(name, version string, provider metric.MeterProvider) {
func (m *meterImpl) setDelegate(name, version string, provider otel.MeterProvider) {
m.lock.Lock()
defer m.lock.Unlock()
d := new(metric.MeterImpl)
*d = provider.Meter(name, metric.WithInstrumentationVersion(version)).MeterImpl()
d := new(otel.MeterImpl)
*d = provider.Meter(name, otel.WithInstrumentationVersion(version)).MeterImpl()
m.delegate = unsafe.Pointer(d)
for _, inst := range m.syncInsts {
@ -184,11 +184,11 @@ func (m *meterImpl) setDelegate(name, version string, provider metric.MeterProvi
m.asyncInsts = nil
}
func (m *meterImpl) NewSyncInstrument(desc metric.Descriptor) (metric.SyncImpl, error) {
func (m *meterImpl) NewSyncInstrument(desc otel.Descriptor) (otel.SyncImpl, error) {
m.lock.Lock()
defer m.lock.Unlock()
if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
if meterPtr := (*otel.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).NewSyncInstrument(desc)
}
@ -203,8 +203,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 otel.MeterImpl) {
implPtr := new(otel.SyncImpl)
var err error
*implPtr, err = d.NewSyncInstrument(inst.descriptor)
@ -221,14 +221,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 := (*otel.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
return (*implPtr).Implementation()
}
return inst
}
func (inst *syncImpl) Bind(labels []label.KeyValue) metric.BoundSyncImpl {
if implPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
func (inst *syncImpl) Bind(labels []label.KeyValue) otel.BoundSyncImpl {
if implPtr := (*otel.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
return (*implPtr).Bind(labels)
}
return &syncHandle{
@ -240,7 +240,7 @@ func (inst *syncImpl) Bind(labels []label.KeyValue) metric.BoundSyncImpl {
func (bound *syncHandle) Unbind() {
bound.initialize.Do(func() {})
implPtr := (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
implPtr := (*otel.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
if implPtr == nil {
return
@ -252,14 +252,14 @@ func (bound *syncHandle) Unbind() {
// Async delegation
func (m *meterImpl) NewAsyncInstrument(
desc metric.Descriptor,
runner metric.AsyncRunner,
) (metric.AsyncImpl, error) {
desc otel.Descriptor,
runner otel.AsyncRunner,
) (otel.AsyncImpl, error) {
m.lock.Lock()
defer m.lock.Unlock()
if meterPtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
if meterPtr := (*otel.MeterImpl)(atomic.LoadPointer(&m.delegate)); meterPtr != nil {
return (*meterPtr).NewAsyncInstrument(desc, runner)
}
@ -274,14 +274,14 @@ func (m *meterImpl) NewAsyncInstrument(
}
func (obs *asyncImpl) Implementation() interface{} {
if implPtr := (*metric.AsyncImpl)(atomic.LoadPointer(&obs.delegate)); implPtr != nil {
if implPtr := (*otel.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 otel.MeterImpl) {
implPtr := new(otel.AsyncImpl)
var err error
*implPtr, err = d.NewAsyncInstrument(obs.descriptor, obs.runner)
@ -299,33 +299,33 @@ func (obs *asyncImpl) setDelegate(d metric.MeterImpl) {
// Metric updates
func (m *meterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, measurements ...metric.Measurement) {
if delegatePtr := (*metric.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
func (m *meterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, measurements ...otel.Measurement) {
if delegatePtr := (*otel.MeterImpl)(atomic.LoadPointer(&m.delegate)); delegatePtr != nil {
(*delegatePtr).RecordBatch(ctx, labels, measurements...)
}
}
func (inst *syncImpl) RecordOne(ctx context.Context, number metric.Number, labels []label.KeyValue) {
if instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
func (inst *syncImpl) RecordOne(ctx context.Context, number otel.Number, labels []label.KeyValue) {
if instPtr := (*otel.SyncImpl)(atomic.LoadPointer(&inst.delegate)); instPtr != nil {
(*instPtr).RecordOne(ctx, number, labels)
}
}
// Bound instrument initialization
func (bound *syncHandle) RecordOne(ctx context.Context, number metric.Number) {
instPtr := (*metric.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
func (bound *syncHandle) RecordOne(ctx context.Context, number otel.Number) {
instPtr := (*otel.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
if instPtr == nil {
return
}
var implPtr *metric.BoundSyncImpl
var implPtr *otel.BoundSyncImpl
bound.initialize.Do(func() {
implPtr = new(metric.BoundSyncImpl)
implPtr = new(otel.BoundSyncImpl)
*implPtr = (*instPtr).Bind(bound.labels)
atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
})
if implPtr == nil {
implPtr = (*metric.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
implPtr = (*otel.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

View File

@ -21,23 +21,23 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/global/internal"
"go.opentelemetry.io/otel/api/metric"
metrictest "go.opentelemetry.io/otel/api/metric/metrictest"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/oteltest"
)
var Must = metric.Must
var Must = otel.Must
var asInt = metric.NewInt64Number
var asFloat = metric.NewFloat64Number
var asInt = otel.NewInt64Number
var asFloat = otel.NewFloat64Number
func TestDirect(t *testing.T) {
internal.ResetForTest()
ctx := context.Background()
meter1 := global.Meter("test1", metric.WithInstrumentationVersion("semver:v1.0.0"))
meter1 := global.Meter("test1", otel.WithInstrumentationVersion("semver:v1.0.0"))
meter2 := global.Meter("test2")
labels1 := []label.KeyValue{label.String("A", "B")}
labels2 := []label.KeyValue{label.String("C", "D")}
@ -51,12 +51,12 @@ func TestDirect(t *testing.T) {
valuerecorder.Record(ctx, 1, labels1...)
valuerecorder.Record(ctx, 2, labels1...)
_ = Must(meter1).NewFloat64ValueObserver("test.valueobserver.float", func(_ context.Context, result metric.Float64ObserverResult) {
_ = Must(meter1).NewFloat64ValueObserver("test.valueobserver.float", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(1., labels1...)
result.Observe(2., labels2...)
})
_ = Must(meter1).NewInt64ValueObserver("test.valueobserver.int", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter1).NewInt64ValueObserver("test.valueobserver.int", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(1, labels1...)
result.Observe(2, labels2...)
})
@ -65,7 +65,7 @@ func TestDirect(t *testing.T) {
second.Record(ctx, 1, labels3...)
second.Record(ctx, 2, labels3...)
mock, provider := metrictest.NewMeterProvider()
mock, provider := oteltest.NewMeterProvider()
global.SetMeterProvider(provider)
counter.Add(ctx, 1, labels1...)
@ -74,56 +74,56 @@ func TestDirect(t *testing.T) {
mock.RunAsyncInstruments()
measurements := metrictest.AsStructs(mock.MeasurementBatches)
measurements := oteltest.AsStructs(mock.MeasurementBatches)
require.EqualValues(t,
[]metrictest.Measured{
[]oteltest.Measured{
{
Name: "test.counter",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asInt(1),
},
{
Name: "test.valuerecorder",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asFloat(3),
},
{
Name: "test.second",
InstrumentationName: "test2",
Labels: metrictest.LabelsToMap(labels3...),
Labels: oteltest.LabelsToMap(labels3...),
Number: asFloat(3),
},
{
Name: "test.valueobserver.float",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asFloat(1),
},
{
Name: "test.valueobserver.float",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels2...),
Labels: oteltest.LabelsToMap(labels2...),
Number: asFloat(2),
},
{
Name: "test.valueobserver.int",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asInt(1),
},
{
Name: "test.valueobserver.int",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: metrictest.LabelsToMap(labels2...),
Labels: oteltest.LabelsToMap(labels2...),
Number: asInt(2),
},
},
@ -150,28 +150,28 @@ func TestBound(t *testing.T) {
boundM.Record(ctx, 1)
boundM.Record(ctx, 2)
mock, provider := metrictest.NewMeterProvider()
mock, provider := oteltest.NewMeterProvider()
global.SetMeterProvider(provider)
boundC.Add(ctx, 1)
boundM.Record(ctx, 3)
require.EqualValues(t,
[]metrictest.Measured{
[]oteltest.Measured{
{
Name: "test.counter",
InstrumentationName: "test",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asFloat(1),
},
{
Name: "test.valuerecorder",
InstrumentationName: "test",
Labels: metrictest.LabelsToMap(labels1...),
Labels: oteltest.LabelsToMap(labels1...),
Number: asInt(3),
},
},
metrictest.AsStructs(mock.MeasurementBatches))
oteltest.AsStructs(mock.MeasurementBatches))
boundC.Unbind()
boundM.Unbind()
@ -198,7 +198,7 @@ func TestUnbindThenRecordOne(t *testing.T) {
internal.ResetForTest()
ctx := context.Background()
mock, provider := metrictest.NewMeterProvider()
mock, provider := oteltest.NewMeterProvider()
meter := global.Meter("test")
counter := Must(meter).NewInt64Counter("test.counter")
@ -213,19 +213,19 @@ func TestUnbindThenRecordOne(t *testing.T) {
}
type meterProviderWithConstructorError struct {
metric.MeterProvider
otel.MeterProvider
}
type meterWithConstructorError struct {
metric.MeterImpl
otel.MeterImpl
}
func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter {
return metric.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()}, iName, opts...)
func (m *meterProviderWithConstructorError) Meter(iName string, opts ...otel.MeterOption) otel.Meter {
return otel.WrapMeterImpl(&meterWithConstructorError{m.MeterProvider.Meter(iName, opts...).MeterImpl()}, iName, opts...)
}
func (m *meterWithConstructorError) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) {
return metric.NoopSync{}, errors.New("constructor error")
func (m *meterWithConstructorError) NewSyncInstrument(_ otel.Descriptor) (otel.SyncImpl, error) {
return otel.NoopSync{}, errors.New("constructor error")
}
func TestErrorInDeferredConstructor(t *testing.T) {
@ -237,7 +237,7 @@ func TestErrorInDeferredConstructor(t *testing.T) {
c1 := Must(meter).NewInt64Counter("test")
c2 := Must(meter).NewInt64Counter("test")
_, provider := metrictest.NewMeterProvider()
_, provider := oteltest.NewMeterProvider()
sdk := &meterProviderWithConstructorError{provider}
require.Panics(t, func() {
@ -263,23 +263,23 @@ func TestImplementationIndirection(t *testing.T) {
ival := counter.Measurement(1).SyncImpl().Implementation()
require.NotNil(t, ival)
_, ok := ival.(*metrictest.Sync)
_, ok := ival.(*oteltest.Sync)
require.False(t, ok)
// Async: no SDK yet
valueobserver := Must(meter1).NewFloat64ValueObserver(
"interface.valueobserver",
func(_ context.Context, result metric.Float64ObserverResult) {},
func(_ context.Context, result otel.Float64ObserverResult) {},
)
ival = valueobserver.AsyncImpl().Implementation()
require.NotNil(t, ival)
_, ok = ival.(*metrictest.Async)
_, ok = ival.(*oteltest.Async)
require.False(t, ok)
// Register the SDK
_, provider := metrictest.NewMeterProvider()
_, provider := oteltest.NewMeterProvider()
global.SetMeterProvider(provider)
// Repeat the above tests
@ -288,14 +288,14 @@ func TestImplementationIndirection(t *testing.T) {
ival = counter.Measurement(1).SyncImpl().Implementation()
require.NotNil(t, ival)
_, ok = ival.(*metrictest.Sync)
_, ok = ival.(*oteltest.Sync)
require.True(t, ok)
// Async
ival = valueobserver.AsyncImpl().Implementation()
require.NotNil(t, ival)
_, ok = ival.(*metrictest.Async)
_, ok = ival.(*oteltest.Async)
require.True(t, ok)
}
@ -308,19 +308,19 @@ func TestRecordBatchMock(t *testing.T) {
meter.RecordBatch(context.Background(), nil, counter.Measurement(1))
mock, provider := metrictest.NewMeterProvider()
mock, provider := oteltest.NewMeterProvider()
global.SetMeterProvider(provider)
meter.RecordBatch(context.Background(), nil, counter.Measurement(1))
require.EqualValues(t,
[]metrictest.Measured{
[]oteltest.Measured{
{
Name: "test.counter",
InstrumentationName: "builtin",
Labels: metrictest.LabelsToMap(),
Labels: oteltest.LabelsToMap(),
Number: asInt(1),
},
},
metrictest.AsStructs(mock.MeasurementBatches))
oteltest.AsStructs(mock.MeasurementBatches))
}

View File

@ -21,48 +21,48 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/registry"
)
type (
newFunc func(name, libraryName string) (metric.InstrumentImpl, error)
newFunc func(name, libraryName string) (otel.InstrumentImpl, error)
)
var (
allNew = map[string]newFunc{
"counter.int64": func(name, libraryName string) (metric.InstrumentImpl, error) {
"counter.int64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64Counter(name))
},
"counter.float64": func(name, libraryName string) (metric.InstrumentImpl, error) {
"counter.float64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64Counter(name))
},
"valuerecorder.int64": func(name, libraryName string) (metric.InstrumentImpl, error) {
"valuerecorder.int64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64ValueRecorder(name))
},
"valuerecorder.float64": func(name, libraryName string) (metric.InstrumentImpl, error) {
"valuerecorder.float64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64ValueRecorder(name))
},
"valueobserver.int64": func(name, libraryName string) (metric.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64ValueObserver(name, func(context.Context, metric.Int64ObserverResult) {}))
"valueobserver.int64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewInt64ValueObserver(name, func(context.Context, otel.Int64ObserverResult) {}))
},
"valueobserver.float64": func(name, libraryName string) (metric.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64ValueObserver(name, func(context.Context, metric.Float64ObserverResult) {}))
"valueobserver.float64": func(name, libraryName string) (otel.InstrumentImpl, error) {
return unwrap(MeterProvider().Meter(libraryName).NewFloat64ValueObserver(name, func(context.Context, otel.Float64ObserverResult) {}))
},
}
)
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) {
func unwrap(impl interface{}, err error) (otel.InstrumentImpl, error) {
if impl == nil {
return nil, err
}
if s, ok := impl.(interface {
SyncImpl() metric.SyncImpl
SyncImpl() otel.SyncImpl
}); ok {
return s.SyncImpl(), err
}
if a, ok := impl.(interface {
AsyncImpl() metric.AsyncImpl
AsyncImpl() otel.AsyncImpl
}); ok {
return a.AsyncImpl(), err
}

View File

@ -19,7 +19,6 @@ import (
"sync/atomic"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/metric"
)
type (
@ -28,7 +27,7 @@ type (
}
meterProviderHolder struct {
mp metric.MeterProvider
mp otel.MeterProvider
}
propagatorsHolder struct {
@ -69,12 +68,12 @@ func SetTracerProvider(tp otel.TracerProvider) {
}
// MeterProvider is the internal implementation for global.MeterProvider.
func MeterProvider() metric.MeterProvider {
func MeterProvider() otel.MeterProvider {
return globalMeter.Load().(meterProviderHolder).mp
}
// SetMeterProvider is the internal implementation for global.SetMeterProvider.
func SetMeterProvider(mp metric.MeterProvider) {
func SetMeterProvider(mp otel.MeterProvider) {
delegateMeterOnce.Do(func() {
current := MeterProvider()

View File

@ -15,8 +15,8 @@
package global
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global/internal"
"go.opentelemetry.io/otel/api/metric"
)
// Meter creates an implementation of the Meter interface from the global
@ -27,7 +27,7 @@ import (
// will be used instead.
//
// This is short for MeterProvider().Meter(name)
func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
func Meter(instrumentationName string, opts ...otel.MeterOption) otel.Meter {
return MeterProvider().Meter(instrumentationName, opts...)
}
@ -39,11 +39,11 @@ func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter
// meter := global.MeterProvider().Meter("example.com/foo")
// or
// meter := global.Meter("example.com/foo")
func MeterProvider() metric.MeterProvider {
func MeterProvider() otel.MeterProvider {
return internal.MeterProvider()
}
// SetMeterProvider registers `mp` as the global meter provider.
func SetMeterProvider(mp metric.MeterProvider) {
func SetMeterProvider(mp otel.MeterProvider) {
internal.SetMeterProvider(mp)
}

View File

@ -17,21 +17,21 @@ package global_test
import (
"testing"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
)
type testMeterProvider struct{}
var _ metric.MeterProvider = &testMeterProvider{}
var _ otel.MeterProvider = &testMeterProvider{}
func (*testMeterProvider) Meter(_ string, _ ...metric.MeterOption) metric.Meter {
return metric.Meter{}
func (*testMeterProvider) Meter(_ string, _ ...otel.MeterOption) otel.Meter {
return otel.Meter{}
}
func TestMultipleGlobalMeterProvider(t *testing.T) {
p1 := testMeterProvider{}
p2 := metric.NoopMeterProvider{}
p2 := otel.NoopMeterProvider{}
global.SetMeterProvider(&p1)
global.SetMeterProvider(&p2)

View File

@ -1,217 +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 (
"context"
"go.opentelemetry.io/otel/label"
)
// The file is organized as follows:
//
// - Observation type
// - Three kinds of Observer callback (int64, float64, batch)
// - Three kinds of Observer result (int64, float64, batch)
// - Three kinds of Observe() function (int64, float64, batch)
// - Three kinds of AsyncRunner interface (abstract, single, batch)
// - Two kinds of Observer constructor (int64, float64)
// - Two kinds of Observation() function (int64, float64)
// - Various internals
// Observation is used for reporting an asynchronous batch of metric
// values. Instances of this type should be created by asynchronous
// instruments (e.g., Int64ValueObserver.Observation()).
type Observation struct {
// number needs to be aligned for 64-bit atomic operations.
number Number
instrument AsyncImpl
}
// Int64ObserverFunc is a type of callback that integral
// observers run.
type Int64ObserverFunc func(context.Context, Int64ObserverResult)
// Float64ObserverFunc is a type of callback that floating point
// observers run.
type Float64ObserverFunc func(context.Context, Float64ObserverResult)
// BatchObserverFunc is a callback argument for use with any
// Observer instrument that will be reported as a batch of
// observations.
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
function func([]label.KeyValue, ...Observation)
}
// Float64ObserverResult is passed to an observer callback to capture
// observations for one asynchronous floating point metric instrument.
type Float64ObserverResult struct {
instrument AsyncImpl
function func([]label.KeyValue, ...Observation)
}
// BatchObserverResult is passed to a batch observer callback to
// capture observations for multiple asynchronous instruments.
type BatchObserverResult struct {
function func([]label.KeyValue, ...Observation)
}
// Observe captures a single integer value from the associated
// instrument callback, with the given labels.
func (ir Int64ObserverResult) Observe(value int64, labels ...label.KeyValue) {
ir.function(labels, Observation{
instrument: 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 ...label.KeyValue) {
fr.function(labels, Observation{
instrument: fr.instrument,
number: NewFloat64Number(value),
})
}
// Observe captures a multiple observations from the associated batch
// instrument callback, with the given labels.
func (br BatchObserverResult) Observe(labels []label.KeyValue, obs ...Observation) {
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([]label.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([]label.KeyValue, ...Observation))
AsyncRunner
}
var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil)
var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil)
var _ AsyncBatchRunner = (*BatchObserverFunc)(nil)
// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner {
return &c
}
// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner {
return &c
}
// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner {
return &c
}
// AnyRunner implements AsyncRunner.
func (*Int64ObserverFunc) AnyRunner() {}
// AnyRunner implements AsyncRunner.
func (*Float64ObserverFunc) AnyRunner() {}
// AnyRunner implements AsyncRunner.
func (*BatchObserverFunc) AnyRunner() {}
// Run implements AsyncSingleRunner.
func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
(*i)(ctx, Int64ObserverResult{
instrument: impl,
function: function,
})
}
// Run implements AsyncSingleRunner.
func (f *Float64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
(*f)(ctx, Float64ObserverResult{
instrument: impl,
function: function,
})
}
// Run implements AsyncBatchRunner.
func (b *BatchObserverFunc) Run(ctx context.Context, function func([]label.KeyValue, ...Observation)) {
(*b)(ctx, BatchObserverResult{
function: function,
})
}
// wrapInt64ValueObserverInstrument converts an AsyncImpl into Int64ValueObserver.
func wrapInt64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Int64ValueObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64ValueObserver{asyncInstrument: common}, err
}
// wrapFloat64ValueObserverInstrument converts an AsyncImpl into Float64ValueObserver.
func wrapFloat64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Float64ValueObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64ValueObserver{asyncInstrument: common}, err
}
// wrapInt64SumObserverInstrument converts an AsyncImpl into Int64SumObserver.
func wrapInt64SumObserverInstrument(asyncInst AsyncImpl, err error) (Int64SumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64SumObserver{asyncInstrument: common}, err
}
// wrapFloat64SumObserverInstrument converts an AsyncImpl into Float64SumObserver.
func wrapFloat64SumObserverInstrument(asyncInst AsyncImpl, err error) (Float64SumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64SumObserver{asyncInstrument: common}, err
}
// wrapInt64UpDownSumObserverInstrument converts an AsyncImpl into Int64UpDownSumObserver.
func wrapInt64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Int64UpDownSumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64UpDownSumObserver{asyncInstrument: common}, err
}
// wrapFloat64UpDownSumObserverInstrument converts an AsyncImpl into Float64UpDownSumObserver.
func wrapFloat64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Float64UpDownSumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64UpDownSumObserver{asyncInstrument: common}, err
}

View File

@ -1,125 +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/unit"
// InstrumentConfig contains options for instrument descriptors.
type InstrumentConfig struct {
// Description describes the instrument in human-readable terms.
Description string
// Unit describes the measurement unit for a instrument.
Unit unit.Unit
// InstrumentationName is the name of the library providing
// instrumentation.
InstrumentationName string
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// InstrumentOption is an interface for applying instrument options.
type InstrumentOption interface {
// ApplyMeter is used to set a InstrumentOption value of a
// InstrumentConfig.
ApplyInstrument(*InstrumentConfig)
}
// NewInstrumentConfig creates a new InstrumentConfig
// and applies all the given options.
func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig {
var config InstrumentConfig
for _, o := range opts {
o.ApplyInstrument(&config)
}
return config
}
// WithDescription applies provided description.
func WithDescription(desc string) InstrumentOption {
return descriptionOption(desc)
}
type descriptionOption string
func (d descriptionOption) ApplyInstrument(config *InstrumentConfig) {
config.Description = string(d)
}
// WithUnit applies provided unit.
func WithUnit(unit unit.Unit) InstrumentOption {
return unitOption(unit)
}
type unitOption unit.Unit
func (u unitOption) ApplyInstrument(config *InstrumentConfig) {
config.Unit = unit.Unit(u)
}
// WithInstrumentationName sets the instrumentation name.
func WithInstrumentationName(name string) InstrumentOption {
return instrumentationNameOption(name)
}
type instrumentationNameOption string
func (i instrumentationNameOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationName = string(i)
}
// MeterConfig contains options for Meters.
type MeterConfig struct {
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// MeterOption is an interface for applying Meter options.
type MeterOption interface {
// ApplyMeter is used to set a MeterOption value of a MeterConfig.
ApplyMeter(*MeterConfig)
}
// NewMeterConfig creates a new MeterConfig and applies
// all the given options.
func NewMeterConfig(opts ...MeterOption) MeterConfig {
var config MeterConfig
for _, o := range opts {
o.ApplyMeter(&config)
}
return config
}
// Option is an interface for applying Instrument or Meter options.
type Option interface {
InstrumentOption
MeterOption
}
// WithInstrumentationVersion sets the instrumentation version.
func WithInstrumentationVersion(version string) Option {
return instrumentationVersionOption(version)
}
type instrumentationVersionOption string
func (i instrumentationVersionOption) ApplyMeter(config *MeterConfig) {
config.InstrumentationVersion = string(i)
}
func (i instrumentationVersionOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationVersion = string(i)
}

View File

@ -1,95 +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 (
"context"
"go.opentelemetry.io/otel/label"
)
// Float64Counter is a metric that accumulates float64 values.
type Float64Counter struct {
syncInstrument
}
// Int64Counter is a metric that accumulates int64 values.
type Int64Counter struct {
syncInstrument
}
// BoundFloat64Counter is a bound instrument for Float64Counter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64Counter struct {
syncBoundInstrument
}
// BoundInt64Counter is a boundInstrument for Int64Counter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64Counter struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64Counter) Bind(labels ...label.KeyValue) (h BoundFloat64Counter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64Counter) Bind(labels ...label.KeyValue) (h BoundInt64Counter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64Counter) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64Counter) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Float64Counter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Int64Counter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}

View File

@ -1,77 +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/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 NumberKind
config InstrumentConfig
}
// NewDescriptor returns a Descriptor with the given contents.
func NewDescriptor(name string, ikind InstrumentKind, nkind NumberKind, opts ...InstrumentOption) Descriptor {
return Descriptor{
name: name,
instrumentKind: ikind,
numberKind: nkind,
config: NewInstrumentConfig(opts...),
}
}
// 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.config.Description
}
// Unit describes the units of the metric instrument. Unitless
// metrics return the empty string.
func (d Descriptor) Unit() unit.Unit {
return d.config.Unit
}
// NumberKind returns whether this instrument is declared over int64,
// float64, or uint64 values.
func (d Descriptor) NumberKind() NumberKind {
return d.numberKind
}
// InstrumentationName returns the name of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationName() string {
return d.config.InstrumentationName
}
// InstrumentationVersion returns the version of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationVersion() string {
return d.config.InstrumentationVersion
}

View File

@ -1,50 +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 provides support for reporting measurements using instruments.
//
// Instruments are categorized as below:
//
// Synchronous instruments are called by the user with a Context.
// Asynchronous instruments are called by the SDK during collection.
//
// Additive instruments are semantically intended for capturing a sum.
// Non-additive instruments are intended for capturing a distribution.
//
// Additive instruments may be monotonic, in which case they are
// non-descreasing and naturally define a rate.
//
// The synchronous instrument names are:
//
// Counter: additive, monotonic
// UpDownCounter: additive
// ValueRecorder: non-additive
//
// and the asynchronous instruments are:
//
// SumObserver: additive, monotonic
// UpDownSumObserver: additive
// ValueObserver: non-additive
//
// All instruments are provided with support for either float64 or
// int64 input values.
//
// The Meter interface supports allocating new instruments as well as
// interfaces for recording batches of synchronous measurements or
// asynchronous observations. To obtain a Meter, use a MeterProvider.
//
// The MeterProvider interface supports obtaining a named Meter interface. To
// obtain a MeterProvider implementation, initialize and configure any
// compatible SDK.
package metric // import "go.opentelemetry.io/otel/api/metric"

View File

@ -1,80 +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.
//go:generate stringer -type=InstrumentKind
package metric
// InstrumentKind describes the kind of instrument.
type InstrumentKind int8
const (
// ValueRecorderInstrumentKind indicates a ValueRecorder instrument.
ValueRecorderInstrumentKind InstrumentKind = iota
// ValueObserverInstrumentKind indicates an ValueObserver instrument.
ValueObserverInstrumentKind
// CounterInstrumentKind indicates a Counter instrument.
CounterInstrumentKind
// UpDownCounterInstrumentKind indicates a UpDownCounter instrument.
UpDownCounterInstrumentKind
// SumObserverInstrumentKind indicates a SumObserver instrument.
SumObserverInstrumentKind
// UpDownSumObserverInstrumentKind indicates a UpDownSumObserver
// instrument.
UpDownSumObserverInstrumentKind
)
// Synchronous returns whether this is a synchronous kind of instrument.
func (k InstrumentKind) Synchronous() bool {
switch k {
case CounterInstrumentKind, UpDownCounterInstrumentKind, ValueRecorderInstrumentKind:
return true
}
return false
}
// Asynchronous returns whether this is an asynchronous kind of instrument.
func (k InstrumentKind) Asynchronous() bool {
return !k.Synchronous()
}
// Adding returns whether this kind of instrument adds its inputs (as opposed to Grouping).
func (k InstrumentKind) Adding() bool {
switch k {
case CounterInstrumentKind, UpDownCounterInstrumentKind, SumObserverInstrumentKind, UpDownSumObserverInstrumentKind:
return true
}
return false
}
// Grouping returns whether this kind of instrument groups its inputs (as opposed to Adding).
func (k InstrumentKind) Grouping() bool {
return !k.Adding()
}
// Monotonic returns whether this kind of instrument exposes a non-decreasing sum.
func (k InstrumentKind) Monotonic() bool {
switch k {
case CounterInstrumentKind, SumObserverInstrumentKind:
return true
}
return false
}
// PrecomputedSum returns whether this kind of instrument receives precomputed sums.
func (k InstrumentKind) PrecomputedSum() bool {
return k.Adding() && k.Asynchronous()
}

View File

@ -1,110 +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_test
import (
"testing"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
)
var (
syncKinds = []metric.InstrumentKind{
metric.ValueRecorderInstrumentKind,
metric.CounterInstrumentKind,
metric.UpDownCounterInstrumentKind,
}
asyncKinds = []metric.InstrumentKind{
metric.ValueObserverInstrumentKind,
metric.SumObserverInstrumentKind,
metric.UpDownSumObserverInstrumentKind,
}
addingKinds = []metric.InstrumentKind{
metric.CounterInstrumentKind,
metric.UpDownCounterInstrumentKind,
metric.SumObserverInstrumentKind,
metric.UpDownSumObserverInstrumentKind,
}
groupingKinds = []metric.InstrumentKind{
metric.ValueRecorderInstrumentKind,
metric.ValueObserverInstrumentKind,
}
monotonicKinds = []metric.InstrumentKind{
metric.CounterInstrumentKind,
metric.SumObserverInstrumentKind,
}
nonMonotonicKinds = []metric.InstrumentKind{
metric.UpDownCounterInstrumentKind,
metric.UpDownSumObserverInstrumentKind,
metric.ValueRecorderInstrumentKind,
metric.ValueObserverInstrumentKind,
}
precomputedSumKinds = []metric.InstrumentKind{
metric.SumObserverInstrumentKind,
metric.UpDownSumObserverInstrumentKind,
}
nonPrecomputedSumKinds = []metric.InstrumentKind{
metric.CounterInstrumentKind,
metric.UpDownCounterInstrumentKind,
metric.ValueRecorderInstrumentKind,
metric.ValueObserverInstrumentKind,
}
)
func TestSynchronous(t *testing.T) {
for _, k := range syncKinds {
require.True(t, k.Synchronous())
require.False(t, k.Asynchronous())
}
for _, k := range asyncKinds {
require.True(t, k.Asynchronous())
require.False(t, k.Synchronous())
}
}
func TestGrouping(t *testing.T) {
for _, k := range groupingKinds {
require.True(t, k.Grouping())
require.False(t, k.Adding())
}
for _, k := range addingKinds {
require.True(t, k.Adding())
require.False(t, k.Grouping())
}
}
func TestMonotonic(t *testing.T) {
for _, k := range monotonicKinds {
require.True(t, k.Monotonic())
}
for _, k := range nonMonotonicKinds {
require.False(t, k.Monotonic())
}
}
func TestPrecomputedSum(t *testing.T) {
for _, k := range precomputedSumKinds {
require.True(t, k.PrecomputedSum())
}
for _, k := range nonPrecomputedSumKinds {
require.False(t, k.PrecomputedSum())
}
}

View File

@ -1,16 +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 metrictest contains utilities for testing metrics.
package metrictest // import "go.opentelemetry.io/otel/api/metric/metrictest"

View File

@ -1,70 +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 metrictest
import (
"testing"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
)
// Measured is the helper struct which provides flat representation of recorded measurements
// to simplify testing
type Measured struct {
Name string
InstrumentationName string
InstrumentationVersion string
Labels map[label.Key]label.Value
Number metric.Number
}
// LabelsToMap converts label set to keyValue map, to be easily used in tests
func LabelsToMap(kvs ...label.KeyValue) map[label.Key]label.Value {
m := map[label.Key]label.Value{}
for _, label := range kvs {
m[label.Key] = label.Value
}
return m
}
// AsStructs converts recorded batches to array of flat, readable Measured helper structures
func AsStructs(batches []Batch) []Measured {
var r []Measured
for _, batch := range batches {
for _, m := range batch.Measurements {
r = append(r, Measured{
Name: m.Instrument.Descriptor().Name(),
InstrumentationName: m.Instrument.Descriptor().InstrumentationName(),
InstrumentationVersion: m.Instrument.Descriptor().InstrumentationVersion(),
Labels: LabelsToMap(batch.Labels...),
Number: m.Number,
})
}
}
return r
}
// ResolveNumberByKind takes defined metric descriptor creates a concrete typed metric number
func ResolveNumberByKind(t *testing.T, kind metric.NumberKind, value float64) metric.Number {
t.Helper()
switch kind {
case metric.Int64NumberKind:
return metric.NewInt64Number(int64(value))
case metric.Float64NumberKind:
return metric.NewFloat64Number(value)
}
panic("invalid number kind")
}

View File

@ -1,222 +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
// MeterMust is a wrapper for Meter interfaces that panics when any
// instrument constructor encounters an error.
type MeterMust struct {
meter Meter
}
// BatchObserverMust is a wrapper for BatchObserver that panics when
// any instrument constructor encounters an error.
type BatchObserverMust struct {
batch BatchObserver
}
// Must constructs a MeterMust implementation from a Meter, allowing
// the application to panic when any instrument constructor yields an
// error.
func Must(meter Meter) MeterMust {
return MeterMust{meter: meter}
}
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter {
if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter {
if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter {
if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter {
if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64ValueRecorder calls `Meter.NewInt64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...InstrumentOption) Int64ValueRecorder {
if inst, err := mm.meter.NewInt64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueRecorder calls `Meter.NewFloat64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...InstrumentOption) Float64ValueRecorder {
if inst, err := mm.meter.NewFloat64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64ValueObserver calls `Meter.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := mm.meter.NewInt64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueObserver calls `Meter.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := mm.meter.NewFloat64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64SumObserver calls `Meter.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64SumObserver {
if inst, err := mm.meter.NewInt64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64SumObserver calls `Meter.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64SumObserver {
if inst, err := mm.meter.NewFloat64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownSumObserver calls `Meter.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := mm.meter.NewInt64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownSumObserver calls `Meter.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := mm.meter.NewFloat64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewBatchObserver returns a wrapper around BatchObserver that panics
// when any instrument constructor returns an error.
func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust {
return BatchObserverMust{
batch: mm.meter.NewBatchObserver(callback),
}
}
// NewInt64ValueObserver calls `BatchObserver.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := bm.batch.NewInt64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueObserver calls `BatchObserver.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := bm.batch.NewFloat64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64SumObserver calls `BatchObserver.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...InstrumentOption) Int64SumObserver {
if inst, err := bm.batch.NewInt64SumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64SumObserver calls `BatchObserver.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...InstrumentOption) Float64SumObserver {
if inst, err := bm.batch.NewFloat64SumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownSumObserver calls `BatchObserver.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := bm.batch.NewInt64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownSumObserver calls `BatchObserver.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := bm.batch.NewFloat64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}

View File

@ -1,124 +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
// BatchObserver represents an Observer callback that can report
// observations for multiple instruments.
type BatchObserver struct {
meter Meter
runner AsyncBatchRunner
}
// Int64ValueObserver is a metric that captures a set of int64 values at a
// point in time.
type Int64ValueObserver struct {
asyncInstrument
}
// Float64ValueObserver is a metric that captures a set of float64 values
// at a point in time.
type Float64ValueObserver struct {
asyncInstrument
}
// Int64SumObserver is a metric that captures a precomputed sum of
// int64 values at a point in time.
type Int64SumObserver struct {
asyncInstrument
}
// Float64SumObserver is a metric that captures a precomputed sum of
// float64 values at a point in time.
type Float64SumObserver struct {
asyncInstrument
}
// Int64UpDownSumObserver is a metric that captures a precomputed sum of
// int64 values at a point in time.
type Int64UpDownSumObserver struct {
asyncInstrument
}
// Float64UpDownSumObserver is a metric that captures a precomputed sum of
// float64 values at a point in time.
type Float64UpDownSumObserver struct {
asyncInstrument
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64ValueObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64ValueObserver) Observation(v float64) Observation {
return Observation{
number: NewFloat64Number(v),
instrument: f.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64SumObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64SumObserver) Observation(v float64) Observation {
return Observation{
number: NewFloat64Number(v),
instrument: f.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64UpDownSumObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64UpDownSumObserver) Observation(v float64) Observation {
return Observation{
number: NewFloat64Number(v),
instrument: f.instrument,
}
}

View File

@ -1,192 +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 (
"context"
"errors"
"go.opentelemetry.io/otel/label"
)
// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation")
// 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
instrument SyncImpl
}
// syncInstrument contains a SyncImpl.
type syncInstrument struct {
instrument SyncImpl
}
// syncBoundInstrument contains a BoundSyncImpl.
type syncBoundInstrument struct {
boundInstrument 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 {
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 {
return m.number
}
// AsyncImpl implements AsyncImpl.
func (a asyncInstrument) AsyncImpl() AsyncImpl {
return a.instrument
}
// SyncImpl returns the implementation object for synchronous instruments.
func (s syncInstrument) SyncImpl() SyncImpl {
return s.instrument
}
func (s syncInstrument) bind(labels []label.KeyValue) syncBoundInstrument {
return newSyncBoundInstrument(s.instrument.Bind(labels))
}
func (s syncInstrument) float64Measurement(value float64) Measurement {
return newMeasurement(s.instrument, NewFloat64Number(value))
}
func (s syncInstrument) int64Measurement(value int64) Measurement {
return newMeasurement(s.instrument, NewInt64Number(value))
}
func (s syncInstrument) directRecord(ctx context.Context, number Number, labels []label.KeyValue) {
s.instrument.RecordOne(ctx, number, labels)
}
func (h syncBoundInstrument) directRecord(ctx context.Context, number Number) {
h.boundInstrument.RecordOne(ctx, number)
}
// Unbind calls SyncImpl.Unbind.
func (h syncBoundInstrument) Unbind() {
h.boundInstrument.Unbind()
}
// checkNewAsync receives an AsyncImpl and potential
// error, and returns the same types, checking for and ensuring that
// the returned interface is not nil.
func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) {
if instrument == nil {
if err == nil {
err = ErrSDKReturnedNilImpl
}
instrument = NoopAsync{}
}
return asyncInstrument{
instrument: instrument,
}, err
}
// 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) {
if instrument == nil {
if err == nil {
err = ErrSDKReturnedNilImpl
}
// Note: an alternate behavior would be to synthesize a new name
// or group all duplicately-named instruments of a certain type
// together and use a tag for the original name, e.g.,
// name = 'invalid.counter.int64'
// label = 'original-name=duplicate-counter-name'
instrument = NoopSync{}
}
return syncInstrument{
instrument: instrument,
}, err
}
func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument {
return syncBoundInstrument{
boundInstrument: boundInstrument,
}
}
func newMeasurement(instrument SyncImpl, number Number) Measurement {
return Measurement{
instrument: instrument,
number: number,
}
}
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
func wrapInt64CounterInstrument(syncInst 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) {
common, err := checkNewSync(syncInst, err)
return Float64Counter{syncInstrument: common}, err
}
// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter.
func wrapInt64UpDownCounterInstrument(syncInst 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) {
common, err := checkNewSync(syncInst, err)
return Float64UpDownCounter{syncInstrument: common}, err
}
// wrapInt64ValueRecorderInstrument converts a SyncImpl into Int64ValueRecorder.
func wrapInt64ValueRecorderInstrument(syncInst SyncImpl, err error) (Int64ValueRecorder, error) {
common, err := checkNewSync(syncInst, err)
return Int64ValueRecorder{syncInstrument: common}, err
}
// wrapFloat64ValueRecorderInstrument converts a SyncImpl into Float64ValueRecorder.
func wrapFloat64ValueRecorderInstrument(syncInst SyncImpl, err error) (Float64ValueRecorder, error) {
common, err := checkNewSync(syncInst, err)
return Float64ValueRecorder{syncInstrument: common}, err
}

View File

@ -1,96 +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 (
"context"
"go.opentelemetry.io/otel/label"
)
// Float64UpDownCounter is a metric instrument that sums floating
// point values.
type Float64UpDownCounter struct {
syncInstrument
}
// Int64UpDownCounter is a metric instrument that sums integer values.
type Int64UpDownCounter struct {
syncInstrument
}
// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64UpDownCounter struct {
syncBoundInstrument
}
// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64UpDownCounter struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64UpDownCounter) Bind(labels ...label.KeyValue) (h BoundFloat64UpDownCounter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64UpDownCounter) Bind(labels ...label.KeyValue) (h BoundInt64UpDownCounter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64UpDownCounter) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}

View File

@ -1,97 +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 (
"context"
"go.opentelemetry.io/otel/label"
)
// Float64ValueRecorder is a metric that records float64 values.
type Float64ValueRecorder struct {
syncInstrument
}
// Int64ValueRecorder is a metric that records int64 values.
type Int64ValueRecorder struct {
syncInstrument
}
// BoundFloat64ValueRecorder is a bound instrument for Float64ValueRecorder.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64ValueRecorder struct {
syncBoundInstrument
}
// BoundInt64ValueRecorder is a bound instrument for Int64ValueRecorder.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64ValueRecorder struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this ValueRecorder. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64ValueRecorder) Bind(labels ...label.KeyValue) (h BoundFloat64ValueRecorder) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this ValueRecorder. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64ValueRecorder) Bind(labels ...label.KeyValue) (h BoundInt64ValueRecorder) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64ValueRecorder) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64ValueRecorder) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Record adds a new value to the list of ValueRecorder's records. The
// labels should contain the keys and values to be associated with
// this value.
func (c Float64ValueRecorder) Record(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Record adds a new value to the ValueRecorder's distribution. The
// labels should contain the keys and values to be associated with
// this value.
func (c Int64ValueRecorder) Record(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Record adds a new value to the ValueRecorder's distribution using the labels
// previously bound to the ValueRecorder via Bind().
func (b BoundFloat64ValueRecorder) Record(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Record adds a new value to the ValueRecorder's distribution using the labels
// previously bound to the ValueRecorder via Bind().
func (b BoundInt64ValueRecorder) Record(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}

124
config.go
View File

@ -18,6 +18,7 @@ import (
"time"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/unit"
)
// TracerConfig is a group of options for a Tracer.
@ -41,15 +42,6 @@ type TracerOption interface {
ApplyTracer(*TracerConfig)
}
type instVersionTracerOption string
func (o instVersionTracerOption) ApplyTracer(c *TracerConfig) { c.InstrumentationVersion = string(o) }
// WithInstrumentationVersion sets the instrumentation version for a Tracer.
func WithInstrumentationVersion(version string) TracerOption {
return instVersionTracerOption(version)
}
// SpanConfig is a group of options for a Span.
type SpanConfig struct {
// Attributes describe the associated qualities of a Span.
@ -186,3 +178,117 @@ func (o spanKindSpanOption) ApplySpan(c *SpanConfig) { c.SpanKind = SpanKind(o)
func WithSpanKind(kind SpanKind) SpanOption {
return spanKindSpanOption(kind)
}
// InstrumentConfig contains options for metric instrument descriptors.
type InstrumentConfig struct {
// Description describes the instrument in human-readable terms.
Description string
// Unit describes the measurement unit for a instrument.
Unit unit.Unit
// InstrumentationName is the name of the library providing
// instrumentation.
InstrumentationName string
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// InstrumentOption is an interface for applying metric instrument options.
type InstrumentOption interface {
// ApplyMeter is used to set a InstrumentOption value of a
// InstrumentConfig.
ApplyInstrument(*InstrumentConfig)
}
// NewInstrumentConfig creates a new InstrumentConfig
// and applies all the given options.
func NewInstrumentConfig(opts ...InstrumentOption) InstrumentConfig {
var config InstrumentConfig
for _, o := range opts {
o.ApplyInstrument(&config)
}
return config
}
// WithDescription applies provided description.
func WithDescription(desc string) InstrumentOption {
return descriptionOption(desc)
}
type descriptionOption string
func (d descriptionOption) ApplyInstrument(config *InstrumentConfig) {
config.Description = string(d)
}
// WithUnit applies provided unit.
func WithUnit(unit unit.Unit) InstrumentOption {
return unitOption(unit)
}
type unitOption unit.Unit
func (u unitOption) ApplyInstrument(config *InstrumentConfig) {
config.Unit = unit.Unit(u)
}
// WithInstrumentationName sets the instrumentation name.
func WithInstrumentationName(name string) InstrumentOption {
return instrumentationNameOption(name)
}
type instrumentationNameOption string
func (i instrumentationNameOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationName = string(i)
}
// MeterConfig contains options for Meters.
type MeterConfig struct {
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// MeterOption is an interface for applying Meter options.
type MeterOption interface {
// ApplyMeter is used to set a MeterOption value of a MeterConfig.
ApplyMeter(*MeterConfig)
}
// NewMeterConfig creates a new MeterConfig and applies
// all the given options.
func NewMeterConfig(opts ...MeterOption) MeterConfig {
var config MeterConfig
for _, o := range opts {
o.ApplyMeter(&config)
}
return config
}
// InstrumentationOption is an interface for applying instrumentation specific
// options.
type InstrumentationOption interface {
InstrumentOption
MeterOption
TracerOption
}
// WithInstrumentationVersion sets the instrumentation version.
func WithInstrumentationVersion(version string) InstrumentationOption {
return instrumentationVersionOption(version)
}
type instrumentationVersionOption string
func (i instrumentationVersionOption) ApplyMeter(config *MeterConfig) {
config.InstrumentationVersion = string(i)
}
func (i instrumentationVersionOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationVersion = string(i)
}
func (i instrumentationVersionOption) ApplyTracer(config *TracerConfig) {
config.InstrumentationVersion = string(i)
}

46
doc.go
View File

@ -69,5 +69,51 @@ used as a default.
defer span.End()
// ...
}
Metric Measurements
Measurements can be made about an operation being performed or the state of a
system in general. These measurements can be crucial to the reliable operation
of code and provide valuable insights about the inner workings of a system.
Measurements are made using instruments provided by this package. The type of
instrument used will depend on the type of measurement being made and of what
part of a system is being measured.
Instruments are categorized as Synchronous or Asynchronous and independently
as Adding or Grouping. Synchronous instruments are called by the user with a
Context. Asynchronous instruments are called by the SDK during collection.
Additive instruments are semantically intended for capturing a sum. Grouping
instruments are intended for capturing a distribution.
Additive instruments may be monotonic, in which case they are non-decreasing
and naturally define a rate.
The synchronous instrument names are:
Counter: additive, monotonic
UpDownCounter: additive
ValueRecorder: grouping
and the asynchronous instruments are:
SumObserver: additive, monotonic
UpDownSumObserver: additive
ValueObserver: grouping
All instruments are provided with support for either float64 or int64 input
values.
An instrument is created using a Meter. Additionally, a Meter is used to
record batches of synchronous measurements or asynchronous observations. A
Meter is obtained using a MeterProvider. A Meter, like a Tracer, is unique to
the instrumentation it instruments and must be named and versioned when
created with a MeterProvider with the name and version of the instrumentation
library.
Instrumentation should be designed to accept a MeterProvider from which it can
create its own unique Meter. Alternatively, the registered global
MeterProvider from the go.opentelemetry.io/otel/api/global package can be used
as a default.
*/
package otel // import "go.opentelemetry.io/otel"

View File

@ -14,15 +14,6 @@
package otel
import (
"go.opentelemetry.io/otel/api/metric"
)
// Meter is the creator of metric instruments.
//
// An uninitialized Meter is a no-op implementation.
type Meter = metric.Meter
// ErrorHandler handles irremediable events.
type ErrorHandler interface {
// Handle handles any error deemed irremediable by an OpenTelemetry

View File

@ -20,7 +20,6 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/stdout"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/propagators"
@ -68,14 +67,14 @@ func main() {
commonLabels := []label.KeyValue{lemonsKey.Int(10), label.String("A", "1"), label.String("B", "2"), label.String("C", "3")}
oneMetricCB := func(_ context.Context, result metric.Float64ObserverResult) {
oneMetricCB := func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(1, commonLabels...)
}
_ = metric.Must(meter).NewFloat64ValueObserver("ex.com.one", oneMetricCB,
metric.WithDescription("A ValueObserver set to 1.0"),
_ = otel.Must(meter).NewFloat64ValueObserver("ex.com.one", oneMetricCB,
otel.WithDescription("A ValueObserver set to 1.0"),
)
valuerecorderTwo := metric.Must(meter).NewFloat64ValueRecorder("ex.com.two")
valuerecorderTwo := otel.Must(meter).NewFloat64ValueRecorder("ex.com.two")
ctx := context.Background()
ctx = otel.ContextWithBaggageValues(ctx, fooKey.String("foo1"), barKey.String("bar1"))

View File

@ -27,7 +27,6 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/otlp"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/propagators"
@ -105,10 +104,10 @@ func main() {
}
// Recorder metric example
valuerecorder := metric.Must(meter).
valuerecorder := otel.Must(meter).
NewFloat64Counter(
"an_important_metric",
metric.WithDescription("Measures the cumulative epicness of the app"),
otel.WithDescription("Measures the cumulative epicness of the app"),
).Bind(commonLabels...)
defer valuerecorder.Unbind()

View File

@ -22,8 +22,8 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/label"
)
@ -52,19 +52,19 @@ func main() {
observerLock := new(sync.RWMutex)
observerValueToReport := new(float64)
observerLabelsToReport := new([]label.KeyValue)
cb := func(_ context.Context, result metric.Float64ObserverResult) {
cb := func(_ context.Context, result otel.Float64ObserverResult) {
(*observerLock).RLock()
value := *observerValueToReport
labels := *observerLabelsToReport
(*observerLock).RUnlock()
result.Observe(value, labels...)
}
_ = metric.Must(meter).NewFloat64ValueObserver("ex.com.one", cb,
metric.WithDescription("A ValueObserver set to 1.0"),
_ = otel.Must(meter).NewFloat64ValueObserver("ex.com.one", cb,
otel.WithDescription("A ValueObserver set to 1.0"),
)
valuerecorder := metric.Must(meter).NewFloat64ValueRecorder("ex.com.two")
counter := metric.Must(meter).NewFloat64Counter("ex.com.three")
valuerecorder := otel.Must(meter).NewFloat64ValueRecorder("ex.com.two")
counter := otel.Must(meter).NewFloat64Counter("ex.com.three")
commonLabels := []label.KeyValue{lemonsKey.Int(10), label.String("A", "1"), label.String("B", "2"), label.String("C", "3")}
notSoCommonLabels := []label.KeyValue{lemonsKey.Int(13)}

View File

@ -22,7 +22,7 @@ import (
"net/http"
"net/http/httptest"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/sdk/metric/controller/pull"
@ -32,7 +32,7 @@ import (
// This test demonstrates that it is relatively difficult to setup a
// Prometheus export pipeline:
//
// 1. The default boundaries are difficult to pass, should be []float instead of []metric.Number
// 1. The default boundaries are difficult to pass, should be []float instead of []otel.Number
//
// TODO: Address this issue.
@ -49,13 +49,13 @@ func ExampleNewExportPipeline() {
ctx := context.Background()
// Use two instruments
counter := metric.Must(meter).NewInt64Counter(
counter := otel.Must(meter).NewInt64Counter(
"a.counter",
metric.WithDescription("Counts things"),
otel.WithDescription("Counts things"),
)
recorder := metric.Must(meter).NewInt64ValueRecorder(
recorder := otel.Must(meter).NewInt64ValueRecorder(
"a.valuerecorder",
metric.WithDescription("Records values"),
otel.WithDescription("Records values"),
)
counter.Add(ctx, 100, label.String("key", "value"))

View File

@ -23,8 +23,8 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -155,7 +155,7 @@ func (e *Exporter) SetController(config Config, options ...pull.Option) {
}
// MeterProvider returns the MeterProvider of this exporter.
func (e *Exporter) MeterProvider() metric.MeterProvider {
func (e *Exporter) MeterProvider() otel.MeterProvider {
return e.controller.MeterProvider()
}
@ -166,7 +166,7 @@ func (e *Exporter) Controller() *pull.Controller {
return e.controller
}
func (e *Exporter) ExportKindFor(*metric.Descriptor, aggregation.Kind) export.ExportKind {
func (e *Exporter) ExportKindFor(*otel.Descriptor, aggregation.Kind) export.ExportKind {
// NOTE: Summary values should use Delta aggregation, then be
// combined into a sliding window, see the TODO below.
// NOTE: Prometheus also supports a "GaugeDelta" exposition format,
@ -252,7 +252,7 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
}
}
func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregation.LastValue, kind metric.NumberKind, desc *prometheus.Desc, labels []string) error {
func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregation.LastValue, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
lv, _, err := lvagg.LastValue()
if err != nil {
return fmt.Errorf("error retrieving last value: %w", err)
@ -267,7 +267,7 @@ func (c *collector) exportLastValue(ch chan<- prometheus.Metric, lvagg aggregati
return nil
}
func (c *collector) exportCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind metric.NumberKind, desc *prometheus.Desc, labels []string) error {
func (c *collector) exportCounter(ch chan<- prometheus.Metric, sum aggregation.Sum, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
v, err := sum.Sum()
if err != nil {
return fmt.Errorf("error retrieving counter: %w", err)
@ -282,13 +282,13 @@ func (c *collector) exportCounter(ch chan<- prometheus.Metric, sum aggregation.S
return nil
}
func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.Distribution, kind metric.NumberKind, desc *prometheus.Desc, labels []string) error {
func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.Distribution, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
count, err := dist.Count()
if err != nil {
return fmt.Errorf("error retrieving count: %w", err)
}
var sum metric.Number
var sum otel.Number
sum, err = dist.Sum()
if err != nil {
return fmt.Errorf("error retrieving distribution sum: %w", err)
@ -309,7 +309,7 @@ func (c *collector) exportSummary(ch chan<- prometheus.Metric, dist aggregation.
return nil
}
func (c *collector) exportHistogram(ch chan<- prometheus.Metric, hist aggregation.Histogram, kind metric.NumberKind, desc *prometheus.Desc, labels []string) error {
func (c *collector) exportHistogram(ch chan<- prometheus.Metric, hist aggregation.Histogram, kind otel.NumberKind, desc *prometheus.Desc, labels []string) error {
buckets, err := hist.Histogram()
if err != nil {
return fmt.Errorf("error retrieving histogram: %w", err)

View File

@ -26,7 +26,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/sdk/metric/controller/pull"
@ -45,8 +45,8 @@ func TestPrometheusExporter(t *testing.T) {
meter := exporter.MeterProvider().Meter("test")
counter := metric.Must(meter).NewFloat64Counter("counter")
valuerecorder := metric.Must(meter).NewFloat64ValueRecorder("valuerecorder")
counter := otel.Must(meter).NewFloat64Counter("counter")
valuerecorder := otel.Must(meter).NewFloat64ValueRecorder("valuerecorder")
labels := []label.KeyValue{
label.Key("A").String("B"),
@ -123,9 +123,9 @@ func TestPrometheusStatefulness(t *testing.T) {
ctx := context.Background()
counter := metric.Must(meter).NewInt64Counter(
counter := otel.Must(meter).NewInt64Counter(
"a.counter",
metric.WithDescription("Counts things"),
otel.WithDescription("Counts things"),
)
counter.Add(ctx, 100, label.String("key", "value"))

View File

@ -24,11 +24,11 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel"
commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
resourcepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/resource/v1"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -294,7 +294,7 @@ func Record(r export.Record) (*metricpb.Metric, error) {
}
}
func gauge(record export.Record, num metric.Number, start, end time.Time) (*metricpb.Metric, error) {
func gauge(record export.Record, num otel.Number, start, end time.Time) (*metricpb.Metric, error) {
desc := record.Descriptor()
labels := record.Labels()
@ -305,7 +305,7 @@ func gauge(record export.Record, num metric.Number, start, end time.Time) (*metr
}
switch n := desc.NumberKind(); n {
case metric.Int64NumberKind:
case otel.Int64NumberKind:
m.Data = &metricpb.Metric_IntGauge{
IntGauge: &metricpb.IntGauge{
DataPoints: []*metricpb.IntDataPoint{
@ -318,7 +318,7 @@ func gauge(record export.Record, num metric.Number, start, end time.Time) (*metr
},
},
}
case metric.Float64NumberKind:
case otel.Float64NumberKind:
m.Data = &metricpb.Metric_DoubleGauge{
DoubleGauge: &metricpb.DoubleGauge{
DataPoints: []*metricpb.DoubleDataPoint{
@ -340,7 +340,7 @@ func gauge(record export.Record, num metric.Number, start, end time.Time) (*metr
// scalar transforms a Sum or LastValue Aggregator into an OTLP Metric.
// For LastValue (Gauge), use start==time.Time{}.
func scalar(record export.Record, num metric.Number, start, end time.Time) (*metricpb.Metric, error) {
func scalar(record export.Record, num otel.Number, start, end time.Time) (*metricpb.Metric, error) {
desc := record.Descriptor()
labels := record.Labels()
@ -351,7 +351,7 @@ func scalar(record export.Record, num metric.Number, start, end time.Time) (*met
}
switch n := desc.NumberKind(); n {
case metric.Int64NumberKind:
case otel.Int64NumberKind:
m.Data = &metricpb.Metric_IntSum{
IntSum: &metricpb.IntSum{
DataPoints: []*metricpb.IntDataPoint{
@ -364,7 +364,7 @@ func scalar(record export.Record, num metric.Number, start, end time.Time) (*met
},
},
}
case metric.Float64NumberKind:
case otel.Float64NumberKind:
m.Data = &metricpb.Metric_DoubleSum{
DoubleSum: &metricpb.DoubleSum{
DataPoints: []*metricpb.DoubleDataPoint{
@ -386,7 +386,7 @@ func scalar(record export.Record, num metric.Number, start, end time.Time) (*met
// minMaxSumCountValue returns the values of the MinMaxSumCount Aggregator
// as discrete values.
func minMaxSumCountValues(a aggregation.MinMaxSumCount) (min, max, sum metric.Number, count int64, err error) {
func minMaxSumCountValues(a aggregation.MinMaxSumCount) (min, max, sum otel.Number, count int64, err error) {
if min, err = a.Min(); err != nil {
return
}
@ -421,7 +421,7 @@ func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metric
bounds := []float64{0.0, 100.0}
switch n := desc.NumberKind(); n {
case metric.Int64NumberKind:
case otel.Int64NumberKind:
m.Data = &metricpb.Metric_IntHistogram{
IntHistogram: &metricpb.IntHistogram{
DataPoints: []*metricpb.IntHistogramDataPoint{
@ -437,7 +437,7 @@ func minMaxSumCount(record export.Record, a aggregation.MinMaxSumCount) (*metric
},
},
}
case metric.Float64NumberKind:
case otel.Float64NumberKind:
m.Data = &metricpb.Metric_DoubleHistogram{
DoubleHistogram: &metricpb.DoubleHistogram{
DataPoints: []*metricpb.DoubleHistogramDataPoint{
@ -501,7 +501,7 @@ func histogram(record export.Record, a aggregation.Histogram) (*metricpb.Metric,
Unit: string(desc.Unit()),
}
switch n := desc.NumberKind(); n {
case metric.Int64NumberKind:
case otel.Int64NumberKind:
m.Data = &metricpb.Metric_IntHistogram{
IntHistogram: &metricpb.IntHistogram{
DataPoints: []*metricpb.IntHistogramDataPoint{
@ -517,7 +517,7 @@ func histogram(record export.Record, a aggregation.Histogram) (*metricpb.Metric,
},
},
}
case metric.Float64NumberKind:
case otel.Float64NumberKind:
m.Data = &metricpb.Metric_DoubleHistogram{
DoubleHistogram: &metricpb.DoubleHistogram{
DataPoints: []*metricpb.DoubleHistogramDataPoint{

View File

@ -24,10 +24,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -96,28 +96,28 @@ func TestStringKeyValues(t *testing.T) {
}
func TestMinMaxSumCountValue(t *testing.T) {
mmsc, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &metric.Descriptor{}))
mmsc, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &otel.Descriptor{}))
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, &otel.Descriptor{}))
assert.NoError(t, mmsc.Update(context.Background(), 10, &otel.Descriptor{}))
// Prior to checkpointing ErrNoData should be returned.
_, _, _, _, err := minMaxSumCountValues(ckpt.(aggregation.MinMaxSumCount))
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, &otel.Descriptor{}))
min, max, sum, count, err := minMaxSumCountValues(ckpt.(aggregation.MinMaxSumCount))
if assert.NoError(t, err) {
assert.Equal(t, min, metric.NewInt64Number(1))
assert.Equal(t, max, metric.NewInt64Number(10))
assert.Equal(t, sum, metric.NewInt64Number(11))
assert.Equal(t, min, otel.NewInt64Number(1))
assert.Equal(t, max, otel.NewInt64Number(10))
assert.Equal(t, sum, otel.NewInt64Number(11))
assert.Equal(t, count, int64(2))
}
}
func TestMinMaxSumCountDatapoints(t *testing.T) {
desc := metric.NewDescriptor("", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
labels := label.NewSet()
mmsc, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &desc))
@ -149,17 +149,17 @@ 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, &otel.Descriptor{})[0]
_, _, _, _, err := minMaxSumCountValues(mmsc)
assert.Error(t, err)
assert.Equal(t, aggregation.ErrNoData, err)
}
func TestSumIntDataPoints(t *testing.T) {
desc := metric.NewDescriptor("", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
labels := label.NewSet()
s, ckpt := metrictest.Unslice2(sumAgg.New(2))
assert.NoError(t, s.Update(context.Background(), metric.Number(1), &desc))
assert.NoError(t, s.Update(context.Background(), otel.Number(1), &desc))
require.NoError(t, s.SynchronizedMove(ckpt, &desc))
record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
sum, ok := ckpt.(aggregation.Sum)
@ -181,10 +181,10 @@ func TestSumIntDataPoints(t *testing.T) {
}
func TestSumFloatDataPoints(t *testing.T) {
desc := metric.NewDescriptor("", metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
labels := label.NewSet()
s, ckpt := metrictest.Unslice2(sumAgg.New(2))
assert.NoError(t, s.Update(context.Background(), metric.NewFloat64Number(1), &desc))
assert.NoError(t, s.Update(context.Background(), otel.NewFloat64Number(1), &desc))
require.NoError(t, s.SynchronizedMove(ckpt, &desc))
record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
sum, ok := ckpt.(aggregation.Sum)
@ -207,10 +207,10 @@ func TestSumFloatDataPoints(t *testing.T) {
}
func TestLastValueIntDataPoints(t *testing.T) {
desc := metric.NewDescriptor("", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
labels := label.NewSet()
s, ckpt := metrictest.Unslice2(lvAgg.New(2))
assert.NoError(t, s.Update(context.Background(), metric.Number(100), &desc))
assert.NoError(t, s.Update(context.Background(), otel.Number(100), &desc))
require.NoError(t, s.SynchronizedMove(ckpt, &desc))
record := export.NewRecord(&desc, &labels, nil, ckpt.Aggregation(), intervalStart, intervalEnd)
sum, ok := ckpt.(aggregation.LastValue)
@ -233,7 +233,7 @@ func TestLastValueIntDataPoints(t *testing.T) {
}
func TestSumErrUnknownValueType(t *testing.T) {
desc := metric.NewDescriptor("", metric.ValueRecorderInstrumentKind, metric.NumberKind(-1))
desc := otel.NewDescriptor("", otel.ValueRecorderInstrumentKind, otel.NumberKind(-1))
labels := label.NewSet()
s := &sumAgg.New(1)[0]
record := export.NewRecord(&desc, &labels, nil, s, intervalStart, intervalEnd)
@ -262,13 +262,13 @@ func (t *testAgg) Aggregation() aggregation.Aggregation {
// None of these three are used:
func (t *testAgg) Update(ctx context.Context, number metric.Number, descriptor *metric.Descriptor) error {
func (t *testAgg) Update(ctx context.Context, number otel.Number, descriptor *otel.Descriptor) error {
return nil
}
func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *metric.Descriptor) error {
func (t *testAgg) SynchronizedMove(destination export.Aggregator, descriptor *otel.Descriptor) error {
return nil
}
func (t *testAgg) Merge(aggregator export.Aggregator, descriptor *metric.Descriptor) error {
func (t *testAgg) Merge(aggregator export.Aggregator, descriptor *otel.Descriptor) error {
return nil
}
@ -284,25 +284,25 @@ type testErrMinMaxSumCount struct {
testErrSum
}
func (te *testErrLastValue) LastValue() (metric.Number, time.Time, error) {
func (te *testErrLastValue) LastValue() (otel.Number, time.Time, error) {
return 0, time.Time{}, te.err
}
func (te *testErrLastValue) Kind() aggregation.Kind {
return aggregation.LastValueKind
}
func (te *testErrSum) Sum() (metric.Number, error) {
func (te *testErrSum) Sum() (otel.Number, error) {
return 0, te.err
}
func (te *testErrSum) Kind() aggregation.Kind {
return aggregation.SumKind
}
func (te *testErrMinMaxSumCount) Min() (metric.Number, error) {
func (te *testErrMinMaxSumCount) Min() (otel.Number, error) {
return 0, te.err
}
func (te *testErrMinMaxSumCount) Max() (metric.Number, error) {
func (te *testErrMinMaxSumCount) Max() (otel.Number, error) {
return 0, te.err
}
@ -318,7 +318,7 @@ var _ aggregation.MinMaxSumCount = &testErrMinMaxSumCount{}
func TestRecordAggregatorIncompatibleErrors(t *testing.T) {
makeMpb := func(kind aggregation.Kind, agg aggregation.Aggregation) (*metricpb.Metric, error) {
desc := metric.NewDescriptor("things", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, otel.Int64NumberKind)
labels := label.NewSet()
res := resource.New()
test := &testAgg{
@ -355,7 +355,7 @@ func TestRecordAggregatorIncompatibleErrors(t *testing.T) {
func TestRecordAggregatorUnexpectedErrors(t *testing.T) {
makeMpb := func(kind aggregation.Kind, agg aggregation.Aggregation) (*metricpb.Metric, error) {
desc := metric.NewDescriptor("things", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("things", otel.CounterInstrumentKind, otel.Int64NumberKind)
labels := label.NewSet()
res := resource.New()
return Record(export.NewRecord(&desc, &labels, res, agg, intervalStart, intervalEnd))

View File

@ -27,10 +27,10 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"go.opentelemetry.io/otel"
colmetricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/metrics/v1"
coltracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/trace/v1"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/otlp/internal/transform"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -287,7 +287,7 @@ func (e *Exporter) Export(parent context.Context, cps metricsdk.CheckpointSet) e
// ExportKindFor reports back to the OpenTelemetry SDK sending this Exporter
// metric telemetry that it needs to be provided in a pass-through format.
func (e *Exporter) ExportKindFor(*metric.Descriptor, aggregation.Kind) metricsdk.ExportKind {
func (e *Exporter) ExportKindFor(*otel.Descriptor, aggregation.Kind) metricsdk.ExportKind {
return metricsdk.PassThroughExporter
}

View File

@ -25,11 +25,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/api/metric"
metricapi "go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/otlp"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
exporttrace "go.opentelemetry.io/otel/sdk/export/trace"
@ -130,52 +129,52 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
labels := []label.KeyValue{label.Bool("test", true)}
type data struct {
iKind metric.InstrumentKind
nKind metricapi.NumberKind
iKind otel.InstrumentKind
nKind otel.NumberKind
val int64
}
instruments := map[string]data{
"test-int64-counter": {metric.CounterInstrumentKind, metricapi.Int64NumberKind, 1},
"test-float64-counter": {metric.CounterInstrumentKind, metricapi.Float64NumberKind, 1},
"test-int64-valuerecorder": {metric.ValueRecorderInstrumentKind, metricapi.Int64NumberKind, 2},
"test-float64-valuerecorder": {metric.ValueRecorderInstrumentKind, metricapi.Float64NumberKind, 2},
"test-int64-valueobserver": {metric.ValueObserverInstrumentKind, metricapi.Int64NumberKind, 3},
"test-float64-valueobserver": {metric.ValueObserverInstrumentKind, metricapi.Float64NumberKind, 3},
"test-int64-counter": {otel.CounterInstrumentKind, otel.Int64NumberKind, 1},
"test-float64-counter": {otel.CounterInstrumentKind, otel.Float64NumberKind, 1},
"test-int64-valuerecorder": {otel.ValueRecorderInstrumentKind, otel.Int64NumberKind, 2},
"test-float64-valuerecorder": {otel.ValueRecorderInstrumentKind, otel.Float64NumberKind, 2},
"test-int64-valueobserver": {otel.ValueObserverInstrumentKind, otel.Int64NumberKind, 3},
"test-float64-valueobserver": {otel.ValueObserverInstrumentKind, otel.Float64NumberKind, 3},
}
for name, data := range instruments {
data := data
switch data.iKind {
case metric.CounterInstrumentKind:
case otel.CounterInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
metricapi.Must(meter).NewInt64Counter(name).Add(ctx, data.val, labels...)
case metricapi.Float64NumberKind:
metricapi.Must(meter).NewFloat64Counter(name).Add(ctx, float64(data.val), labels...)
case otel.Int64NumberKind:
otel.Must(meter).NewInt64Counter(name).Add(ctx, data.val, labels...)
case otel.Float64NumberKind:
otel.Must(meter).NewFloat64Counter(name).Add(ctx, float64(data.val), labels...)
default:
assert.Failf(t, "unsupported number testing kind", data.nKind.String())
}
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
metricapi.Must(meter).NewInt64ValueRecorder(name).Record(ctx, data.val, labels...)
case metricapi.Float64NumberKind:
metricapi.Must(meter).NewFloat64ValueRecorder(name).Record(ctx, float64(data.val), labels...)
case otel.Int64NumberKind:
otel.Must(meter).NewInt64ValueRecorder(name).Record(ctx, data.val, labels...)
case otel.Float64NumberKind:
otel.Must(meter).NewFloat64ValueRecorder(name).Record(ctx, float64(data.val), labels...)
default:
assert.Failf(t, "unsupported number testing kind", data.nKind.String())
}
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
metricapi.Must(meter).NewInt64ValueObserver(name,
func(_ context.Context, result metricapi.Int64ObserverResult) {
case otel.Int64NumberKind:
otel.Must(meter).NewInt64ValueObserver(name,
func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(data.val, labels...)
},
)
case metricapi.Float64NumberKind:
callback := func(v float64) metricapi.Float64ObserverFunc {
return metricapi.Float64ObserverFunc(func(_ context.Context, result metricapi.Float64ObserverResult) { result.Observe(v, labels...) })
case otel.Float64NumberKind:
callback := func(v float64) otel.Float64ObserverFunc {
return otel.Float64ObserverFunc(func(_ context.Context, result otel.Float64ObserverResult) { result.Observe(v, labels...) })
}(float64(data.val))
metricapi.Must(meter).NewFloat64ValueObserver(name, callback)
otel.Must(meter).NewFloat64ValueObserver(name, callback)
default:
assert.Failf(t, "unsupported number testing kind", data.nKind.String())
}
@ -245,42 +244,42 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption)
seen[m.Name] = struct{}{}
switch data.iKind {
case metric.CounterInstrumentKind:
case otel.CounterInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
case otel.Int64NumberKind:
if dp := m.GetIntSum().DataPoints; assert.Len(t, dp, 1) {
assert.Equal(t, data.val, dp[0].Value, "invalid value for %q", m.Name)
}
case metricapi.Float64NumberKind:
case otel.Float64NumberKind:
if dp := m.GetDoubleSum().DataPoints; assert.Len(t, dp, 1) {
assert.Equal(t, float64(data.val), dp[0].Value, "invalid value for %q", m.Name)
}
default:
assert.Failf(t, "invalid number kind", data.nKind.String())
}
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
case otel.Int64NumberKind:
if dp := m.GetIntGauge().DataPoints; assert.Len(t, dp, 1) {
assert.Equal(t, data.val, dp[0].Value, "invalid value for %q", m.Name)
}
case metricapi.Float64NumberKind:
case otel.Float64NumberKind:
if dp := m.GetDoubleGauge().DataPoints; assert.Len(t, dp, 1) {
assert.Equal(t, float64(data.val), dp[0].Value, "invalid value for %q", m.Name)
}
default:
assert.Failf(t, "invalid number kind", data.nKind.String())
}
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
switch data.nKind {
case metricapi.Int64NumberKind:
case otel.Int64NumberKind:
assert.NotNil(t, m.GetIntHistogram())
if dp := m.GetIntHistogram().DataPoints; assert.Len(t, dp, 1) {
count := dp[0].Count
assert.Equal(t, uint64(1), count, "invalid count for %q", m.Name)
assert.Equal(t, int64(data.val*int64(count)), dp[0].Sum, "invalid sum for %q (value %d)", m.Name, data.val)
}
case metricapi.Float64NumberKind:
case otel.Float64NumberKind:
assert.NotNil(t, m.GetDoubleHistogram())
if dp := m.GetDoubleHistogram().DataPoints; assert.Len(t, dp, 1) {
count := dp[0].Count

View File

@ -23,12 +23,12 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
colmetricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/metrics/v1"
commonpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/common/v1"
metricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/metrics/v1"
resourcepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/resource/v1"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -93,10 +93,10 @@ func (m *checkpointSet) ForEach(_ metricsdk.ExportKindSelector, fn func(metricsd
type record struct {
name string
iKind metric.InstrumentKind
nKind metric.NumberKind
iKind otel.InstrumentKind
nKind otel.NumberKind
resource *resource.Resource
opts []metric.InstrumentOption
opts []otel.InstrumentOption
labels []label.KeyValue
}
@ -162,16 +162,16 @@ func TestNoGroupingExport(t *testing.T) {
[]record{
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
nil,
nil,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
nil,
nil,
append(baseKeyValues, cpuKey.Int(2)),
@ -217,8 +217,8 @@ func TestNoGroupingExport(t *testing.T) {
func TestValuerecorderMetricGroupingExport(t *testing.T) {
r := record{
"valuerecorder",
metric.ValueRecorderInstrumentKind,
metric.Int64NumberKind,
otel.ValueRecorderInstrumentKind,
otel.Int64NumberKind,
nil,
nil,
append(baseKeyValues, cpuKey.Int(1)),
@ -286,8 +286,8 @@ func TestValuerecorderMetricGroupingExport(t *testing.T) {
func TestCountInt64MetricGroupingExport(t *testing.T) {
r := record{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
nil,
nil,
append(baseKeyValues, cpuKey.Int(1)),
@ -335,8 +335,8 @@ func TestCountInt64MetricGroupingExport(t *testing.T) {
func TestCountFloat64MetricGroupingExport(t *testing.T) {
r := record{
"float64-count",
metric.CounterInstrumentKind,
metric.Float64NumberKind,
otel.CounterInstrumentKind,
otel.Float64NumberKind,
nil,
nil,
append(baseKeyValues, cpuKey.Int(1)),
@ -405,32 +405,32 @@ func TestResourceMetricGroupingExport(t *testing.T) {
[]record{
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
nil,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
nil,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
nil,
append(baseKeyValues, cpuKey.Int(2)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstB,
nil,
append(baseKeyValues, cpuKey.Int(1)),
@ -506,64 +506,64 @@ func TestResourceMetricGroupingExport(t *testing.T) {
}
func TestResourceInstLibMetricGroupingExport(t *testing.T) {
countingLib1 := []metric.InstrumentOption{
metric.WithInstrumentationName("counting-lib"),
metric.WithInstrumentationVersion("v1"),
countingLib1 := []otel.InstrumentOption{
otel.WithInstrumentationName("counting-lib"),
otel.WithInstrumentationVersion("v1"),
}
countingLib2 := []metric.InstrumentOption{
metric.WithInstrumentationName("counting-lib"),
metric.WithInstrumentationVersion("v2"),
countingLib2 := []otel.InstrumentOption{
otel.WithInstrumentationName("counting-lib"),
otel.WithInstrumentationVersion("v2"),
}
summingLib := []metric.InstrumentOption{
metric.WithInstrumentationName("summing-lib"),
summingLib := []otel.InstrumentOption{
otel.WithInstrumentationName("summing-lib"),
}
runMetricExportTests(
t,
[]record{
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
countingLib2,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
countingLib1,
append(baseKeyValues, cpuKey.Int(2)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstA,
summingLib,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterInstrumentKind,
metric.Int64NumberKind,
otel.CounterInstrumentKind,
otel.Int64NumberKind,
testInstB,
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
@ -713,12 +713,12 @@ func runMetricExportTest(t *testing.T, exp *Exporter, rs []record, expected []me
recs := map[label.Distinct][]metricsdk.Record{}
resources := map[label.Distinct]*resource.Resource{}
for _, r := range rs {
desc := metric.NewDescriptor(r.name, r.iKind, r.nKind, r.opts...)
desc := otel.NewDescriptor(r.name, r.iKind, r.nKind, r.opts...)
labs := label.NewSet(r.labels...)
var agg, ckpt metricsdk.Aggregator
switch r.iKind {
case metric.CounterInstrumentKind:
case otel.CounterInstrumentKind:
agg, ckpt = metrictest.Unslice2(sum.New(2))
default:
agg, ckpt = metrictest.Unslice2(histogram.New(2, &desc, testHistogramBoundaries))
@ -726,12 +726,12 @@ func runMetricExportTest(t *testing.T, exp *Exporter, rs []record, expected []me
ctx := context.Background()
switch r.nKind {
case metric.Int64NumberKind:
require.NoError(t, agg.Update(ctx, metric.NewInt64Number(1), &desc))
require.NoError(t, agg.Update(ctx, metric.NewInt64Number(10), &desc))
case metric.Float64NumberKind:
require.NoError(t, agg.Update(ctx, metric.NewFloat64Number(1), &desc))
require.NoError(t, agg.Update(ctx, metric.NewFloat64Number(10), &desc))
case otel.Int64NumberKind:
require.NoError(t, agg.Update(ctx, otel.NewInt64Number(1), &desc))
require.NoError(t, agg.Update(ctx, otel.NewInt64Number(10), &desc))
case otel.Float64NumberKind:
require.NoError(t, agg.Update(ctx, otel.NewFloat64Number(1), &desc))
require.NoError(t, agg.Update(ctx, otel.NewFloat64Number(10), &desc))
default:
t.Fatalf("invalid number kind: %v", r.nKind)
}

View File

@ -20,7 +20,6 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/exporters/stdout"
"go.opentelemetry.io/otel/label"
)
@ -38,11 +37,11 @@ var (
meter = global.MeterProvider().Meter(
instrumentationName,
metric.WithInstrumentationVersion(instrumentationVersion),
otel.WithInstrumentationVersion(instrumentationVersion),
)
loopCounter = metric.Must(meter).NewInt64Counter("function.loops")
paramValue = metric.Must(meter).NewInt64ValueRecorder("function.param")
loopCounter = otel.Must(meter).NewInt64Counter("function.loops")
paramValue = otel.Must(meter).NewInt64ValueRecorder("function.param")
nameKey = label.Key("function.name")
)

View File

@ -21,9 +21,9 @@ import (
"strings"
"time"
apimetric "go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/sdk/export/metric"
exportmetric "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
)
@ -31,7 +31,7 @@ type metricExporter struct {
config Config
}
var _ metric.Exporter = &metricExporter{}
var _ exportmetric.Exporter = &metricExporter{}
type line struct {
Name string `json:"Name"`
@ -52,17 +52,17 @@ type quantile struct {
Value interface{} `json:"Value"`
}
func (e *metricExporter) ExportKindFor(*apimetric.Descriptor, aggregation.Kind) metric.ExportKind {
return metric.PassThroughExporter
func (e *metricExporter) ExportKindFor(*otel.Descriptor, aggregation.Kind) exportmetric.ExportKind {
return exportmetric.PassThroughExporter
}
func (e *metricExporter) Export(_ context.Context, checkpointSet metric.CheckpointSet) error {
func (e *metricExporter) Export(_ context.Context, checkpointSet exportmetric.CheckpointSet) error {
if e.config.DisableMetricExport {
return nil
}
var aggError error
var batch []line
aggError = checkpointSet.ForEach(e, func(record metric.Record) error {
aggError = checkpointSet.ForEach(e, func(record exportmetric.Record) error {
desc := record.Descriptor()
agg := record.Aggregation()
kind := desc.NumberKind()

View File

@ -26,7 +26,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/stdout"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
@ -99,11 +99,11 @@ func TestStdoutTimestamp(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
ctx := context.Background()
desc := metric.NewDescriptor("test.name", metric.ValueObserverInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
aggregatortest.CheckedUpdate(t, lvagg, metric.NewInt64Number(321), &desc)
aggregatortest.CheckedUpdate(t, lvagg, otel.NewInt64Number(321), &desc)
require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
checkpointSet.Add(&desc, ckpt)
@ -138,11 +138,11 @@ func TestStdoutCounterFormat(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
desc := metric.NewDescriptor("test.name", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("test.name", otel.CounterInstrumentKind, otel.Int64NumberKind)
cagg, ckpt := metrictest.Unslice2(sum.New(2))
aggregatortest.CheckedUpdate(fix.t, cagg, metric.NewInt64Number(123), &desc)
aggregatortest.CheckedUpdate(fix.t, cagg, otel.NewInt64Number(123), &desc)
require.NoError(t, cagg.SynchronizedMove(ckpt, &desc))
checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@ -157,10 +157,10 @@ func TestStdoutLastValueFormat(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
desc := metric.NewDescriptor("test.name", metric.ValueObserverInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
aggregatortest.CheckedUpdate(fix.t, lvagg, metric.NewFloat64Number(123.456), &desc)
aggregatortest.CheckedUpdate(fix.t, lvagg, otel.NewFloat64Number(123.456), &desc)
require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@ -175,12 +175,12 @@ func TestStdoutMinMaxSumCount(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
desc := metric.NewDescriptor("test.name", metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
magg, ckpt := metrictest.Unslice2(minmaxsumcount.New(2, &desc))
aggregatortest.CheckedUpdate(fix.t, magg, metric.NewFloat64Number(123.456), &desc)
aggregatortest.CheckedUpdate(fix.t, magg, metric.NewFloat64Number(876.543), &desc)
aggregatortest.CheckedUpdate(fix.t, magg, otel.NewFloat64Number(123.456), &desc)
aggregatortest.CheckedUpdate(fix.t, magg, otel.NewFloat64Number(876.543), &desc)
require.NoError(t, magg.SynchronizedMove(ckpt, &desc))
checkpointSet.Add(&desc, ckpt, label.String("A", "B"), label.String("C", "D"))
@ -195,11 +195,11 @@ func TestStdoutValueRecorderFormat(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
desc := metric.NewDescriptor("test.name", metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
aagg, ckpt := metrictest.Unslice2(array.New(2))
for i := 0; i < 1000; i++ {
aggregatortest.CheckedUpdate(fix.t, aagg, metric.NewFloat64Number(float64(i)+0.5), &desc)
aggregatortest.CheckedUpdate(fix.t, aagg, otel.NewFloat64Number(float64(i)+0.5), &desc)
}
require.NoError(t, aagg.SynchronizedMove(ckpt, &desc))
@ -234,7 +234,7 @@ func TestStdoutValueRecorderFormat(t *testing.T) {
}
func TestStdoutNoData(t *testing.T) {
desc := metric.NewDescriptor("test.name", metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
runTwoAggs := func(agg, ckpt export.Aggregator) {
t.Run(fmt.Sprintf("%T", agg), func(t *testing.T) {
@ -263,7 +263,7 @@ func TestStdoutLastValueNotSet(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(testResource)
desc := metric.NewDescriptor("test.name", metric.ValueObserverInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
@ -314,10 +314,10 @@ func TestStdoutResource(t *testing.T) {
checkpointSet := metrictest.NewCheckpointSet(tc.res)
desc := metric.NewDescriptor("test.name", metric.ValueObserverInstrumentKind, metric.Float64NumberKind)
desc := otel.NewDescriptor("test.name", otel.ValueObserverInstrumentKind, otel.Float64NumberKind)
lvagg, ckpt := metrictest.Unslice2(lastvalue.New(2))
aggregatortest.CheckedUpdate(fix.t, lvagg, metric.NewFloat64Number(123.456), &desc)
aggregatortest.CheckedUpdate(fix.t, lvagg, otel.NewFloat64Number(123.456), &desc)
require.NoError(t, lvagg.SynchronizedMove(ckpt, &desc))
checkpointSet.Add(&desc, ckpt, tc.attrs...)

View File

@ -1,6 +1,6 @@
// Code generated by "stringer -type=InstrumentKind"; DO NOT EDIT.
package metric
package otel
import "strconv"

View File

@ -20,8 +20,8 @@ import (
"fmt"
"sync"
api "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
api "go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
)

View File

@ -12,25 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
import (
"context"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/unit"
)
// The file is organized as follows:
//
// - MeterProvider interface
// - Meter struct
// - RecordBatch
// - BatchObserver
// - Synchronous instrument constructors (2 x int64,float64)
// - Asynchronous instrument constructors (1 x int64,float64)
// - Batch asynchronous constructors (1 x int64,float64)
// - Internals
// MeterProvider supports named Meter instances.
type MeterProvider interface {
// Meter creates an implementation of the Meter interface.
@ -42,8 +32,7 @@ type MeterProvider interface {
Meter(instrumentationName string, opts ...MeterOption) Meter
}
// Meter is the OpenTelemetry metric API, based on a `MeterImpl`
// implementation and the `Meter` library name.
// Meter is the creator of metric instruments.
//
// An uninitialized Meter is a no-op implementation.
type Meter struct {
@ -318,3 +307,270 @@ func (m Meter) newSync(
desc.config.InstrumentationVersion = m.version
return m.impl.NewSyncInstrument(desc)
}
// MeterMust is a wrapper for Meter interfaces that panics when any
// instrument constructor encounters an error.
type MeterMust struct {
meter Meter
}
// BatchObserverMust is a wrapper for BatchObserver that panics when
// any instrument constructor encounters an error.
type BatchObserverMust struct {
batch BatchObserver
}
// Must constructs a MeterMust implementation from a Meter, allowing
// the application to panic when any instrument constructor yields an
// error.
func Must(meter Meter) MeterMust {
return MeterMust{meter: meter}
}
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter {
if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter {
if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter {
if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter {
if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64ValueRecorder calls `Meter.NewInt64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...InstrumentOption) Int64ValueRecorder {
if inst, err := mm.meter.NewInt64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueRecorder calls `Meter.NewFloat64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...InstrumentOption) Float64ValueRecorder {
if inst, err := mm.meter.NewFloat64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64ValueObserver calls `Meter.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := mm.meter.NewInt64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueObserver calls `Meter.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := mm.meter.NewFloat64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64SumObserver calls `Meter.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64SumObserver {
if inst, err := mm.meter.NewInt64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64SumObserver calls `Meter.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64SumObserver {
if inst, err := mm.meter.NewFloat64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownSumObserver calls `Meter.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := mm.meter.NewInt64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownSumObserver calls `Meter.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := mm.meter.NewFloat64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewBatchObserver returns a wrapper around BatchObserver that panics
// when any instrument constructor returns an error.
func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust {
return BatchObserverMust{
batch: mm.meter.NewBatchObserver(callback),
}
}
// NewInt64ValueObserver calls `BatchObserver.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := bm.batch.NewInt64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64ValueObserver calls `BatchObserver.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := bm.batch.NewFloat64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64SumObserver calls `BatchObserver.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...InstrumentOption) Int64SumObserver {
if inst, err := bm.batch.NewInt64SumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64SumObserver calls `BatchObserver.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...InstrumentOption) Float64SumObserver {
if inst, err := bm.batch.NewFloat64SumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewInt64UpDownSumObserver calls `BatchObserver.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := bm.batch.NewInt64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {
return inst
}
}
// NewFloat64UpDownSumObserver calls `BatchObserver.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := bm.batch.NewFloat64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {
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 InstrumentKind
numberKind NumberKind
config InstrumentConfig
}
// NewDescriptor returns a Descriptor with the given contents.
func NewDescriptor(name string, ikind InstrumentKind, nkind NumberKind, opts ...InstrumentOption) Descriptor {
return Descriptor{
name: name,
instrumentKind: ikind,
numberKind: nkind,
config: NewInstrumentConfig(opts...),
}
}
// 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.config.Description
}
// Unit describes the units of the metric instrument. Unitless
// metrics return the empty string.
func (d Descriptor) Unit() unit.Unit {
return d.config.Unit
}
// NumberKind returns whether this instrument is declared over int64,
// float64, or uint64 values.
func (d Descriptor) NumberKind() NumberKind {
return d.numberKind
}
// InstrumentationName returns the name of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationName() string {
return d.config.InstrumentationName
}
// InstrumentationVersion returns the version of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationVersion() string {
return d.config.InstrumentationVersion
}

776
metric_instrument.go Normal file
View File

@ -0,0 +1,776 @@
// 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.
//go:generate stringer -type=InstrumentKind
package otel
import (
"context"
"errors"
"go.opentelemetry.io/otel/label"
)
// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation")
// InstrumentKind describes the kind of instrument.
type InstrumentKind int8
const (
// ValueRecorderInstrumentKind indicates a ValueRecorder instrument.
ValueRecorderInstrumentKind InstrumentKind = iota
// ValueObserverInstrumentKind indicates an ValueObserver instrument.
ValueObserverInstrumentKind
// CounterInstrumentKind indicates a Counter instrument.
CounterInstrumentKind
// UpDownCounterInstrumentKind indicates a UpDownCounter instrument.
UpDownCounterInstrumentKind
// SumObserverInstrumentKind indicates a SumObserver instrument.
SumObserverInstrumentKind
// UpDownSumObserverInstrumentKind indicates a UpDownSumObserver
// instrument.
UpDownSumObserverInstrumentKind
)
// Synchronous returns whether this is a synchronous kind of instrument.
func (k InstrumentKind) Synchronous() bool {
switch k {
case CounterInstrumentKind, UpDownCounterInstrumentKind, ValueRecorderInstrumentKind:
return true
}
return false
}
// Asynchronous returns whether this is an asynchronous kind of instrument.
func (k InstrumentKind) Asynchronous() bool {
return !k.Synchronous()
}
// Adding returns whether this kind of instrument adds its inputs (as opposed to Grouping).
func (k InstrumentKind) Adding() bool {
switch k {
case CounterInstrumentKind, UpDownCounterInstrumentKind, SumObserverInstrumentKind, UpDownSumObserverInstrumentKind:
return true
}
return false
}
// Grouping returns whether this kind of instrument groups its inputs (as opposed to Adding).
func (k InstrumentKind) Grouping() bool {
return !k.Adding()
}
// Monotonic returns whether this kind of instrument exposes a non-decreasing sum.
func (k InstrumentKind) Monotonic() bool {
switch k {
case CounterInstrumentKind, SumObserverInstrumentKind:
return true
}
return false
}
// PrecomputedSum returns whether this kind of instrument receives precomputed sums.
func (k InstrumentKind) PrecomputedSum() bool {
return k.Adding() && k.Asynchronous()
}
// Observation is used for reporting an asynchronous batch of metric
// values. Instances of this type should be created by asynchronous
// instruments (e.g., Int64ValueObserver.Observation()).
type Observation struct {
// number needs to be aligned for 64-bit atomic operations.
number Number
instrument AsyncImpl
}
// Int64ObserverFunc is a type of callback that integral
// observers run.
type Int64ObserverFunc func(context.Context, Int64ObserverResult)
// Float64ObserverFunc is a type of callback that floating point
// observers run.
type Float64ObserverFunc func(context.Context, Float64ObserverResult)
// BatchObserverFunc is a callback argument for use with any
// Observer instrument that will be reported as a batch of
// observations.
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
function func([]label.KeyValue, ...Observation)
}
// Float64ObserverResult is passed to an observer callback to capture
// observations for one asynchronous floating point metric instrument.
type Float64ObserverResult struct {
instrument AsyncImpl
function func([]label.KeyValue, ...Observation)
}
// BatchObserverResult is passed to a batch observer callback to
// capture observations for multiple asynchronous instruments.
type BatchObserverResult struct {
function func([]label.KeyValue, ...Observation)
}
// Observe captures a single integer value from the associated
// instrument callback, with the given labels.
func (ir Int64ObserverResult) Observe(value int64, labels ...label.KeyValue) {
ir.function(labels, Observation{
instrument: 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 ...label.KeyValue) {
fr.function(labels, Observation{
instrument: fr.instrument,
number: NewFloat64Number(value),
})
}
// Observe captures a multiple observations from the associated batch
// instrument callback, with the given labels.
func (br BatchObserverResult) Observe(labels []label.KeyValue, obs ...Observation) {
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([]label.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([]label.KeyValue, ...Observation))
AsyncRunner
}
var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil)
var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil)
var _ AsyncBatchRunner = (*BatchObserverFunc)(nil)
// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner {
return &c
}
// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner {
return &c
}
// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner {
return &c
}
// AnyRunner implements AsyncRunner.
func (*Int64ObserverFunc) AnyRunner() {}
// AnyRunner implements AsyncRunner.
func (*Float64ObserverFunc) AnyRunner() {}
// AnyRunner implements AsyncRunner.
func (*BatchObserverFunc) AnyRunner() {}
// Run implements AsyncSingleRunner.
func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
(*i)(ctx, Int64ObserverResult{
instrument: impl,
function: function,
})
}
// Run implements AsyncSingleRunner.
func (f *Float64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
(*f)(ctx, Float64ObserverResult{
instrument: impl,
function: function,
})
}
// Run implements AsyncBatchRunner.
func (b *BatchObserverFunc) Run(ctx context.Context, function func([]label.KeyValue, ...Observation)) {
(*b)(ctx, BatchObserverResult{
function: function,
})
}
// wrapInt64ValueObserverInstrument converts an AsyncImpl into Int64ValueObserver.
func wrapInt64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Int64ValueObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64ValueObserver{asyncInstrument: common}, err
}
// wrapFloat64ValueObserverInstrument converts an AsyncImpl into Float64ValueObserver.
func wrapFloat64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Float64ValueObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64ValueObserver{asyncInstrument: common}, err
}
// wrapInt64SumObserverInstrument converts an AsyncImpl into Int64SumObserver.
func wrapInt64SumObserverInstrument(asyncInst AsyncImpl, err error) (Int64SumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64SumObserver{asyncInstrument: common}, err
}
// wrapFloat64SumObserverInstrument converts an AsyncImpl into Float64SumObserver.
func wrapFloat64SumObserverInstrument(asyncInst AsyncImpl, err error) (Float64SumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64SumObserver{asyncInstrument: common}, err
}
// wrapInt64UpDownSumObserverInstrument converts an AsyncImpl into Int64UpDownSumObserver.
func wrapInt64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Int64UpDownSumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Int64UpDownSumObserver{asyncInstrument: common}, err
}
// wrapFloat64UpDownSumObserverInstrument converts an AsyncImpl into Float64UpDownSumObserver.
func wrapFloat64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Float64UpDownSumObserver, error) {
common, err := checkNewAsync(asyncInst, err)
return Float64UpDownSumObserver{asyncInstrument: common}, err
}
// BatchObserver represents an Observer callback that can report
// observations for multiple instruments.
type BatchObserver struct {
meter Meter
runner AsyncBatchRunner
}
// Int64ValueObserver is a metric that captures a set of int64 values at a
// point in time.
type Int64ValueObserver struct {
asyncInstrument
}
// Float64ValueObserver is a metric that captures a set of float64 values
// at a point in time.
type Float64ValueObserver struct {
asyncInstrument
}
// Int64SumObserver is a metric that captures a precomputed sum of
// int64 values at a point in time.
type Int64SumObserver struct {
asyncInstrument
}
// Float64SumObserver is a metric that captures a precomputed sum of
// float64 values at a point in time.
type Float64SumObserver struct {
asyncInstrument
}
// Int64UpDownSumObserver is a metric that captures a precomputed sum of
// int64 values at a point in time.
type Int64UpDownSumObserver struct {
asyncInstrument
}
// Float64UpDownSumObserver is a metric that captures a precomputed sum of
// float64 values at a point in time.
type Float64UpDownSumObserver struct {
asyncInstrument
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64ValueObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64ValueObserver) Observation(v float64) Observation {
return Observation{
number: NewFloat64Number(v),
instrument: f.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64SumObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64SumObserver) Observation(v float64) Observation {
return Observation{
number: NewFloat64Number(v),
instrument: f.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (i Int64UpDownSumObserver) Observation(v int64) Observation {
return Observation{
number: NewInt64Number(v),
instrument: i.instrument,
}
}
// Observation returns an Observation, a BatchObserverFunc
// argument, for an asynchronous integer instrument.
// This returns an implementation-level object for use by the SDK,
// users should not refer to this.
func (f Float64UpDownSumObserver) Observation(v float64) Observation {
return Observation{
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
instrument SyncImpl
}
// syncInstrument contains a SyncImpl.
type syncInstrument struct {
instrument SyncImpl
}
// syncBoundInstrument contains a BoundSyncImpl.
type syncBoundInstrument struct {
boundInstrument 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 {
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 {
return m.number
}
// AsyncImpl implements AsyncImpl.
func (a asyncInstrument) AsyncImpl() AsyncImpl {
return a.instrument
}
// SyncImpl returns the implementation object for synchronous instruments.
func (s syncInstrument) SyncImpl() SyncImpl {
return s.instrument
}
func (s syncInstrument) bind(labels []label.KeyValue) syncBoundInstrument {
return newSyncBoundInstrument(s.instrument.Bind(labels))
}
func (s syncInstrument) float64Measurement(value float64) Measurement {
return newMeasurement(s.instrument, NewFloat64Number(value))
}
func (s syncInstrument) int64Measurement(value int64) Measurement {
return newMeasurement(s.instrument, NewInt64Number(value))
}
func (s syncInstrument) directRecord(ctx context.Context, number Number, labels []label.KeyValue) {
s.instrument.RecordOne(ctx, number, labels)
}
func (h syncBoundInstrument) directRecord(ctx context.Context, number Number) {
h.boundInstrument.RecordOne(ctx, number)
}
// Unbind calls SyncImpl.Unbind.
func (h syncBoundInstrument) Unbind() {
h.boundInstrument.Unbind()
}
// checkNewAsync receives an AsyncImpl and potential
// error, and returns the same types, checking for and ensuring that
// the returned interface is not nil.
func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) {
if instrument == nil {
if err == nil {
err = ErrSDKReturnedNilImpl
}
instrument = NoopAsync{}
}
return asyncInstrument{
instrument: instrument,
}, err
}
// 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) {
if instrument == nil {
if err == nil {
err = ErrSDKReturnedNilImpl
}
// Note: an alternate behavior would be to synthesize a new name
// or group all duplicately-named instruments of a certain type
// together and use a tag for the original name, e.g.,
// name = 'invalid.counter.int64'
// label = 'original-name=duplicate-counter-name'
instrument = NoopSync{}
}
return syncInstrument{
instrument: instrument,
}, err
}
func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument {
return syncBoundInstrument{
boundInstrument: boundInstrument,
}
}
func newMeasurement(instrument SyncImpl, number Number) Measurement {
return Measurement{
instrument: instrument,
number: number,
}
}
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
func wrapInt64CounterInstrument(syncInst 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) {
common, err := checkNewSync(syncInst, err)
return Float64Counter{syncInstrument: common}, err
}
// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter.
func wrapInt64UpDownCounterInstrument(syncInst 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) {
common, err := checkNewSync(syncInst, err)
return Float64UpDownCounter{syncInstrument: common}, err
}
// wrapInt64ValueRecorderInstrument converts a SyncImpl into Int64ValueRecorder.
func wrapInt64ValueRecorderInstrument(syncInst SyncImpl, err error) (Int64ValueRecorder, error) {
common, err := checkNewSync(syncInst, err)
return Int64ValueRecorder{syncInstrument: common}, err
}
// wrapFloat64ValueRecorderInstrument converts a SyncImpl into Float64ValueRecorder.
func wrapFloat64ValueRecorderInstrument(syncInst SyncImpl, err error) (Float64ValueRecorder, error) {
common, err := checkNewSync(syncInst, err)
return Float64ValueRecorder{syncInstrument: common}, err
}
// Float64Counter is a metric that accumulates float64 values.
type Float64Counter struct {
syncInstrument
}
// Int64Counter is a metric that accumulates int64 values.
type Int64Counter struct {
syncInstrument
}
// BoundFloat64Counter is a bound instrument for Float64Counter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64Counter struct {
syncBoundInstrument
}
// BoundInt64Counter is a boundInstrument for Int64Counter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64Counter struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64Counter) Bind(labels ...label.KeyValue) (h BoundFloat64Counter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64Counter) Bind(labels ...label.KeyValue) (h BoundInt64Counter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64Counter) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64Counter) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Float64Counter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Int64Counter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}
// Float64UpDownCounter is a metric instrument that sums floating
// point values.
type Float64UpDownCounter struct {
syncInstrument
}
// Int64UpDownCounter is a metric instrument that sums integer values.
type Int64UpDownCounter struct {
syncInstrument
}
// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64UpDownCounter struct {
syncBoundInstrument
}
// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64UpDownCounter struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64UpDownCounter) Bind(labels ...label.KeyValue) (h BoundFloat64UpDownCounter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this counter. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64UpDownCounter) Bind(labels ...label.KeyValue) (h BoundInt64UpDownCounter) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64UpDownCounter) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Float64UpDownCounter) Add(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Add adds the value to the counter's sum. The labels should contain
// the keys and values to be associated with this value.
func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Add adds the value to the counter's sum using the labels
// previously bound to this counter via Bind()
func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}
// Float64ValueRecorder is a metric that records float64 values.
type Float64ValueRecorder struct {
syncInstrument
}
// Int64ValueRecorder is a metric that records int64 values.
type Int64ValueRecorder struct {
syncInstrument
}
// BoundFloat64ValueRecorder is a bound instrument for Float64ValueRecorder.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundFloat64ValueRecorder struct {
syncBoundInstrument
}
// BoundInt64ValueRecorder is a bound instrument for Int64ValueRecorder.
//
// It inherits the Unbind function from syncBoundInstrument.
type BoundInt64ValueRecorder struct {
syncBoundInstrument
}
// Bind creates a bound instrument for this ValueRecorder. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Float64ValueRecorder) Bind(labels ...label.KeyValue) (h BoundFloat64ValueRecorder) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Bind creates a bound instrument for this ValueRecorder. The labels are
// associated with values recorded via subsequent calls to Record.
func (c Int64ValueRecorder) Bind(labels ...label.KeyValue) (h BoundInt64ValueRecorder) {
h.syncBoundInstrument = c.bind(labels)
return
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Float64ValueRecorder) Measurement(value float64) Measurement {
return c.float64Measurement(value)
}
// Measurement creates a Measurement object to use with batch
// recording.
func (c Int64ValueRecorder) Measurement(value int64) Measurement {
return c.int64Measurement(value)
}
// Record adds a new value to the list of ValueRecorder's records. The
// labels should contain the keys and values to be associated with
// this value.
func (c Float64ValueRecorder) Record(ctx context.Context, value float64, labels ...label.KeyValue) {
c.directRecord(ctx, NewFloat64Number(value), labels)
}
// Record adds a new value to the ValueRecorder's distribution. The
// labels should contain the keys and values to be associated with
// this value.
func (c Int64ValueRecorder) Record(ctx context.Context, value int64, labels ...label.KeyValue) {
c.directRecord(ctx, NewInt64Number(value), labels)
}
// Record adds a new value to the ValueRecorder's distribution using the labels
// previously bound to the ValueRecorder via Bind().
func (b BoundFloat64ValueRecorder) Record(ctx context.Context, value float64) {
b.directRecord(ctx, NewFloat64Number(value))
}
// Record adds a new value to the ValueRecorder's distribution using the labels
// previously bound to the ValueRecorder via Bind().
func (b BoundInt64ValueRecorder) Record(ctx context.Context, value int64) {
b.directRecord(ctx, NewInt64Number(value))
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
import (
"context"

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
import (
"context"

View File

@ -12,17 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric_test
package otel_test
import (
"context"
"errors"
"testing"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/metrictest"
mockTest "go.opentelemetry.io/otel/api/metric/metrictest"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/oteltest"
"go.opentelemetry.io/otel/unit"
"github.com/google/go-cmp/cmp"
@ -30,16 +29,103 @@ import (
"github.com/stretchr/testify/require"
)
var Must = metric.Must
var Must = otel.Must
func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue, mock *mockTest.MeterImpl, nkind metric.NumberKind, mkind metric.InstrumentKind, instrument metric.InstrumentImpl, expected ...float64) {
var (
syncKinds = []otel.InstrumentKind{
otel.ValueRecorderInstrumentKind,
otel.CounterInstrumentKind,
otel.UpDownCounterInstrumentKind,
}
asyncKinds = []otel.InstrumentKind{
otel.ValueObserverInstrumentKind,
otel.SumObserverInstrumentKind,
otel.UpDownSumObserverInstrumentKind,
}
addingKinds = []otel.InstrumentKind{
otel.CounterInstrumentKind,
otel.UpDownCounterInstrumentKind,
otel.SumObserverInstrumentKind,
otel.UpDownSumObserverInstrumentKind,
}
groupingKinds = []otel.InstrumentKind{
otel.ValueRecorderInstrumentKind,
otel.ValueObserverInstrumentKind,
}
monotonicKinds = []otel.InstrumentKind{
otel.CounterInstrumentKind,
otel.SumObserverInstrumentKind,
}
nonMonotonicKinds = []otel.InstrumentKind{
otel.UpDownCounterInstrumentKind,
otel.UpDownSumObserverInstrumentKind,
otel.ValueRecorderInstrumentKind,
otel.ValueObserverInstrumentKind,
}
precomputedSumKinds = []otel.InstrumentKind{
otel.SumObserverInstrumentKind,
otel.UpDownSumObserverInstrumentKind,
}
nonPrecomputedSumKinds = []otel.InstrumentKind{
otel.CounterInstrumentKind,
otel.UpDownCounterInstrumentKind,
otel.ValueRecorderInstrumentKind,
otel.ValueObserverInstrumentKind,
}
)
func TestSynchronous(t *testing.T) {
for _, k := range syncKinds {
require.True(t, k.Synchronous())
require.False(t, k.Asynchronous())
}
for _, k := range asyncKinds {
require.True(t, k.Asynchronous())
require.False(t, k.Synchronous())
}
}
func TestGrouping(t *testing.T) {
for _, k := range groupingKinds {
require.True(t, k.Grouping())
require.False(t, k.Adding())
}
for _, k := range addingKinds {
require.True(t, k.Adding())
require.False(t, k.Grouping())
}
}
func TestMonotonic(t *testing.T) {
for _, k := range monotonicKinds {
require.True(t, k.Monotonic())
}
for _, k := range nonMonotonicKinds {
require.False(t, k.Monotonic())
}
}
func TestPrecomputedSum(t *testing.T) {
for _, k := range precomputedSumKinds {
require.True(t, k.PrecomputedSum())
}
for _, k := range nonPrecomputedSumKinds {
require.False(t, k.PrecomputedSum())
}
}
func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind otel.NumberKind, mkind otel.InstrumentKind, instrument otel.InstrumentImpl, expected ...float64) {
t.Helper()
batchesCount := len(mock.MeasurementBatches)
if len(mock.MeasurementBatches) != len(expected) {
t.Errorf("Expected %d recorded measurement batches, got %d", batchesCount, len(mock.MeasurementBatches))
}
recorded := metrictest.AsStructs(mock.MeasurementBatches)
recorded := oteltest.AsStructs(mock.MeasurementBatches)
for i, batch := range mock.MeasurementBatches {
if len(batch.Measurements) != 1 {
@ -49,11 +135,11 @@ func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue
measurement := batch.Measurements[0]
descriptor := measurement.Instrument.Descriptor()
expected := metrictest.Measured{
expected := oteltest.Measured{
Name: descriptor.Name(),
InstrumentationName: descriptor.InstrumentationName(),
Labels: metrictest.LabelsToMap(labels...),
Number: metrictest.ResolveNumberByKind(t, nkind, expected[i]),
Labels: oteltest.LabelsToMap(labels...),
Number: oteltest.ResolveNumberByKind(t, nkind, expected[i]),
}
require.Equal(t, expected, recorded[i])
}
@ -62,7 +148,7 @@ func checkSyncBatches(ctx context.Context, t *testing.T, labels []label.KeyValue
func TestOptions(t *testing.T) {
type testcase struct {
name string
opts []metric.InstrumentOption
opts []otel.InstrumentOption
desc string
unit unit.Unit
}
@ -75,34 +161,34 @@ func TestOptions(t *testing.T) {
},
{
name: "description",
opts: []metric.InstrumentOption{
metric.WithDescription("stuff"),
opts: []otel.InstrumentOption{
otel.WithDescription("stuff"),
},
desc: "stuff",
unit: "",
},
{
name: "description override",
opts: []metric.InstrumentOption{
metric.WithDescription("stuff"),
metric.WithDescription("things"),
opts: []otel.InstrumentOption{
otel.WithDescription("stuff"),
otel.WithDescription("things"),
},
desc: "things",
unit: "",
},
{
name: "unit",
opts: []metric.InstrumentOption{
metric.WithUnit("s"),
opts: []otel.InstrumentOption{
otel.WithUnit("s"),
},
desc: "",
unit: "s",
},
{
name: "unit override",
opts: []metric.InstrumentOption{
metric.WithUnit("s"),
metric.WithUnit("h"),
opts: []otel.InstrumentOption{
otel.WithUnit("s"),
otel.WithUnit("h"),
},
desc: "",
unit: "h",
@ -110,7 +196,7 @@ func TestOptions(t *testing.T) {
}
for idx, tt := range testcases {
t.Logf("Testing counter case %s (%d)", tt.name, idx)
if diff := cmp.Diff(metric.NewInstrumentConfig(tt.opts...), metric.InstrumentConfig{
if diff := cmp.Diff(otel.NewInstrumentConfig(tt.opts...), otel.InstrumentConfig{
Description: tt.desc,
Unit: tt.unit,
}); diff != "" {
@ -123,7 +209,7 @@ func TestCounter(t *testing.T) {
// N.B. the API does not check for negative
// values, that's the SDK's responsibility.
t.Run("float64 counter", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
c := Must(meter).NewFloat64Counter("test.counter.float")
ctx := context.Background()
labels := []label.KeyValue{label.String("A", "B")}
@ -131,12 +217,12 @@ func TestCounter(t *testing.T) {
boundInstrument := c.Bind(labels...)
boundInstrument.Add(ctx, -742)
meter.RecordBatch(ctx, labels, c.Measurement(42))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Float64NumberKind, metric.CounterInstrumentKind, c.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.CounterInstrumentKind, c.SyncImpl(),
1994.1, -742, 42,
)
})
t.Run("int64 counter", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
c := Must(meter).NewInt64Counter("test.counter.int")
ctx := context.Background()
labels := []label.KeyValue{label.String("A", "B"), label.String("C", "D")}
@ -144,13 +230,13 @@ func TestCounter(t *testing.T) {
boundInstrument := c.Bind(labels...)
boundInstrument.Add(ctx, 4200)
meter.RecordBatch(ctx, labels, c.Measurement(420000))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Int64NumberKind, metric.CounterInstrumentKind, c.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.CounterInstrumentKind, c.SyncImpl(),
42, 4200, 420000,
)
})
t.Run("int64 updowncounter", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
c := Must(meter).NewInt64UpDownCounter("test.updowncounter.int")
ctx := context.Background()
labels := []label.KeyValue{label.String("A", "B"), label.String("C", "D")}
@ -158,12 +244,12 @@ func TestCounter(t *testing.T) {
boundInstrument := c.Bind(labels...)
boundInstrument.Add(ctx, -100)
meter.RecordBatch(ctx, labels, c.Measurement(42))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Int64NumberKind, metric.UpDownCounterInstrumentKind, c.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
100, -100, 42,
)
})
t.Run("float64 updowncounter", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
c := Must(meter).NewFloat64UpDownCounter("test.updowncounter.float")
ctx := context.Background()
labels := []label.KeyValue{label.String("A", "B"), label.String("C", "D")}
@ -171,7 +257,7 @@ func TestCounter(t *testing.T) {
boundInstrument := c.Bind(labels...)
boundInstrument.Add(ctx, -76)
meter.RecordBatch(ctx, labels, c.Measurement(-100.1))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Float64NumberKind, metric.UpDownCounterInstrumentKind, c.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.UpDownCounterInstrumentKind, c.SyncImpl(),
100.1, -76, -100.1,
)
})
@ -179,7 +265,7 @@ func TestCounter(t *testing.T) {
func TestValueRecorder(t *testing.T) {
t.Run("float64 valuerecorder", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
m := Must(meter).NewFloat64ValueRecorder("test.valuerecorder.float")
ctx := context.Background()
labels := []label.KeyValue{}
@ -187,12 +273,12 @@ func TestValueRecorder(t *testing.T) {
boundInstrument := m.Bind(labels...)
boundInstrument.Record(ctx, 0)
meter.RecordBatch(ctx, labels, m.Measurement(-100.5))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Float64NumberKind, metric.ValueRecorderInstrumentKind, m.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Float64NumberKind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
42, 0, -100.5,
)
})
t.Run("int64 valuerecorder", func(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
m := Must(meter).NewInt64ValueRecorder("test.valuerecorder.int")
ctx := context.Background()
labels := []label.KeyValue{label.Int("I", 1)}
@ -200,7 +286,7 @@ func TestValueRecorder(t *testing.T) {
boundInstrument := m.Bind(labels...)
boundInstrument.Record(ctx, 80)
meter.RecordBatch(ctx, labels, m.Measurement(0))
checkSyncBatches(ctx, t, labels, mockSDK, metric.Int64NumberKind, metric.ValueRecorderInstrumentKind, m.SyncImpl(),
checkSyncBatches(ctx, t, labels, mockSDK, otel.Int64NumberKind, otel.ValueRecorderInstrumentKind, m.SyncImpl(),
173, 80, 0,
)
})
@ -209,77 +295,77 @@ func TestValueRecorder(t *testing.T) {
func TestObserverInstruments(t *testing.T) {
t.Run("float valueobserver", func(t *testing.T) {
labels := []label.KeyValue{label.String("O", "P")}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewFloat64ValueObserver("test.valueobserver.float", func(_ context.Context, result metric.Float64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewFloat64ValueObserver("test.valueobserver.float", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(42.1, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Float64NumberKind, metric.ValueObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
42.1,
)
})
t.Run("int valueobserver", func(t *testing.T) {
labels := []label.KeyValue{}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewInt64ValueObserver("test.observer.int", func(_ context.Context, result metric.Int64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewInt64ValueObserver("test.observer.int", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(-142, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Int64NumberKind, metric.ValueObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.ValueObserverInstrumentKind, o.AsyncImpl(),
-142,
)
})
t.Run("float sumobserver", func(t *testing.T) {
labels := []label.KeyValue{label.String("O", "P")}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewFloat64SumObserver("test.sumobserver.float", func(_ context.Context, result metric.Float64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewFloat64SumObserver("test.sumobserver.float", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(42.1, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Float64NumberKind, metric.SumObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
42.1,
)
})
t.Run("int sumobserver", func(t *testing.T) {
labels := []label.KeyValue{}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewInt64SumObserver("test.observer.int", func(_ context.Context, result metric.Int64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewInt64SumObserver("test.observer.int", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(-142, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Int64NumberKind, metric.SumObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.SumObserverInstrumentKind, o.AsyncImpl(),
-142,
)
})
t.Run("float updownsumobserver", func(t *testing.T) {
labels := []label.KeyValue{label.String("O", "P")}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewFloat64UpDownSumObserver("test.updownsumobserver.float", func(_ context.Context, result metric.Float64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewFloat64UpDownSumObserver("test.updownsumobserver.float", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(42.1, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Float64NumberKind, metric.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Float64NumberKind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
42.1,
)
})
t.Run("int updownsumobserver", func(t *testing.T) {
labels := []label.KeyValue{}
mockSDK, meter := mockTest.NewMeter()
o := Must(meter).NewInt64UpDownSumObserver("test.observer.int", func(_ context.Context, result metric.Int64ObserverResult) {
mockSDK, meter := oteltest.NewMeter()
o := Must(meter).NewInt64UpDownSumObserver("test.observer.int", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(-142, labels...)
})
mockSDK.RunAsyncInstruments()
checkObserverBatch(t, labels, mockSDK, metric.Int64NumberKind, metric.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
checkObserverBatch(t, labels, mockSDK, otel.Int64NumberKind, otel.UpDownSumObserverInstrumentKind, o.AsyncImpl(),
-142,
)
})
}
func TestBatchObserverInstruments(t *testing.T) {
mockSDK, meter := mockTest.NewMeter()
mockSDK, meter := oteltest.NewMeter()
var obs1 metric.Int64ValueObserver
var obs2 metric.Float64ValueObserver
var obs1 otel.Int64ValueObserver
var obs2 otel.Float64ValueObserver
labels := []label.KeyValue{
label.String("A", "B"),
@ -287,7 +373,7 @@ func TestBatchObserverInstruments(t *testing.T) {
}
cb := Must(meter).NewBatchObserver(
func(_ context.Context, result metric.BatchObserverResult) {
func(_ context.Context, result otel.BatchObserverResult) {
result.Observe(labels,
obs1.Observation(42),
obs2.Observation(42.0),
@ -301,8 +387,8 @@ func TestBatchObserverInstruments(t *testing.T) {
require.Len(t, mockSDK.MeasurementBatches, 1)
impl1 := obs1.AsyncImpl().Implementation().(*mockTest.Async)
impl2 := obs2.AsyncImpl().Implementation().(*mockTest.Async)
impl1 := obs1.AsyncImpl().Implementation().(*oteltest.Async)
impl2 := obs2.AsyncImpl().Implementation().(*oteltest.Async)
require.NotNil(t, impl1)
require.NotNil(t, impl2)
@ -312,21 +398,21 @@ func TestBatchObserverInstruments(t *testing.T) {
require.Len(t, got.Measurements, 2)
m1 := got.Measurements[0]
require.Equal(t, impl1, m1.Instrument.Implementation().(*mockTest.Async))
require.Equal(t, 0, m1.Number.CompareNumber(metric.Int64NumberKind, mockTest.ResolveNumberByKind(t, metric.Int64NumberKind, 42)))
require.Equal(t, impl1, m1.Instrument.Implementation().(*oteltest.Async))
require.Equal(t, 0, m1.Number.CompareNumber(otel.Int64NumberKind, oteltest.ResolveNumberByKind(t, otel.Int64NumberKind, 42)))
m2 := got.Measurements[1]
require.Equal(t, impl2, m2.Instrument.Implementation().(*mockTest.Async))
require.Equal(t, 0, m2.Number.CompareNumber(metric.Float64NumberKind, mockTest.ResolveNumberByKind(t, metric.Float64NumberKind, 42)))
require.Equal(t, impl2, m2.Instrument.Implementation().(*oteltest.Async))
require.Equal(t, 0, m2.Number.CompareNumber(otel.Float64NumberKind, oteltest.ResolveNumberByKind(t, otel.Float64NumberKind, 42)))
}
func checkObserverBatch(t *testing.T, labels []label.KeyValue, mock *mockTest.MeterImpl, nkind metric.NumberKind, mkind metric.InstrumentKind, observer metric.AsyncImpl, expected float64) {
func checkObserverBatch(t *testing.T, labels []label.KeyValue, mock *oteltest.MeterImpl, nkind otel.NumberKind, mkind otel.InstrumentKind, observer otel.AsyncImpl, expected float64) {
t.Helper()
assert.Len(t, mock.MeasurementBatches, 1)
if len(mock.MeasurementBatches) < 1 {
return
}
o := observer.Implementation().(*mockTest.Async)
o := observer.Implementation().(*oteltest.Async)
if !assert.NotNil(t, o) {
return
}
@ -338,37 +424,37 @@ func checkObserverBatch(t *testing.T, labels []label.KeyValue, mock *mockTest.Me
}
measurement := got.Measurements[0]
require.Equal(t, mkind, measurement.Instrument.Descriptor().InstrumentKind())
assert.Equal(t, o, measurement.Instrument.Implementation().(*mockTest.Async))
ft := mockTest.ResolveNumberByKind(t, nkind, expected)
assert.Equal(t, o, measurement.Instrument.Implementation().(*oteltest.Async))
ft := oteltest.ResolveNumberByKind(t, nkind, expected)
assert.Equal(t, 0, measurement.Number.CompareNumber(nkind, ft))
}
type testWrappedMeter struct {
}
var _ metric.MeterImpl = testWrappedMeter{}
var _ otel.MeterImpl = testWrappedMeter{}
func (testWrappedMeter) RecordBatch(context.Context, []label.KeyValue, ...metric.Measurement) {
func (testWrappedMeter) RecordBatch(context.Context, []label.KeyValue, ...otel.Measurement) {
}
func (testWrappedMeter) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) {
func (testWrappedMeter) NewSyncInstrument(_ otel.Descriptor) (otel.SyncImpl, error) {
return nil, nil
}
func (testWrappedMeter) NewAsyncInstrument(_ metric.Descriptor, _ metric.AsyncRunner) (metric.AsyncImpl, error) {
func (testWrappedMeter) NewAsyncInstrument(_ otel.Descriptor, _ otel.AsyncRunner) (otel.AsyncImpl, error) {
return nil, errors.New("Test wrap error")
}
func TestWrappedInstrumentError(t *testing.T) {
impl := &testWrappedMeter{}
meter := metric.WrapMeterImpl(impl, "test")
meter := otel.WrapMeterImpl(impl, "test")
valuerecorder, err := meter.NewInt64ValueRecorder("test.valuerecorder")
require.Equal(t, err, metric.ErrSDKReturnedNilImpl)
require.Equal(t, err, otel.ErrSDKReturnedNilImpl)
require.NotNil(t, valuerecorder.SyncImpl())
observer, err := meter.NewInt64ValueObserver("test.observer", func(_ context.Context, result metric.Int64ObserverResult) {})
observer, err := meter.NewInt64ValueObserver("test.observer", func(_ context.Context, result otel.Int64ObserverResult) {})
require.NotNil(t, err)
require.NotNil(t, observer.AsyncImpl())
@ -376,10 +462,10 @@ func TestWrappedInstrumentError(t *testing.T) {
func TestNilCallbackObserverNoop(t *testing.T) {
// Tests that a nil callback yields a no-op observer without error.
_, meter := mockTest.NewMeter()
_, meter := oteltest.NewMeter()
observer := Must(meter).NewInt64ValueObserver("test.observer", nil)
_, ok := observer.AsyncImpl().(metric.NoopAsync)
_, ok := observer.AsyncImpl().(otel.NoopAsync)
require.True(t, ok)
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
//go:generate stringer -type=NumberKind

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metric
package otel
import (
"math"

View File

@ -1,6 +1,6 @@
// Code generated by "stringer -type=NumberKind"; DO NOT EDIT.
package metric
package otel
import "strconv"

View File

@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metrictest
package oteltest
import (
"os"
"testing"
"unsafe"
ottest "go.opentelemetry.io/otel/internal/testing"
internaltest "go.opentelemetry.io/otel/internal/testing"
)
// Ensure struct alignment prior to running tests.
// TestMain ensures struct alignment prior to running tests.
func TestMain(m *testing.M) {
fields := []ottest.FieldOffset{
fields := []internaltest.FieldOffset{
{
Name: "Batch.Measurments",
Offset: unsafe.Offsetof(Batch{}.Measurements),
@ -33,8 +33,12 @@ func TestMain(m *testing.M) {
Name: "Measurement.Number",
Offset: unsafe.Offsetof(Measurement{}.Number),
},
{
Name: "MockTracer.StartSpanID",
Offset: unsafe.Offsetof(MockTracer{}.StartSpanID),
},
}
if !ottest.Aligned8Byte(fields, os.Stderr) {
if !internaltest.Aligned8Byte(fields, os.Stderr) {
os.Exit(1)
}

View File

@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package metrictest
package oteltest
import (
"context"
"sync"
"testing"
"go.opentelemetry.io/otel/api/metric"
apimetric "go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel"
apimetric "go.opentelemetry.io/otel"
internalmetric "go.opentelemetry.io/otel/internal/metric"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/registry"
)
type (
@ -126,7 +127,7 @@ func NewMeter() (*MeterImpl, apimetric.Meter) {
return impl, p.Meter("mock")
}
func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (apimetric.SyncImpl, error) {
func (m *MeterImpl) NewSyncInstrument(descriptor otel.Descriptor) (apimetric.SyncImpl, error) {
m.lock.Lock()
defer m.lock.Unlock()
@ -138,7 +139,7 @@ func (m *MeterImpl) NewSyncInstrument(descriptor metric.Descriptor) (apimetric.S
}, nil
}
func (m *MeterImpl) NewAsyncInstrument(descriptor metric.Descriptor, runner metric.AsyncRunner) (apimetric.AsyncImpl, error) {
func (m *MeterImpl) NewAsyncInstrument(descriptor otel.Descriptor, runner otel.AsyncRunner) (apimetric.AsyncImpl, error) {
m.lock.Lock()
defer m.lock.Unlock()
@ -165,7 +166,7 @@ func (m *MeterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, me
m.collect(ctx, labels, mm)
}
func (m *MeterImpl) CollectAsync(labels []label.KeyValue, obs ...metric.Observation) {
func (m *MeterImpl) CollectAsync(labels []label.KeyValue, obs ...otel.Observation) {
mm := make([]Measurement, len(obs))
for i := 0; i < len(obs); i++ {
o := obs[i]
@ -191,3 +192,51 @@ func (m *MeterImpl) collect(ctx context.Context, labels []label.KeyValue, measur
func (m *MeterImpl) RunAsyncInstruments() {
m.asyncInstruments.Run(context.Background(), m)
}
// Measured is the helper struct which provides flat representation of recorded measurements
// to simplify testing
type Measured struct {
Name string
InstrumentationName string
InstrumentationVersion string
Labels map[label.Key]label.Value
Number otel.Number
}
// LabelsToMap converts label set to keyValue map, to be easily used in tests
func LabelsToMap(kvs ...label.KeyValue) map[label.Key]label.Value {
m := map[label.Key]label.Value{}
for _, label := range kvs {
m[label.Key] = label.Value
}
return m
}
// AsStructs converts recorded batches to array of flat, readable Measured helper structures
func AsStructs(batches []Batch) []Measured {
var r []Measured
for _, batch := range batches {
for _, m := range batch.Measurements {
r = append(r, Measured{
Name: m.Instrument.Descriptor().Name(),
InstrumentationName: m.Instrument.Descriptor().InstrumentationName(),
InstrumentationVersion: m.Instrument.Descriptor().InstrumentationVersion(),
Labels: LabelsToMap(batch.Labels...),
Number: m.Number,
})
}
}
return r
}
// ResolveNumberByKind takes defined metric descriptor creates a concrete typed metric number
func ResolveNumberByKind(t *testing.T, kind otel.NumberKind, value float64) otel.Number {
t.Helper()
switch kind {
case otel.Int64NumberKind:
return otel.NewInt64Number(int64(value))
case otel.Float64NumberKind:
return otel.NewFloat64Number(value)
}
panic("invalid number kind")
}

View File

@ -1,39 +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 oteltest_test
import (
"os"
"testing"
"unsafe"
ottest "go.opentelemetry.io/otel/internal/testing"
"go.opentelemetry.io/otel/oteltest"
)
// Ensure struct alignment prior to running tests.
func TestMain(m *testing.M) {
fields := []ottest.FieldOffset{
{
Name: "MockTracer.StartSpanID",
Offset: unsafe.Offsetof(oteltest.MockTracer{}.StartSpanID),
},
}
if !ottest.Aligned8Byte(fields, os.Stderr) {
os.Exit(1)
}
os.Exit(m.Run())
}

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package registry // import "go.opentelemetry.io/otel/api/metric/registry"
package registry // import "go.opentelemetry.io/otel/registry"
import (
"context"
"fmt"
"sync"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
)
// MeterProvider is a standard MeterProvider for wrapping `MeterImpl`
type MeterProvider struct {
impl metric.MeterImpl
impl otel.MeterImpl
}
var _ metric.MeterProvider = (*MeterProvider)(nil)
var _ otel.MeterProvider = (*MeterProvider)(nil)
// uniqueInstrumentMeterImpl implements the metric.MeterImpl interface, adding
// uniqueInstrumentMeterImpl implements the otel.MeterImpl interface, adding
// uniqueness checking for instrument descriptors. Use NewUniqueInstrumentMeter
// to wrap an implementation with uniqueness checking.
type uniqueInstrumentMeterImpl struct {
lock sync.Mutex
impl metric.MeterImpl
state map[key]metric.InstrumentImpl
impl otel.MeterImpl
state map[key]otel.InstrumentImpl
}
var _ metric.MeterImpl = (*uniqueInstrumentMeterImpl)(nil)
var _ otel.MeterImpl = (*uniqueInstrumentMeterImpl)(nil)
type key struct {
instrumentName string
@ -49,15 +49,15 @@ type key struct {
// NewMeterProvider returns a new provider that implements instrument
// name-uniqueness checking.
func NewMeterProvider(impl metric.MeterImpl) *MeterProvider {
func NewMeterProvider(impl otel.MeterImpl) *MeterProvider {
return &MeterProvider{
impl: NewUniqueInstrumentMeterImpl(impl),
}
}
// Meter implements MeterProvider.
func (p *MeterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
return metric.WrapMeterImpl(p.impl, instrumentationName, opts...)
func (p *MeterProvider) Meter(instrumentationName string, opts ...otel.MeterOption) otel.Meter {
return otel.WrapMeterImpl(p.impl, instrumentationName, opts...)
}
// ErrMetricKindMismatch is the standard error for mismatched metric
@ -65,21 +65,21 @@ func (p *MeterProvider) Meter(instrumentationName string, opts ...metric.MeterOp
var ErrMetricKindMismatch = fmt.Errorf(
"A metric was already registered by this name with another kind or number type")
// NewUniqueInstrumentMeterImpl returns a wrapped metric.MeterImpl with
// NewUniqueInstrumentMeterImpl returns a wrapped otel.MeterImpl with
// the addition of uniqueness checking.
func NewUniqueInstrumentMeterImpl(impl metric.MeterImpl) metric.MeterImpl {
func NewUniqueInstrumentMeterImpl(impl otel.MeterImpl) otel.MeterImpl {
return &uniqueInstrumentMeterImpl{
impl: impl,
state: map[key]metric.InstrumentImpl{},
state: map[key]otel.InstrumentImpl{},
}
}
// RecordBatch implements metric.MeterImpl.
func (u *uniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, ms ...metric.Measurement) {
// RecordBatch implements otel.MeterImpl.
func (u *uniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []label.KeyValue, ms ...otel.Measurement) {
u.impl.RecordBatch(ctx, labels, ms...)
}
func keyOf(descriptor metric.Descriptor) key {
func keyOf(descriptor otel.Descriptor) key {
return key{
descriptor.Name(),
descriptor.InstrumentationName(),
@ -89,7 +89,7 @@ func keyOf(descriptor metric.Descriptor) key {
// NewMetricKindMismatchError formats an error that describes a
// mismatched metric instrument definition.
func NewMetricKindMismatchError(desc metric.Descriptor) error {
func NewMetricKindMismatchError(desc otel.Descriptor) error {
return fmt.Errorf("Metric was %s (%s %s)registered as a %s %s: %w",
desc.Name(),
desc.InstrumentationName(),
@ -99,9 +99,9 @@ func NewMetricKindMismatchError(desc metric.Descriptor) error {
ErrMetricKindMismatch)
}
// Compatible determines whether two metric.Descriptors are considered
// Compatible determines whether two otel.Descriptors are considered
// the same for the purpose of uniqueness checking.
func Compatible(candidate, existing metric.Descriptor) bool {
func Compatible(candidate, existing otel.Descriptor) bool {
return candidate.InstrumentKind() == existing.InstrumentKind() &&
candidate.NumberKind() == existing.NumberKind()
}
@ -111,7 +111,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 otel.Descriptor) (otel.InstrumentImpl, error) {
impl, ok := u.state[keyOf(descriptor)]
if !ok {
return nil, nil
@ -124,8 +124,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 otel.MeterImpl.
func (u *uniqueInstrumentMeterImpl) NewSyncInstrument(descriptor otel.Descriptor) (otel.SyncImpl, error) {
u.lock.Lock()
defer u.lock.Unlock()
@ -134,7 +134,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.(otel.SyncImpl), nil
}
syncInst, err := u.impl.NewSyncInstrument(descriptor)
@ -145,11 +145,11 @@ func (u *uniqueInstrumentMeterImpl) NewSyncInstrument(descriptor metric.Descript
return syncInst, nil
}
// NewAsyncInstrument implements metric.MeterImpl.
// NewAsyncInstrument implements otel.MeterImpl.
func (u *uniqueInstrumentMeterImpl) NewAsyncInstrument(
descriptor metric.Descriptor,
runner metric.AsyncRunner,
) (metric.AsyncImpl, error) {
descriptor otel.Descriptor,
runner otel.AsyncRunner,
) (otel.AsyncImpl, error) {
u.lock.Lock()
defer u.lock.Unlock()
@ -158,7 +158,7 @@ func (u *uniqueInstrumentMeterImpl) NewAsyncInstrument(
if err != nil {
return nil, err
} else if impl != nil {
return impl.(metric.AsyncImpl), nil
return impl.(otel.AsyncImpl), nil
}
asyncInst, err := u.impl.NewAsyncInstrument(descriptor, runner)

View File

@ -21,49 +21,49 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
mockTest "go.opentelemetry.io/otel/api/metric/metrictest"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/oteltest"
"go.opentelemetry.io/otel/registry"
)
type (
newFunc func(m metric.Meter, name string) (metric.InstrumentImpl, error)
newFunc func(m otel.Meter, name string) (otel.InstrumentImpl, error)
)
var (
allNew = map[string]newFunc{
"counter.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
"counter.int64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewInt64Counter(name))
},
"counter.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
"counter.float64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewFloat64Counter(name))
},
"valuerecorder.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
"valuerecorder.int64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewInt64ValueRecorder(name))
},
"valuerecorder.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
"valuerecorder.float64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewFloat64ValueRecorder(name))
},
"valueobserver.int64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
return unwrap(m.NewInt64ValueObserver(name, func(context.Context, metric.Int64ObserverResult) {}))
"valueobserver.int64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewInt64ValueObserver(name, func(context.Context, otel.Int64ObserverResult) {}))
},
"valueobserver.float64": func(m metric.Meter, name string) (metric.InstrumentImpl, error) {
return unwrap(m.NewFloat64ValueObserver(name, func(context.Context, metric.Float64ObserverResult) {}))
"valueobserver.float64": func(m otel.Meter, name string) (otel.InstrumentImpl, error) {
return unwrap(m.NewFloat64ValueObserver(name, func(context.Context, otel.Float64ObserverResult) {}))
},
}
)
func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) {
func unwrap(impl interface{}, err error) (otel.InstrumentImpl, error) {
if impl == nil {
return nil, err
}
if s, ok := impl.(interface {
SyncImpl() metric.SyncImpl
SyncImpl() otel.SyncImpl
}); ok {
return s.SyncImpl(), err
}
if a, ok := impl.(interface {
AsyncImpl() metric.AsyncImpl
AsyncImpl() otel.AsyncImpl
}); ok {
return a.AsyncImpl(), err
}
@ -72,7 +72,7 @@ func unwrap(impl interface{}, err error) (metric.InstrumentImpl, error) {
func TestRegistrySameInstruments(t *testing.T) {
for _, nf := range allNew {
_, provider := mockTest.NewMeterProvider()
_, provider := oteltest.NewMeterProvider()
meter := provider.Meter("meter")
inst1, err1 := nf(meter, "this")
@ -86,7 +86,7 @@ func TestRegistrySameInstruments(t *testing.T) {
func TestRegistryDifferentNamespace(t *testing.T) {
for _, nf := range allNew {
_, provider := mockTest.NewMeterProvider()
_, provider := oteltest.NewMeterProvider()
meter1 := provider.Meter("meter1")
meter2 := provider.Meter("meter2")
@ -101,7 +101,7 @@ func TestRegistryDifferentNamespace(t *testing.T) {
func TestRegistryDiffInstruments(t *testing.T) {
for origName, origf := range allNew {
_, provider := mockTest.NewMeterProvider()
_, provider := oteltest.NewMeterProvider()
meter := provider.Meter("meter")
_, err := origf(meter, "this")
@ -121,7 +121,7 @@ func TestRegistryDiffInstruments(t *testing.T) {
}
func TestMeterProvider(t *testing.T) {
impl, _ := mockTest.NewMeter()
impl, _ := oteltest.NewMeter()
p := registry.NewMeterProvider(impl)
m1 := p.Meter("m1")
m1p := p.Meter("m1")

View File

@ -18,7 +18,7 @@ import (
"fmt"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
)
// These interfaces describe the various ways to access state from an
@ -37,7 +37,7 @@ type (
// Sum returns an aggregated sum.
Sum interface {
Aggregation
Sum() (metric.Number, error)
Sum() (otel.Number, error)
}
// Count returns the number of values that were aggregated.
@ -49,32 +49,32 @@ type (
// Min returns the minimum value over the set of values that were aggregated.
Min interface {
Aggregation
Min() (metric.Number, error)
Min() (otel.Number, error)
}
// Max returns the maximum value over the set of values that were aggregated.
Max interface {
Aggregation
Max() (metric.Number, error)
Max() (otel.Number, error)
}
// Quantile returns an exact or estimated quantile over the
// set of values that were aggregated.
Quantile interface {
Aggregation
Quantile(float64) (metric.Number, error)
Quantile(float64) (otel.Number, error)
}
// LastValue returns the latest value that was aggregated.
LastValue interface {
Aggregation
LastValue() (metric.Number, time.Time, error)
LastValue() (otel.Number, time.Time, error)
}
// Points returns the raw set of values that were aggregated.
Points interface {
Aggregation
Points() ([]metric.Number, error)
Points() ([]otel.Number, error)
}
// Buckets represents histogram buckets boundaries and counts.
@ -96,16 +96,16 @@ type (
Histogram interface {
Aggregation
Count() (int64, error)
Sum() (metric.Number, error)
Sum() (otel.Number, error)
Histogram() (Buckets, error)
}
// MinMaxSumCount supports the Min, Max, Sum, and Count interfaces.
MinMaxSumCount interface {
Aggregation
Min() (metric.Number, error)
Max() (metric.Number, error)
Sum() (metric.Number, error)
Min() (otel.Number, error)
Max() (otel.Number, error)
Sum() (otel.Number, error)
Count() (int64, error)
}
@ -113,11 +113,11 @@ type (
// interfaces.
Distribution interface {
Aggregation
Min() (metric.Number, error)
Max() (metric.Number, error)
Sum() (metric.Number, error)
Min() (otel.Number, error)
Max() (otel.Number, error)
Sum() (otel.Number, error)
Count() (int64, error)
Quantile(float64) (metric.Number, error)
Quantile(float64) (otel.Number, error)
}
)

View File

@ -19,7 +19,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
)
@ -37,16 +37,16 @@ func TestExportKindIncludes(t *testing.T) {
require.False(t, DeltaExporter.Includes(PassThroughExporter|CumulativeExporter))
}
var deltaMemoryKinds = []metric.InstrumentKind{
metric.SumObserverInstrumentKind,
metric.UpDownSumObserverInstrumentKind,
var deltaMemoryKinds = []otel.InstrumentKind{
otel.SumObserverInstrumentKind,
otel.UpDownSumObserverInstrumentKind,
}
var cumulativeMemoryKinds = []metric.InstrumentKind{
metric.ValueRecorderInstrumentKind,
metric.ValueObserverInstrumentKind,
metric.CounterInstrumentKind,
metric.UpDownCounterInstrumentKind,
var cumulativeMemoryKinds = []otel.InstrumentKind{
otel.ValueRecorderInstrumentKind,
otel.ValueObserverInstrumentKind,
otel.CounterInstrumentKind,
otel.UpDownCounterInstrumentKind,
}
func TestExportKindMemoryRequired(t *testing.T) {

View File

@ -21,7 +21,7 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/resource"
@ -94,7 +94,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 *otel.Descriptor, aggregator ...*Aggregator)
}
// Checkpointer is the interface used by a Controller to coordinate
@ -152,7 +152,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 metric.Number, descriptor *metric.Descriptor) error
Update(ctx context.Context, number otel.Number, descriptor *otel.Descriptor) error
// SynchronizedMove is called during collection to finish one
// period of aggregation by atomically saving the
@ -173,7 +173,7 @@ type Aggregator interface {
//
// This call has no Context argument because it is expected to
// perform only computation.
SynchronizedMove(destination Aggregator, descriptor *metric.Descriptor) error
SynchronizedMove(destination Aggregator, descriptor *otel.Descriptor) error
// Merge combines the checkpointed state from the argument
// Aggregator into this Aggregator. Merge is not synchronized
@ -181,7 +181,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 *otel.Descriptor) error
}
// Subtractor is an optional interface implemented by some
@ -191,7 +191,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 *otel.Descriptor) error
}
// Exporter handles presentation of the checkpoint of aggregate
@ -221,7 +221,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 *otel.Descriptor, aggregatorKind aggregation.Kind) ExportKind
}
// CheckpointSet allows a controller to access a complete checkpoint of
@ -262,7 +262,7 @@ type CheckpointSet interface {
// are shared by the Accumulator->Processor and Processor->Exporter
// steps.
type Metadata struct {
descriptor *metric.Descriptor
descriptor *otel.Descriptor
labels *label.Set
resource *resource.Resource
}
@ -285,7 +285,7 @@ type Record struct {
}
// Descriptor describes the metric instrument being exported.
func (m Metadata) Descriptor() *metric.Descriptor {
func (m Metadata) Descriptor() *otel.Descriptor {
return m.descriptor
}
@ -304,7 +304,7 @@ func (m Metadata) Resource() *resource.Resource {
// Accumulations to send to Processors. The Descriptor, Labels, Resource,
// and Aggregator represent aggregate metric events received over a single
// collection period.
func NewAccumulation(descriptor *metric.Descriptor, labels *label.Set, resource *resource.Resource, aggregator Aggregator) Accumulation {
func NewAccumulation(descriptor *otel.Descriptor, labels *label.Set, resource *resource.Resource, aggregator Aggregator) Accumulation {
return Accumulation{
Metadata: Metadata{
descriptor: descriptor,
@ -324,7 +324,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 *label.Set, resource *resource.Resource, aggregation aggregation.Aggregation, start, end time.Time) Record {
func NewRecord(descriptor *otel.Descriptor, labels *label.Set, resource *resource.Resource, aggregation aggregation.Aggregation, start, end time.Time) Record {
return Record{
Metadata: Metadata{
descriptor: descriptor,
@ -379,20 +379,20 @@ func (kind ExportKind) Includes(has ExportKind) bool {
}
// ExportKindFor returns a constant, as an implementation of ExportKindSelector.
func (kind ExportKind) ExportKindFor(_ *metric.Descriptor, _ aggregation.Kind) ExportKind {
func (kind ExportKind) ExportKindFor(_ *otel.Descriptor, _ aggregation.Kind) ExportKind {
return kind
}
// MemoryRequired returns whether an exporter of this kind requires
// memory to export correctly.
func (kind ExportKind) MemoryRequired(mkind metric.InstrumentKind) bool {
func (kind ExportKind) MemoryRequired(mkind otel.InstrumentKind) bool {
switch mkind {
case metric.ValueRecorderInstrumentKind, metric.ValueObserverInstrumentKind,
metric.CounterInstrumentKind, metric.UpDownCounterInstrumentKind:
case otel.ValueRecorderInstrumentKind, otel.ValueObserverInstrumentKind,
otel.CounterInstrumentKind, otel.UpDownCounterInstrumentKind:
// Delta-oriented instruments:
return kind.Includes(CumulativeExporter)
case metric.SumObserverInstrumentKind, metric.UpDownSumObserverInstrumentKind:
case otel.SumObserverInstrumentKind, otel.UpDownSumObserverInstrumentKind:
// Cumulative-oriented instruments:
return kind.Includes(DeltaExporter)
}

View File

@ -21,7 +21,7 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -29,7 +29,7 @@ import (
)
type mapkey struct {
desc *metric.Descriptor
desc *otel.Descriptor
distinct label.Distinct
}
@ -48,17 +48,17 @@ type NoopAggregator struct{}
var _ export.Aggregator = (*NoopAggregator)(nil)
// Update implements export.Aggregator.
func (NoopAggregator) Update(context.Context, metric.Number, *metric.Descriptor) error {
func (NoopAggregator) Update(context.Context, otel.Number, *otel.Descriptor) error {
return nil
}
// SynchronizedMove implements export.Aggregator.
func (NoopAggregator) SynchronizedMove(export.Aggregator, *metric.Descriptor) error {
func (NoopAggregator) SynchronizedMove(export.Aggregator, *otel.Descriptor) error {
return nil
}
// Merge implements export.Aggregator.
func (NoopAggregator) Merge(export.Aggregator, *metric.Descriptor) error {
func (NoopAggregator) Merge(export.Aggregator, *otel.Descriptor) error {
return nil
}
@ -91,7 +91,7 @@ func (p *CheckpointSet) Reset() {
//
// If there is an existing record with the same descriptor and labels,
// the stored aggregator will be returned and should be merged.
func (p *CheckpointSet) Add(desc *metric.Descriptor, newAgg export.Aggregator, labels ...label.KeyValue) (agg export.Aggregator, added bool) {
func (p *CheckpointSet) Add(desc *otel.Descriptor, newAgg export.Aggregator, labels ...label.KeyValue) (agg export.Aggregator, added bool) {
elabels := label.NewSet(labels...)
key := mapkey{

View File

@ -18,7 +18,7 @@ import (
"fmt"
"math"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
)
@ -34,15 +34,15 @@ 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 ValueRecorder metrics.
func RangeTest(number metric.Number, descriptor *metric.Descriptor) error {
func RangeTest(number otel.Number, descriptor *otel.Descriptor) error {
numberKind := descriptor.NumberKind()
if numberKind == metric.Float64NumberKind && math.IsNaN(number.AsFloat64()) {
if numberKind == otel.Float64NumberKind && math.IsNaN(number.AsFloat64()) {
return aggregation.ErrNaNInput
}
switch descriptor.InstrumentKind() {
case metric.CounterInstrumentKind, metric.SumObserverInstrumentKind:
case otel.CounterInstrumentKind, otel.SumObserverInstrumentKind:
if number.IsNegative(numberKind) {
return aggregation.ErrNegativeInput
}

View File

@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
@ -38,27 +38,27 @@ 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 *otel.Descriptor) {
// If the descriptor uses int64 numbers, this won't register as NaN
nan := metric.NewFloat64Number(math.NaN())
nan := otel.NewFloat64Number(math.NaN())
err := aggregator.RangeTest(nan, desc)
if desc.NumberKind() == metric.Float64NumberKind {
if desc.NumberKind() == otel.Float64NumberKind {
require.Equal(t, aggregation.ErrNaNInput, err)
} else {
require.Nil(t, err)
}
}
func testRangeNegative(t *testing.T, desc *metric.Descriptor) {
var neg, pos metric.Number
func testRangeNegative(t *testing.T, desc *otel.Descriptor) {
var neg, pos otel.Number
if desc.NumberKind() == metric.Float64NumberKind {
pos = metric.NewFloat64Number(+1)
neg = metric.NewFloat64Number(-1)
if desc.NumberKind() == otel.Float64NumberKind {
pos = otel.NewFloat64Number(+1)
neg = otel.NewFloat64Number(-1)
} else {
pos = metric.NewInt64Number(+1)
neg = metric.NewInt64Number(-1)
pos = otel.NewInt64Number(+1)
neg = otel.NewInt64Number(-1)
}
posErr := aggregator.RangeTest(pos, desc)
@ -70,11 +70,11 @@ func testRangeNegative(t *testing.T, desc *metric.Descriptor) {
func TestRangeTest(t *testing.T) {
// Only Counters implement a range test.
for _, nkind := range []metric.NumberKind{metric.Float64NumberKind, metric.Int64NumberKind} {
for _, nkind := range []otel.NumberKind{otel.Float64NumberKind, otel.Int64NumberKind} {
t.Run(nkind.String(), func(t *testing.T) {
desc := metric.NewDescriptor(
desc := otel.NewDescriptor(
"name",
metric.CounterInstrumentKind,
otel.CounterInstrumentKind,
nkind,
)
testRangeNegative(t, &desc)
@ -83,14 +83,14 @@ func TestRangeTest(t *testing.T) {
}
func TestNaNTest(t *testing.T) {
for _, nkind := range []metric.NumberKind{metric.Float64NumberKind, metric.Int64NumberKind} {
for _, nkind := range []otel.NumberKind{otel.Float64NumberKind, otel.Int64NumberKind} {
t.Run(nkind.String(), func(t *testing.T) {
for _, mkind := range []metric.InstrumentKind{
metric.CounterInstrumentKind,
metric.ValueRecorderInstrumentKind,
metric.ValueObserverInstrumentKind,
for _, mkind := range []otel.InstrumentKind{
otel.CounterInstrumentKind,
otel.ValueRecorderInstrumentKind,
otel.ValueObserverInstrumentKind,
} {
desc := metric.NewDescriptor(
desc := otel.NewDescriptor(
"name",
mkind,
nkind,

View File

@ -22,7 +22,7 @@ import (
"testing"
"unsafe"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
ottest "go.opentelemetry.io/otel/internal/testing"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -31,30 +31,30 @@ import (
const Magnitude = 1000
type Profile struct {
NumberKind metric.NumberKind
Random func(sign int) metric.Number
NumberKind otel.NumberKind
Random func(sign int) otel.Number
}
func newProfiles() []Profile {
rnd := rand.New(rand.NewSource(rand.Int63()))
return []Profile{
{
NumberKind: metric.Int64NumberKind,
Random: func(sign int) metric.Number {
return metric.NewInt64Number(int64(sign) * int64(rnd.Intn(Magnitude+1)))
NumberKind: otel.Int64NumberKind,
Random: func(sign int) otel.Number {
return otel.NewInt64Number(int64(sign) * int64(rnd.Intn(Magnitude+1)))
},
},
{
NumberKind: metric.Float64NumberKind,
Random: func(sign int) metric.Number {
return metric.NewFloat64Number(float64(sign) * rnd.Float64() * Magnitude)
NumberKind: otel.Float64NumberKind,
Random: func(sign int) otel.Number {
return otel.NewFloat64Number(float64(sign) * rnd.Float64() * Magnitude)
},
},
}
}
func NewAggregatorTest(mkind metric.InstrumentKind, nkind metric.NumberKind) *metric.Descriptor {
desc := metric.NewDescriptor("test.name", mkind, nkind)
func NewAggregatorTest(mkind otel.InstrumentKind, nkind otel.NumberKind) *otel.Descriptor {
desc := otel.NewDescriptor("test.name", mkind, nkind)
return &desc
}
@ -85,17 +85,17 @@ func TestMain(m *testing.M) {
type Numbers struct {
// numbers has to be aligned for 64-bit atomic operations.
numbers []metric.Number
kind metric.NumberKind
numbers []otel.Number
kind otel.NumberKind
}
func NewNumbers(kind metric.NumberKind) Numbers {
func NewNumbers(kind otel.NumberKind) Numbers {
return Numbers{
kind: kind,
}
}
func (n *Numbers) Append(v metric.Number) {
func (n *Numbers) Append(v otel.Number) {
n.numbers = append(n.numbers, v)
}
@ -115,8 +115,8 @@ func (n *Numbers) Swap(i, j int) {
n.numbers[i], n.numbers[j] = n.numbers[j], n.numbers[i]
}
func (n *Numbers) Sum() metric.Number {
var sum metric.Number
func (n *Numbers) Sum() otel.Number {
var sum otel.Number
for _, num := range n.numbers {
sum.AddNumber(n.kind, num)
}
@ -127,16 +127,16 @@ func (n *Numbers) Count() int64 {
return int64(len(n.numbers))
}
func (n *Numbers) Min() metric.Number {
func (n *Numbers) Min() otel.Number {
return n.numbers[0]
}
func (n *Numbers) Max() metric.Number {
func (n *Numbers) Max() otel.Number {
return n.numbers[len(n.numbers)-1]
}
// Median() is an alias for Quantile(0.5).
func (n *Numbers) Median() metric.Number {
func (n *Numbers) Median() otel.Number {
// Note that len(n.numbers) is 1 greater than the max element
// index, so dividing by two rounds up. This gives the
// intended definition for Quantile() in tests, which is to
@ -145,12 +145,12 @@ func (n *Numbers) Median() metric.Number {
return n.numbers[len(n.numbers)/2]
}
func (n *Numbers) Points() []metric.Number {
func (n *Numbers) Points() []otel.Number {
return n.numbers
}
// Performs the same range test the SDK does on behalf of the aggregator.
func CheckedUpdate(t *testing.T, agg export.Aggregator, number metric.Number, descriptor *metric.Descriptor) {
func CheckedUpdate(t *testing.T, agg export.Aggregator, number otel.Number, descriptor *otel.Descriptor) {
ctx := context.Background()
// Note: Aggregator tests are written assuming that the SDK
@ -166,7 +166,7 @@ func CheckedUpdate(t *testing.T, agg export.Aggregator, number metric.Number, de
}
}
func CheckedMerge(t *testing.T, aggInto, aggFrom export.Aggregator, descriptor *metric.Descriptor) {
func CheckedMerge(t *testing.T, aggInto, aggFrom export.Aggregator, descriptor *otel.Descriptor) {
if err := aggInto.Merge(aggFrom, descriptor); err != nil {
t.Error("Unexpected Merge failure", err)
}

View File

@ -21,7 +21,7 @@ import (
"sync"
"unsafe"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -32,11 +32,11 @@ type (
// an array with the exact set of values.
Aggregator struct {
lock sync.Mutex
sum metric.Number
sum otel.Number
points points
}
points []metric.Number
points []otel.Number
)
var _ export.Aggregator = &Aggregator{}
@ -62,7 +62,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
}
// Sum returns the sum of values in the checkpoint.
func (c *Aggregator) Sum() (metric.Number, error) {
func (c *Aggregator) Sum() (otel.Number, error) {
return c.sum, nil
}
@ -72,29 +72,29 @@ func (c *Aggregator) Count() (int64, error) {
}
// Max returns the maximum value in the checkpoint.
func (c *Aggregator) Max() (metric.Number, error) {
func (c *Aggregator) Max() (otel.Number, error) {
return c.points.Quantile(1)
}
// Min returns the mininum value in the checkpoint.
func (c *Aggregator) Min() (metric.Number, error) {
func (c *Aggregator) Min() (otel.Number, error) {
return c.points.Quantile(0)
}
// Quantile returns the estimated quantile of data in the checkpoint.
// It is an error if `q` is less than 0 or greated than 1.
func (c *Aggregator) Quantile(q float64) (metric.Number, error) {
func (c *Aggregator) Quantile(q float64) (otel.Number, error) {
return c.points.Quantile(q)
}
// Points returns access to the raw data set.
func (c *Aggregator) Points() ([]metric.Number, error) {
func (c *Aggregator) Points() ([]otel.Number, error) {
return c.points, nil
}
// 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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -116,7 +116,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 metric.Number, desc *metric.Descriptor) error {
func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
c.lock.Lock()
c.points = append(c.points, number)
c.sum.AddNumber(desc.NumberKind(), number)
@ -126,7 +126,7 @@ func (c *Aggregator) Update(_ context.Context, number metric.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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -140,12 +140,12 @@ func (c *Aggregator) Merge(oa export.Aggregator, desc *metric.Descriptor) error
return nil
}
func (c *Aggregator) sort(kind metric.NumberKind) {
func (c *Aggregator) sort(kind otel.NumberKind) {
switch kind {
case metric.Float64NumberKind:
case otel.Float64NumberKind:
sort.Float64s(*(*[]float64)(unsafe.Pointer(&c.points)))
case metric.Int64NumberKind:
case otel.Int64NumberKind:
sort.Sort(&c.points)
default:
@ -155,7 +155,7 @@ func (c *Aggregator) sort(kind metric.NumberKind) {
}
}
func combine(a, b points, kind metric.NumberKind) points {
func combine(a, b points, kind otel.NumberKind) points {
result := make(points, 0, len(a)+len(b))
for len(a) != 0 && len(b) != 0 {
@ -190,7 +190,7 @@ func (p *points) Swap(i, j int) {
// Quantile returns the least X such that Pr(x<X)>=q, where X is an
// element of the data set. This uses the "Nearest-Rank" definition
// of a quantile.
func (p *points) Quantile(q float64) (metric.Number, error) {
func (p *points) Quantile(q float64) (otel.Number, error) {
if len(*p) == 0 {
return 0, aggregation.ErrNoData
}

View File

@ -22,7 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
)
@ -31,7 +31,7 @@ type updateTest struct {
count int
}
func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) {
func checkZero(t *testing.T, agg *Aggregator, desc *otel.Descriptor) {
kind := desc.NumberKind()
sum, err := agg.Sum()
@ -62,7 +62,7 @@ func new4() (_, _, _, _ *Aggregator) {
}
func (ut *updateTest) run(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg, ckpt := new2()
all := aggregatortest.NewNumbers(profile.NumberKind)
@ -129,7 +129,7 @@ type mergeTest struct {
}
func (mt *mergeTest) run(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg1, agg2, ckpt1, ckpt2 := new4()
all := aggregatortest.NewNumbers(profile.NumberKind)
@ -225,12 +225,12 @@ func TestArrayErrors(t *testing.T) {
require.Error(t, err)
require.Equal(t, err, aggregation.ErrNoData)
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
aggregatortest.CheckedUpdate(t, agg, metric.Number(0), descriptor)
aggregatortest.CheckedUpdate(t, agg, otel.Number(0), descriptor)
if profile.NumberKind == metric.Float64NumberKind {
aggregatortest.CheckedUpdate(t, agg, metric.NewFloat64Number(math.NaN()), descriptor)
if profile.NumberKind == otel.Float64NumberKind {
aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(math.NaN()), descriptor)
}
require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))
@ -240,7 +240,7 @@ func TestArrayErrors(t *testing.T) {
num, err := ckpt.Quantile(0)
require.Nil(t, err)
require.Equal(t, num, metric.Number(0))
require.Equal(t, num, otel.Number(0))
_, err = ckpt.Quantile(-0.0001)
require.Error(t, err)
@ -253,7 +253,7 @@ func TestArrayErrors(t *testing.T) {
}
func TestArrayFloat64(t *testing.T) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
fpsf := func(sign int) []float64 {
// Check behavior of a bunch of odd floating
@ -282,18 +282,18 @@ func TestArrayFloat64(t *testing.T) {
}
}
all := aggregatortest.NewNumbers(metric.Float64NumberKind)
all := aggregatortest.NewNumbers(otel.Float64NumberKind)
agg, ckpt := new2()
for _, f := range fpsf(1) {
all.Append(metric.NewFloat64Number(f))
aggregatortest.CheckedUpdate(t, agg, metric.NewFloat64Number(f), descriptor)
all.Append(otel.NewFloat64Number(f))
aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(f), descriptor)
}
for _, f := range fpsf(-1) {
all.Append(metric.NewFloat64Number(f))
aggregatortest.CheckedUpdate(t, agg, metric.NewFloat64Number(f), descriptor)
all.Append(otel.NewFloat64Number(f))
aggregatortest.CheckedUpdate(t, agg, otel.NewFloat64Number(f), descriptor)
}
require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))

View File

@ -20,7 +20,7 @@ import (
sdk "github.com/DataDog/sketches-go/ddsketch"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -33,7 +33,7 @@ type Config = sdk.Config
type Aggregator struct {
lock sync.Mutex
cfg *Config
kind metric.NumberKind
kind otel.NumberKind
sketch *sdk.DDSketch
}
@ -42,7 +42,7 @@ var _ aggregation.MinMaxSumCount = &Aggregator{}
var _ aggregation.Distribution = &Aggregator{}
// New returns a new DDSketch aggregator.
func New(cnt int, desc *metric.Descriptor, cfg *Config) []Aggregator {
func New(cnt int, desc *otel.Descriptor, cfg *Config) []Aggregator {
if cfg == nil {
cfg = NewDefaultConfig()
}
@ -73,7 +73,7 @@ func NewDefaultConfig() *Config {
}
// Sum returns the sum of values in the checkpoint.
func (c *Aggregator) Sum() (metric.Number, error) {
func (c *Aggregator) Sum() (otel.Number, error) {
return c.toNumber(c.sketch.Sum()), nil
}
@ -83,18 +83,18 @@ func (c *Aggregator) Count() (int64, error) {
}
// Max returns the maximum value in the checkpoint.
func (c *Aggregator) Max() (metric.Number, error) {
func (c *Aggregator) Max() (otel.Number, error) {
return c.Quantile(1)
}
// Min returns the minimum value in the checkpoint.
func (c *Aggregator) Min() (metric.Number, error) {
func (c *Aggregator) Min() (otel.Number, error) {
return c.Quantile(0)
}
// Quantile returns the estimated quantile of data in the checkpoint.
// It is an error if `q` is less than 0 or greated than 1.
func (c *Aggregator) Quantile(q float64) (metric.Number, error) {
func (c *Aggregator) Quantile(q float64) (otel.Number, error) {
if c.sketch.Count() == 0 {
return 0, aggregation.ErrNoData
}
@ -105,16 +105,16 @@ func (c *Aggregator) Quantile(q float64) (metric.Number, error) {
return c.toNumber(f), nil
}
func (c *Aggregator) toNumber(f float64) metric.Number {
if c.kind == metric.Float64NumberKind {
return metric.NewFloat64Number(f)
func (c *Aggregator) toNumber(f float64) otel.Number {
if c.kind == otel.Float64NumberKind {
return otel.NewFloat64Number(f)
}
return metric.NewInt64Number(int64(f))
return otel.NewInt64Number(int64(f))
}
// SynchronizedMove saves the current state into oa and resets the current state to
// a new sketch, taking a lock to prevent concurrent Update() calls.
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor) error {
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -131,7 +131,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
// 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 metric.Number, desc *metric.Descriptor) error {
func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
c.lock.Lock()
defer c.lock.Unlock()
c.sketch.Add(number.CoerceToFloat64(desc.NumberKind()))
@ -139,7 +139,7 @@ func (c *Aggregator) Update(_ context.Context, number metric.Number, desc *metri
}
// Merge combines two sketches into one.
func (c *Aggregator) Merge(oa export.Aggregator, d *metric.Descriptor) error {
func (c *Aggregator) Merge(oa export.Aggregator, d *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
)
@ -31,17 +31,17 @@ const count = 1000
type updateTest struct {
}
func new2(desc *metric.Descriptor) (_, _ *Aggregator) {
func new2(desc *otel.Descriptor) (_, _ *Aggregator) {
alloc := New(2, desc, NewDefaultConfig())
return &alloc[0], &alloc[1]
}
func new4(desc *metric.Descriptor) (_, _, _, _ *Aggregator) {
func new4(desc *otel.Descriptor) (_, _, _, _ *Aggregator) {
alloc := New(4, desc, NewDefaultConfig())
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 *otel.Descriptor) {
kind := desc.NumberKind()
sum, err := agg.Sum()
@ -66,7 +66,7 @@ func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) {
}
func (ut *updateTest) run(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg, ckpt := new2(descriptor)
all := aggregatortest.NewNumbers(profile.NumberKind)
@ -127,7 +127,7 @@ type mergeTest struct {
}
func (mt *mergeTest) run(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg1, agg2, ckpt1, ckpt2 := new4(descriptor)

View File

@ -19,7 +19,7 @@ import (
"math/rand"
"testing"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
)
@ -37,7 +37,7 @@ func benchmarkHistogramSearchFloat64(b *testing.B, size int) {
for i := range values {
values[i] = rand.Float64() * inputRange
}
desc := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, metric.Float64NumberKind)
desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Float64NumberKind)
agg := &histogram.New(1, desc, boundaries)[0]
ctx := context.Background()
@ -45,7 +45,7 @@ func benchmarkHistogramSearchFloat64(b *testing.B, size int) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = agg.Update(ctx, metric.NewFloat64Number(values[i]), desc)
_ = agg.Update(ctx, otel.NewFloat64Number(values[i]), desc)
}
}
@ -88,7 +88,7 @@ func benchmarkHistogramSearchInt64(b *testing.B, size int) {
for i := range values {
values[i] = int64(rand.Float64() * inputRange)
}
desc := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
agg := &histogram.New(1, desc, boundaries)[0]
ctx := context.Background()
@ -96,7 +96,7 @@ func benchmarkHistogramSearchInt64(b *testing.B, size int) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = agg.Update(ctx, metric.NewInt64Number(values[i]), desc)
_ = agg.Update(ctx, otel.NewInt64Number(values[i]), desc)
}
}

View File

@ -19,7 +19,7 @@ import (
"sort"
"sync"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -36,7 +36,7 @@ type (
Aggregator struct {
lock sync.Mutex
boundaries []float64
kind metric.NumberKind
kind otel.NumberKind
state state
}
@ -45,7 +45,7 @@ type (
// the less than equal bucket count for the pre-determined boundaries.
state struct {
bucketCounts []float64
sum metric.Number
sum otel.Number
count int64
}
)
@ -63,7 +63,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, boundaries []float64) []Aggregator {
func New(cnt int, desc *otel.Descriptor, boundaries []float64) []Aggregator {
aggs := make([]Aggregator, cnt)
// Boundaries MUST be ordered otherwise the histogram could not
@ -94,7 +94,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
}
// Sum returns the sum of all values in the checkpoint.
func (c *Aggregator) Sum() (metric.Number, error) {
func (c *Aggregator) Sum() (otel.Number, error) {
return c.state.sum, nil
}
@ -115,7 +115,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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -134,7 +134,7 @@ func emptyState(boundaries []float64) state {
}
// Update adds the recorded measurement to the current data set.
func (c *Aggregator) Update(_ context.Context, number metric.Number, desc *metric.Descriptor) error {
func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
kind := desc.NumberKind()
asFloat := number.CoerceToFloat64(kind)
@ -168,7 +168,7 @@ func (c *Aggregator) Update(_ context.Context, number metric.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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -22,7 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
)
@ -60,19 +60,19 @@ var (
boundaries = []float64{500, 250, 750}
)
func new2(desc *metric.Descriptor) (_, _ *histogram.Aggregator) {
func new2(desc *otel.Descriptor) (_, _ *histogram.Aggregator) {
alloc := histogram.New(2, desc, boundaries)
return &alloc[0], &alloc[1]
}
func new4(desc *metric.Descriptor) (_, _, _, _ *histogram.Aggregator) {
func new4(desc *otel.Descriptor) (_, _, _, _ *histogram.Aggregator) {
alloc := histogram.New(4, desc, boundaries)
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 *otel.Descriptor) {
asum, err := agg.Sum()
require.Equal(t, metric.Number(0), asum, "Empty checkpoint sum = 0")
require.Equal(t, otel.Number(0), asum, "Empty checkpoint sum = 0")
require.NoError(t, err)
count, err := agg.Count()
@ -109,7 +109,7 @@ func TestHistogramPositiveAndNegative(t *testing.T) {
// Validates count, sum and buckets for a given profile and policy
func testHistogram(t *testing.T, profile aggregatortest.Profile, policy policy) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg, ckpt := new2(descriptor)
@ -154,7 +154,7 @@ func testHistogram(t *testing.T, profile aggregatortest.Profile, policy policy)
func TestHistogramInitial(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg := &histogram.New(1, descriptor, boundaries)[0]
buckets, err := agg.Histogram()
@ -167,7 +167,7 @@ func TestHistogramInitial(t *testing.T) {
func TestHistogramMerge(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg1, agg2, ckpt1, ckpt2 := new4(descriptor)
@ -219,7 +219,7 @@ func TestHistogramMerge(t *testing.T) {
func TestHistogramNotSet(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg, ckpt := new2(descriptor)
@ -231,7 +231,7 @@ func TestHistogramNotSet(t *testing.T) {
})
}
func calcBuckets(points []metric.Number, profile aggregatortest.Profile) []uint64 {
func calcBuckets(points []otel.Number, profile aggregatortest.Profile) []uint64 {
sortedBoundaries := make([]float64, len(boundaries))
copy(sortedBoundaries, boundaries)

View File

@ -20,7 +20,7 @@ import (
"time"
"unsafe"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -40,7 +40,7 @@ type (
// value is the int64- or float64-encoded Set() data
//
// value needs to be aligned for 64-bit atomic operations.
value metric.Number
value otel.Number
// timestamp indicates when this record was submitted.
// this can be used to pick a winner when multiple
@ -82,7 +82,7 @@ func (g *Aggregator) Kind() aggregation.Kind {
// corresponding timestamp. The error value aggregation.ErrNoData
// will be returned if (due to a race condition) the checkpoint was
// computed before the first value was set.
func (g *Aggregator) LastValue() (metric.Number, time.Time, error) {
func (g *Aggregator) LastValue() (otel.Number, time.Time, error) {
gd := (*lastValueData)(g.value)
if gd == unsetLastValue {
return 0, time.Time{}, aggregation.ErrNoData
@ -91,7 +91,7 @@ func (g *Aggregator) LastValue() (metric.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, _ *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(g, oa)
@ -101,7 +101,7 @@ func (g *Aggregator) SynchronizedMove(oa export.Aggregator, _ *metric.Descriptor
}
// Update atomically sets the current "last" value.
func (g *Aggregator) Update(_ context.Context, number metric.Number, desc *metric.Descriptor) error {
func (g *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
ngd := &lastValueData{
value: number,
timestamp: time.Now(),
@ -112,7 +112,7 @@ func (g *Aggregator) Update(_ context.Context, number metric.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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(g, oa)

View File

@ -24,7 +24,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
ottest "go.opentelemetry.io/otel/internal/testing"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -64,16 +64,16 @@ func checkZero(t *testing.T, agg *Aggregator) {
lv, ts, err := agg.LastValue()
require.True(t, errors.Is(err, aggregation.ErrNoData))
require.Equal(t, time.Time{}, ts)
require.Equal(t, metric.Number(0), lv)
require.Equal(t, otel.Number(0), lv)
}
func TestLastValueUpdate(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
agg, ckpt := new2()
record := aggregatortest.NewAggregatorTest(metric.ValueObserverInstrumentKind, profile.NumberKind)
record := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, profile.NumberKind)
var last metric.Number
var last otel.Number
for i := 0; i < count; i++ {
x := profile.Random(rand.Intn(1)*2 - 1)
last = x
@ -93,7 +93,7 @@ func TestLastValueMerge(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
agg1, agg2, ckpt1, ckpt2 := new4()
descriptor := aggregatortest.NewAggregatorTest(metric.ValueObserverInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, profile.NumberKind)
first1 := profile.Random(+1)
first2 := profile.Random(+1)
@ -124,7 +124,7 @@ func TestLastValueMerge(t *testing.T) {
}
func TestLastValueNotSet(t *testing.T) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueObserverInstrumentKind, metric.Int64NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
g, ckpt := new2()
require.NoError(t, g.SynchronizedMove(ckpt, descriptor))

View File

@ -18,7 +18,7 @@ import (
"context"
"sync"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -29,14 +29,14 @@ type (
// keeping only the min, max, sum, and count.
Aggregator struct {
lock sync.Mutex
kind metric.NumberKind
kind otel.NumberKind
state
}
state struct {
sum metric.Number
min metric.Number
max metric.Number
sum otel.Number
min otel.Number
max otel.Number
count int64
}
)
@ -49,7 +49,7 @@ var _ aggregation.MinMaxSumCount = &Aggregator{}
// Max.
//
// This type uses a mutex for Update() and SynchronizedMove() concurrency.
func New(cnt int, desc *metric.Descriptor) []Aggregator {
func New(cnt int, desc *otel.Descriptor) []Aggregator {
kind := desc.NumberKind()
aggs := make([]Aggregator, cnt)
for i := range aggs {
@ -72,7 +72,7 @@ func (c *Aggregator) Kind() aggregation.Kind {
}
// Sum returns the sum of values in the checkpoint.
func (c *Aggregator) Sum() (metric.Number, error) {
func (c *Aggregator) Sum() (otel.Number, error) {
return c.sum, nil
}
@ -84,7 +84,7 @@ func (c *Aggregator) Count() (int64, error) {
// Min returns the minimum value in the checkpoint.
// The error value aggregation.ErrNoData will be returned
// if there were no measurements recorded during the checkpoint.
func (c *Aggregator) Min() (metric.Number, error) {
func (c *Aggregator) Min() (otel.Number, error) {
if c.count == 0 {
return 0, aggregation.ErrNoData
}
@ -94,7 +94,7 @@ func (c *Aggregator) Min() (metric.Number, error) {
// Max returns the maximum value in the checkpoint.
// The error value aggregation.ErrNoData will be returned
// if there were no measurements recorded during the checkpoint.
func (c *Aggregator) Max() (metric.Number, error) {
func (c *Aggregator) Max() (otel.Number, error) {
if c.count == 0 {
return 0, aggregation.ErrNoData
}
@ -103,7 +103,7 @@ func (c *Aggregator) Max() (metric.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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -119,7 +119,7 @@ func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *metric.Descrip
return nil
}
func emptyState(kind metric.NumberKind) state {
func emptyState(kind otel.NumberKind) state {
return state{
count: 0,
sum: 0,
@ -129,7 +129,7 @@ func emptyState(kind metric.NumberKind) state {
}
// Update adds the recorded measurement to the current data set.
func (c *Aggregator) Update(_ context.Context, number metric.Number, desc *metric.Descriptor) error {
func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
kind := desc.NumberKind()
c.lock.Lock()
@ -146,7 +146,7 @@ func (c *Aggregator) Update(_ context.Context, number metric.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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)

View File

@ -22,7 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
)
@ -76,17 +76,17 @@ func TestMinMaxSumCountPositiveAndNegative(t *testing.T) {
})
}
func new2(desc *metric.Descriptor) (_, _ *Aggregator) {
func new2(desc *otel.Descriptor) (_, _ *Aggregator) {
alloc := New(2, desc)
return &alloc[0], &alloc[1]
}
func new4(desc *metric.Descriptor) (_, _, _, _ *Aggregator) {
func new4(desc *otel.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 *otel.Descriptor) {
kind := desc.NumberKind()
sum, err := agg.Sum()
@ -108,7 +108,7 @@ func checkZero(t *testing.T, agg *Aggregator, desc *metric.Descriptor) {
// Validates min, max, sum and count for a given profile and policy
func minMaxSumCount(t *testing.T, profile aggregatortest.Profile, policy policy) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg, ckpt := new2(descriptor)
@ -156,7 +156,7 @@ func minMaxSumCount(t *testing.T, profile aggregatortest.Profile, policy policy)
func TestMinMaxSumCountMerge(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
agg1, agg2, ckpt1, ckpt2 := new4(descriptor)
@ -214,7 +214,7 @@ func TestMinMaxSumCountMerge(t *testing.T) {
func TestMaxSumCountNotSet(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
alloc := New(2, descriptor)
agg, ckpt := &alloc[0], &alloc[1]
@ -222,7 +222,7 @@ func TestMaxSumCountNotSet(t *testing.T) {
require.NoError(t, agg.SynchronizedMove(ckpt, descriptor))
asum, err := ckpt.Sum()
require.Equal(t, metric.Number(0), asum, "Empty checkpoint sum = 0")
require.Equal(t, otel.Number(0), asum, "Empty checkpoint sum = 0")
require.Nil(t, err)
count, err := ckpt.Count()
@ -231,6 +231,6 @@ func TestMaxSumCountNotSet(t *testing.T) {
max, err := ckpt.Max()
require.Equal(t, aggregation.ErrNoData, err)
require.Equal(t, metric.Number(0), max)
require.Equal(t, otel.Number(0), max)
})
}

View File

@ -17,7 +17,7 @@ package sum // import "go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
import (
"context"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
@ -27,7 +27,7 @@ import (
type Aggregator struct {
// current holds current increments to this counter record
// current needs to be aligned for 64-bit atomic operations.
value metric.Number
value otel.Number
}
var _ export.Aggregator = &Aggregator{}
@ -53,29 +53,29 @@ func (c *Aggregator) Kind() aggregation.Kind {
// Sum returns the last-checkpointed sum. This will never return an
// error.
func (c *Aggregator) Sum() (metric.Number, error) {
func (c *Aggregator) Sum() (otel.Number, error) {
return c.value, nil
}
// 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, _ *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
}
o.value = c.value.SwapNumberAtomic(metric.Number(0))
o.value = c.value.SwapNumberAtomic(otel.Number(0))
return nil
}
// Update atomically adds to the current value.
func (c *Aggregator) Update(_ context.Context, number metric.Number, desc *metric.Descriptor) error {
func (c *Aggregator) Update(_ context.Context, number otel.Number, desc *otel.Descriptor) error {
c.value.AddNumberAtomic(desc.NumberKind(), number)
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 *otel.Descriptor) error {
o, _ := oa.(*Aggregator)
if o == nil {
return aggregator.NewInconsistentAggregatorError(c, oa)
@ -84,7 +84,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 *otel.Descriptor) error {
op, _ := opAgg.(*Aggregator)
if op == nil {
return aggregator.NewInconsistentAggregatorError(c, opAgg)
@ -96,6 +96,6 @@ func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *metri
}
res.value = c.value
res.value.AddNumber(descriptor.NumberKind(), metric.NewNumberSignChange(descriptor.NumberKind(), op.value))
res.value.AddNumber(descriptor.NumberKind(), otel.NewNumberSignChange(descriptor.NumberKind(), op.value))
return nil
}

View File

@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
ottest "go.opentelemetry.io/otel/internal/testing"
"go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest"
)
@ -53,7 +53,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 *otel.Descriptor) {
kind := desc.NumberKind()
sum, err := agg.Sum()
@ -65,9 +65,9 @@ func TestCounterSum(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
agg, ckpt := new2()
descriptor := aggregatortest.NewAggregatorTest(metric.CounterInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.CounterInstrumentKind, profile.NumberKind)
sum := metric.Number(0)
sum := otel.Number(0)
for i := 0; i < count; i++ {
x := profile.Random(+1)
sum.AddNumber(profile.NumberKind, x)
@ -89,9 +89,9 @@ func TestValueRecorderSum(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
agg, ckpt := new2()
descriptor := aggregatortest.NewAggregatorTest(metric.ValueRecorderInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.ValueRecorderInstrumentKind, profile.NumberKind)
sum := metric.Number(0)
sum := otel.Number(0)
for i := 0; i < count; i++ {
r1 := profile.Random(+1)
@ -115,9 +115,9 @@ func TestCounterMerge(t *testing.T) {
aggregatortest.RunProfiles(t, func(t *testing.T, profile aggregatortest.Profile) {
agg1, agg2, ckpt1, ckpt2 := new4()
descriptor := aggregatortest.NewAggregatorTest(metric.CounterInstrumentKind, profile.NumberKind)
descriptor := aggregatortest.NewAggregatorTest(otel.CounterInstrumentKind, profile.NumberKind)
sum := metric.Number(0)
sum := otel.Number(0)
for i := 0; i < count; i++ {
x := profile.Random(+1)
sum.AddNumber(profile.NumberKind, x)

View File

@ -20,8 +20,8 @@ import (
"math/rand"
"testing"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric"
@ -29,7 +29,7 @@ import (
)
type benchFixture struct {
meter metric.Meter
meter otel.Meter
accumulator *sdk.Accumulator
B *testing.B
export.AggregatorSelector
@ -43,7 +43,7 @@ func newFixture(b *testing.B) *benchFixture {
}
bf.accumulator = sdk.NewAccumulator(bf)
bf.meter = metric.WrapMeterImpl(bf.accumulator, "benchmarks")
bf.meter = otel.WrapMeterImpl(bf.accumulator, "benchmarks")
return bf
}
@ -51,12 +51,12 @@ func (f *benchFixture) Process(export.Accumulation) error {
return nil
}
func (f *benchFixture) Meter(_ string, _ ...metric.MeterOption) metric.Meter {
func (f *benchFixture) Meter(_ string, _ ...otel.MeterOption) otel.Meter {
return f.meter
}
func (f *benchFixture) meterMust() metric.MeterMust {
return metric.Must(f.meter)
func (f *benchFixture) meterMust() otel.MeterMust {
return otel.Must(f.meter)
}
func makeManyLabels(n int) [][]label.KeyValue {
@ -401,7 +401,7 @@ func BenchmarkObserverRegistration(b *testing.B) {
for i := 0; i < b.N; i++ {
names = append(names, fmt.Sprintf("test.%d.lastvalue", i))
}
cb := func(_ context.Context, result metric.Int64ObserverResult) {}
cb := func(_ context.Context, result otel.Int64ObserverResult) {}
b.ResetTimer()
@ -414,7 +414,7 @@ func BenchmarkValueObserverObservationInt64(b *testing.B) {
ctx := context.Background()
fix := newFixture(b)
labs := makeLabels(1)
_ = fix.meterMust().NewInt64ValueObserver("test.lastvalue", func(_ context.Context, result metric.Int64ObserverResult) {
_ = fix.meterMust().NewInt64ValueObserver("test.lastvalue", func(_ context.Context, result otel.Int64ObserverResult) {
for i := 0; i < b.N; i++ {
result.Observe((int64)(i), labs...)
}
@ -429,7 +429,7 @@ func BenchmarkValueObserverObservationFloat64(b *testing.B) {
ctx := context.Background()
fix := newFixture(b)
labs := makeLabels(1)
_ = fix.meterMust().NewFloat64ValueObserver("test.lastvalue", func(_ context.Context, result metric.Float64ObserverResult) {
_ = fix.meterMust().NewFloat64ValueObserver("test.lastvalue", func(_ context.Context, result otel.Float64ObserverResult) {
for i := 0; i < b.N; i++ {
result.Observe((float64)(i), labs...)
}
@ -501,7 +501,7 @@ func benchmarkBatchRecord8Labels(b *testing.B, numInst int) {
ctx := context.Background()
fix := newFixture(b)
labs := makeLabels(numLabels)
var meas []metric.Measurement
var meas []otel.Measurement
for i := 0; i < numInst; i++ {
inst := fix.meterMust().NewInt64Counter(fmt.Sprintf("int64.%d.sum", i))

View File

@ -18,8 +18,8 @@ import (
"context"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/registry"
export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric"
controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time"
@ -81,7 +81,7 @@ func (c *Controller) SetClock(clock controllerTime.Clock) {
// MeterProvider returns a MeterProvider for the implementation managed by
// this controller.
func (c *Controller) MeterProvider() metric.MeterProvider {
func (c *Controller) MeterProvider() otel.MeterProvider {
return c.provider
}

View File

@ -22,7 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/controller/controllertest"
@ -44,7 +44,7 @@ func TestPullNoCache(t *testing.T) {
ctx := context.Background()
meter := puller.MeterProvider().Meter("nocache")
counter := metric.Must(meter).NewInt64Counter("counter.sum")
counter := otel.Must(meter).NewInt64Counter("counter.sum")
counter.Add(ctx, 10, label.String("A", "B"))
@ -81,7 +81,7 @@ func TestPullWithCache(t *testing.T) {
ctx := context.Background()
meter := puller.MeterProvider().Meter("nocache")
counter := metric.Must(meter).NewInt64Counter("counter.sum")
counter := otel.Must(meter).NewInt64Counter("counter.sum")
counter.Add(ctx, 10, label.String("A", "B"))

View File

@ -19,9 +19,9 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/metric/registry"
"go.opentelemetry.io/otel/registry"
export "go.opentelemetry.io/otel/sdk/export/metric"
sdk "go.opentelemetry.io/otel/sdk/metric"
controllerTime "go.opentelemetry.io/otel/sdk/metric/controller/time"
@ -84,7 +84,7 @@ func (c *Controller) SetClock(clock controllerTime.Clock) {
}
// MeterProvider returns a MeterProvider instance for this controller.
func (c *Controller) MeterProvider() metric.MeterProvider {
func (c *Controller) MeterProvider() otel.MeterProvider {
return c.provider
}

View File

@ -24,8 +24,8 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -114,7 +114,7 @@ func TestPushTicker(t *testing.T) {
ctx := context.Background()
counter := metric.Must(meter).NewInt64Counter("counter.sum")
counter := otel.Must(meter).NewInt64Counter("counter.sum")
p.Start()
@ -194,8 +194,8 @@ func TestPushExportError(t *testing.T) {
ctx := context.Background()
meter := p.MeterProvider().Meter("name")
counter1 := metric.Must(meter).NewInt64Counter("counter1.sum")
counter2 := metric.Must(meter).NewInt64Counter("counter2.sum")
counter1 := otel.Must(meter).NewInt64Counter("counter1.sum")
counter2 := otel.Must(meter).NewInt64Counter("counter2.sum")
p.Start()
runtime.Gosched()

View File

@ -23,8 +23,8 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -33,7 +33,7 @@ import (
"go.opentelemetry.io/otel/sdk/resource"
)
var Must = metric.Must
var Must = otel.Must
var testResource = resource.New(label.String("R", "V"))
type handler struct {
@ -83,12 +83,12 @@ type testSelector struct {
newAggCount int
}
func (ts *testSelector) AggregatorFor(desc *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (ts *testSelector) AggregatorFor(desc *otel.Descriptor, aggPtrs ...*export.Aggregator) {
ts.newAggCount += len(aggPtrs)
processortest.AggregatorSelector().AggregatorFor(desc, aggPtrs...)
}
func newSDK(t *testing.T) (metric.Meter, *metricsdk.Accumulator, *correctnessProcessor) {
func newSDK(t *testing.T) (otel.Meter, *metricsdk.Accumulator, *correctnessProcessor) {
testHandler.Reset()
processor := &correctnessProcessor{
t: t,
@ -98,7 +98,7 @@ func newSDK(t *testing.T) (metric.Meter, *metricsdk.Accumulator, *correctnessPro
processor,
metricsdk.WithResource(testResource),
)
meter := metric.WrapMeterImpl(accum, "test")
meter := otel.WrapMeterImpl(accum, "test")
return meter, accum, processor
}
@ -253,7 +253,7 @@ func TestSDKLabelsDeduplication(t *testing.T) {
var actual [][]label.KeyValue
for _, rec := range processor.accumulations {
sum, _ := rec.Aggregator().(aggregation.Sum).Sum()
require.Equal(t, sum, metric.NewInt64Number(2))
require.Equal(t, sum, otel.NewInt64Number(2))
kvs := rec.Labels().ToSlice()
actual = append(actual, kvs)
@ -300,13 +300,13 @@ func TestObserverCollection(t *testing.T) {
ctx := context.Background()
meter, sdk, processor := newSDK(t)
_ = Must(meter).NewFloat64ValueObserver("float.valueobserver.lastvalue", func(_ context.Context, result metric.Float64ObserverResult) {
_ = Must(meter).NewFloat64ValueObserver("float.valueobserver.lastvalue", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(1, label.String("A", "B"))
// last value wins
result.Observe(-1, label.String("A", "B"))
result.Observe(-1, label.String("C", "D"))
})
_ = Must(meter).NewInt64ValueObserver("int.valueobserver.lastvalue", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter).NewInt64ValueObserver("int.valueobserver.lastvalue", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(-1, label.String("A", "B"))
result.Observe(1)
// last value wins
@ -314,12 +314,12 @@ func TestObserverCollection(t *testing.T) {
result.Observe(1)
})
_ = Must(meter).NewFloat64SumObserver("float.sumobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) {
_ = Must(meter).NewFloat64SumObserver("float.sumobserver.sum", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(1, label.String("A", "B"))
result.Observe(2, label.String("A", "B"))
result.Observe(1, label.String("C", "D"))
})
_ = Must(meter).NewInt64SumObserver("int.sumobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter).NewInt64SumObserver("int.sumobserver.sum", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(2, label.String("A", "B"))
result.Observe(1)
// last value wins
@ -327,12 +327,12 @@ func TestObserverCollection(t *testing.T) {
result.Observe(1)
})
_ = Must(meter).NewFloat64UpDownSumObserver("float.updownsumobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) {
_ = Must(meter).NewFloat64UpDownSumObserver("float.updownsumobserver.sum", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(1, label.String("A", "B"))
result.Observe(-2, label.String("A", "B"))
result.Observe(1, label.String("C", "D"))
})
_ = Must(meter).NewInt64UpDownSumObserver("int.updownsumobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter).NewInt64UpDownSumObserver("int.updownsumobserver.sum", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(2, label.String("A", "B"))
result.Observe(1)
// last value wins
@ -340,7 +340,7 @@ func TestObserverCollection(t *testing.T) {
result.Observe(-1)
})
_ = Must(meter).NewInt64ValueObserver("empty.valueobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter).NewInt64ValueObserver("empty.valueobserver.sum", func(_ context.Context, result otel.Int64ObserverResult) {
})
collected := sdk.Collect(ctx)
@ -374,13 +374,13 @@ func TestSumObserverInputRange(t *testing.T) {
meter, sdk, processor := newSDK(t)
// TODO: these tests are testing for negative values, not for _descending values_. Fix.
_ = Must(meter).NewFloat64SumObserver("float.sumobserver.sum", func(_ context.Context, result metric.Float64ObserverResult) {
_ = Must(meter).NewFloat64SumObserver("float.sumobserver.sum", func(_ context.Context, result otel.Float64ObserverResult) {
result.Observe(-2, label.String("A", "B"))
require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush())
result.Observe(-1, label.String("C", "D"))
require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush())
})
_ = Must(meter).NewInt64SumObserver("int.sumobserver.sum", func(_ context.Context, result metric.Int64ObserverResult) {
_ = Must(meter).NewInt64SumObserver("int.sumobserver.sum", func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(-1, label.String("A", "B"))
require.Equal(t, aggregation.ErrNegativeInput, testHandler.Flush())
result.Observe(-1)
@ -400,15 +400,15 @@ func TestObserverBatch(t *testing.T) {
ctx := context.Background()
meter, sdk, processor := newSDK(t)
var floatValueObs metric.Float64ValueObserver
var intValueObs metric.Int64ValueObserver
var floatSumObs metric.Float64SumObserver
var intSumObs metric.Int64SumObserver
var floatUpDownSumObs metric.Float64UpDownSumObserver
var intUpDownSumObs metric.Int64UpDownSumObserver
var floatValueObs otel.Float64ValueObserver
var intValueObs otel.Int64ValueObserver
var floatSumObs otel.Float64SumObserver
var intSumObs otel.Int64SumObserver
var floatUpDownSumObs otel.Float64UpDownSumObserver
var intUpDownSumObs otel.Int64UpDownSumObserver
var batch = Must(meter).NewBatchObserver(
func(_ context.Context, result metric.BatchObserverResult) {
func(_ context.Context, result otel.BatchObserverResult) {
result.Observe(
[]label.KeyValue{
label.String("A", "B"),
@ -530,15 +530,15 @@ func TestRecordPersistence(t *testing.T) {
func TestIncorrectInstruments(t *testing.T) {
// The Batch observe/record APIs are susceptible to
// uninitialized instruments.
var counter metric.Int64Counter
var observer metric.Int64ValueObserver
var counter otel.Int64Counter
var observer otel.Int64ValueObserver
ctx := context.Background()
meter, sdk, _ := newSDK(t)
// Now try with uninitialized instruments.
meter.RecordBatch(ctx, nil, counter.Measurement(1))
meter.NewBatchObserver(func(_ context.Context, result metric.BatchObserverResult) {
meter.NewBatchObserver(func(_ context.Context, result otel.BatchObserverResult) {
result.Observe(nil, observer.Observation(1))
})
@ -547,14 +547,14 @@ func TestIncorrectInstruments(t *testing.T) {
require.Equal(t, 0, collected)
// Now try with instruments from another SDK.
var noopMeter metric.Meter
counter = metric.Must(noopMeter).NewInt64Counter("name.sum")
observer = metric.Must(noopMeter).NewBatchObserver(
func(context.Context, metric.BatchObserverResult) {},
var noopMeter otel.Meter
counter = otel.Must(noopMeter).NewInt64Counter("name.sum")
observer = otel.Must(noopMeter).NewBatchObserver(
func(context.Context, otel.BatchObserverResult) {},
).NewInt64ValueObserver("observer")
meter.RecordBatch(ctx, nil, counter.Measurement(1))
meter.NewBatchObserver(func(_ context.Context, result metric.BatchObserverResult) {
meter.NewBatchObserver(func(_ context.Context, result otel.BatchObserverResult) {
result.Observe(nil, observer.Observation(1))
})
@ -569,7 +569,7 @@ func TestSyncInAsync(t *testing.T) {
counter := Must(meter).NewFloat64Counter("counter.sum")
_ = Must(meter).NewInt64ValueObserver("observer.lastvalue",
func(ctx context.Context, result metric.Int64ObserverResult) {
func(ctx context.Context, result otel.Int64ObserverResult) {
result.Observe(10)
counter.Add(ctx, 100)
},

View File

@ -22,12 +22,12 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
)
func TestStressInt64Histogram(t *testing.T) {
desc := metric.NewDescriptor("some_metric", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
alloc := histogram.New(2, &desc, []float64{25, 50, 75})
h, ckpt := &alloc[0], &alloc[1]
@ -41,7 +41,7 @@ func TestStressInt64Histogram(t *testing.T) {
case <-ctx.Done():
return
default:
_ = h.Update(ctx, metric.NewInt64Number(rnd.Int63()%100), &desc)
_ = h.Update(ctx, otel.NewInt64Number(rnd.Int63()%100), &desc)
}
}
}()

View File

@ -20,12 +20,12 @@ import (
"testing"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
)
func TestStressInt64MinMaxSumCount(t *testing.T) {
desc := metric.NewDescriptor("some_metric", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("some_metric", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
alloc := minmaxsumcount.New(2, &desc)
mmsc, ckpt := &alloc[0], &alloc[1]
@ -39,7 +39,7 @@ func TestStressInt64MinMaxSumCount(t *testing.T) {
case <-ctx.Done():
return
default:
_ = mmsc.Update(ctx, metric.NewInt64Number(v), &desc)
_ = mmsc.Update(ctx, otel.NewInt64Number(v), &desc)
}
v++
}

View File

@ -20,7 +20,7 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -41,13 +41,13 @@ type (
// data for the same instrument with the same
// resources, and this code has logic to combine data
// properly from multiple accumulators. However, the
// use of *metric.Descriptor in the stateKey makes
// use of *otel.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 *otel.Descriptor
distinct label.Distinct
resource label.Distinct
}

View File

@ -24,7 +24,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -40,10 +40,10 @@ func TestProcessor(t *testing.T) {
kind export.ExportKind
}
type instrumentCase struct {
kind metric.InstrumentKind
kind otel.InstrumentKind
}
type numberCase struct {
kind metric.NumberKind
kind otel.NumberKind
}
type aggregatorCase struct {
kind aggregation.Kind
@ -56,17 +56,17 @@ func TestProcessor(t *testing.T) {
} {
t.Run(tc.kind.String(), func(t *testing.T) {
for _, ic := range []instrumentCase{
{kind: metric.CounterInstrumentKind},
{kind: metric.UpDownCounterInstrumentKind},
{kind: metric.ValueRecorderInstrumentKind},
{kind: metric.SumObserverInstrumentKind},
{kind: metric.UpDownSumObserverInstrumentKind},
{kind: metric.ValueObserverInstrumentKind},
{kind: otel.CounterInstrumentKind},
{kind: otel.UpDownCounterInstrumentKind},
{kind: otel.ValueRecorderInstrumentKind},
{kind: otel.SumObserverInstrumentKind},
{kind: otel.UpDownSumObserverInstrumentKind},
{kind: otel.ValueObserverInstrumentKind},
} {
t.Run(ic.kind.String(), func(t *testing.T) {
for _, nc := range []numberCase{
{kind: metric.Int64NumberKind},
{kind: metric.Float64NumberKind},
{kind: otel.Int64NumberKind},
{kind: otel.Float64NumberKind},
} {
t.Run(nc.kind.String(), func(t *testing.T) {
for _, ac := range []aggregatorCase{
@ -95,14 +95,14 @@ func TestProcessor(t *testing.T) {
}
}
func asNumber(nkind metric.NumberKind, value int64) metric.Number {
if nkind == metric.Int64NumberKind {
return metric.NewInt64Number(value)
func asNumber(nkind otel.NumberKind, value int64) otel.Number {
if nkind == otel.Int64NumberKind {
return otel.NewInt64Number(value)
}
return metric.NewFloat64Number(float64(value))
return otel.NewFloat64Number(float64(value))
}
func updateFor(t *testing.T, desc *metric.Descriptor, selector export.AggregatorSelector, res *resource.Resource, value int64, labs ...label.KeyValue) export.Accumulation {
func updateFor(t *testing.T, desc *otel.Descriptor, selector export.AggregatorSelector, res *resource.Resource, value int64, labs ...label.KeyValue) export.Accumulation {
ls := label.NewSet(labs...)
var agg export.Aggregator
selector.AggregatorFor(desc, &agg)
@ -114,8 +114,8 @@ func updateFor(t *testing.T, desc *metric.Descriptor, selector export.Aggregator
func testProcessor(
t *testing.T,
ekind export.ExportKind,
mkind metric.InstrumentKind,
nkind metric.NumberKind,
mkind otel.InstrumentKind,
nkind otel.NumberKind,
akind aggregation.Kind,
) {
// Note: this selector uses the instrument name to dictate
@ -131,8 +131,8 @@ func testProcessor(
instSuffix := fmt.Sprint(".", strings.ToLower(akind.String()))
desc1 := metric.NewDescriptor(fmt.Sprint("inst1", instSuffix), mkind, nkind)
desc2 := metric.NewDescriptor(fmt.Sprint("inst2", instSuffix), mkind, nkind)
desc1 := otel.NewDescriptor(fmt.Sprint("inst1", instSuffix), mkind, nkind)
desc2 := otel.NewDescriptor(fmt.Sprint("inst2", instSuffix), mkind, nkind)
for nc := 0; nc < nCheckpoint; nc++ {
@ -258,7 +258,7 @@ func testProcessor(
type bogusExporter struct{}
func (bogusExporter) ExportKindFor(*metric.Descriptor, aggregation.Kind) export.ExportKind {
func (bogusExporter) ExportKindFor(*otel.Descriptor, aggregation.Kind) export.ExportKind {
return 1000000
}
@ -295,7 +295,7 @@ func TestBasicInconsistent(t *testing.T) {
// Test no start
b = basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
desc := metric.NewDescriptor("inst", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
accum := export.NewAccumulation(&desc, label.EmptySet(), resource.Empty(), metrictest.NoopAggregator{})
require.Equal(t, basic.ErrInconsistentState, b.Process(accum))
@ -318,7 +318,7 @@ func TestBasicTimestamps(t *testing.T) {
b := basic.New(processorTest.AggregatorSelector(), export.PassThroughExporter)
afterNew := time.Now()
desc := metric.NewDescriptor("inst", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("inst", otel.CounterInstrumentKind, otel.Int64NumberKind)
accum := export.NewAccumulation(&desc, label.EmptySet(), resource.Empty(), metrictest.NoopAggregator{})
b.StartCollection()
@ -364,7 +364,7 @@ func TestStatefulNoMemoryCumulative(t *testing.T) {
res := resource.New(label.String("R", "V"))
ekind := export.CumulativeExporter
desc := metric.NewDescriptor("inst.sum", metric.CounterInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("inst.sum", otel.CounterInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))
@ -398,7 +398,7 @@ func TestStatefulNoMemoryDelta(t *testing.T) {
res := resource.New(label.String("R", "V"))
ekind := export.DeltaExporter
desc := metric.NewDescriptor("inst.sum", metric.SumObserverInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("inst.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))
@ -436,7 +436,7 @@ func TestMultiObserverSum(t *testing.T) {
} {
res := resource.New(label.String("R", "V"))
desc := metric.NewDescriptor("observe.sum", metric.SumObserverInstrumentKind, metric.Int64NumberKind)
desc := otel.NewDescriptor("observe.sum", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
selector := processorTest.AggregatorSelector()
processor := basic.New(selector, ekind, basic.WithMemory(false))

View File

@ -21,7 +21,7 @@ import (
"sync"
"time"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -39,7 +39,7 @@ type (
// unique descriptor, distinct labels, and distinct resource
// attributes.
mapKey struct {
desc *metric.Descriptor
desc *otel.Descriptor
labels label.Distinct
resource label.Distinct
}
@ -161,7 +161,7 @@ func AggregatorSelector() export.AggregatorSelector {
}
// AggregatorFor implements export.AggregatorSelector.
func (testAggregatorSelector) AggregatorFor(desc *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (testAggregatorSelector) AggregatorFor(desc *otel.Descriptor, aggPtrs ...*export.Aggregator) {
switch {
case strings.HasSuffix(desc.Name(), ".disabled"):

View File

@ -20,7 +20,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
metricsdk "go.opentelemetry.io/otel/sdk/metric"
@ -36,12 +36,12 @@ func generateTestData(proc export.Processor) {
resource.New(label.String("R", "V")),
),
)
meter := metric.WrapMeterImpl(accum, "testing")
meter := otel.WrapMeterImpl(accum, "testing")
counter := metric.Must(meter).NewFloat64Counter("counter.sum")
counter := otel.Must(meter).NewFloat64Counter("counter.sum")
_ = metric.Must(meter).NewInt64SumObserver("observer.sum",
func(_ context.Context, result metric.Int64ObserverResult) {
_ = otel.Must(meter).NewInt64SumObserver("observer.sum",
func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(10, label.String("K1", "V1"))
result.Observe(11, label.String("K1", "V2"))
},

View File

@ -15,7 +15,7 @@
package reducer // import "go.opentelemetry.io/otel/sdk/metric/processor/reducer"
import (
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
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) label.Filter
LabelFilterFor(descriptor *otel.Descriptor) label.Filter
}
)

View File

@ -20,7 +20,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
metricsdk "go.opentelemetry.io/otel/sdk/metric"
@ -45,20 +45,20 @@ var (
type testFilter struct{}
func (testFilter) LabelFilterFor(_ *metric.Descriptor) label.Filter {
func (testFilter) LabelFilterFor(_ *otel.Descriptor) label.Filter {
return func(label label.KeyValue) bool {
return label.Key == "A" || label.Key == "C"
}
}
func generateData(impl metric.MeterImpl) {
func generateData(impl otel.MeterImpl) {
ctx := context.Background()
meter := metric.WrapMeterImpl(impl, "testing")
meter := otel.WrapMeterImpl(impl, "testing")
counter := metric.Must(meter).NewFloat64Counter("counter.sum")
counter := otel.Must(meter).NewFloat64Counter("counter.sum")
_ = metric.Must(meter).NewInt64SumObserver("observer.sum",
func(_ context.Context, result metric.Int64ObserverResult) {
_ = otel.Must(meter).NewInt64SumObserver("observer.sum",
func(_ context.Context, result otel.Int64ObserverResult) {
result.Observe(10, kvs1...)
result.Observe(10, kvs2...)
},

View File

@ -21,9 +21,9 @@ import (
"sync"
"sync/atomic"
"go.opentelemetry.io/otel"
api "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/metric"
api "go.opentelemetry.io/otel/api/metric"
internal "go.opentelemetry.io/otel/internal/metric"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
@ -76,7 +76,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 *otel.Descriptor
ordered label.Distinct
}
@ -124,7 +124,7 @@ type (
instrument struct {
meter *Accumulator
descriptor metric.Descriptor
descriptor otel.Descriptor
}
asyncInstrument struct {
@ -329,7 +329,7 @@ func (m *Accumulator) NewSyncInstrument(descriptor api.Descriptor) (api.SyncImpl
}
// NewAsyncInstrument implements api.MetricImpl.
func (m *Accumulator) NewAsyncInstrument(descriptor api.Descriptor, runner metric.AsyncRunner) (api.AsyncImpl, error) {
func (m *Accumulator) NewAsyncInstrument(descriptor api.Descriptor, runner otel.AsyncRunner) (api.AsyncImpl, error) {
a := &asyncInstrument{
instrument: instrument{
descriptor: descriptor,
@ -405,7 +405,7 @@ func (m *Accumulator) collectSyncInstruments() int {
}
// CollectAsync implements internal.AsyncCollector.
func (m *Accumulator) CollectAsync(kv []label.KeyValue, obs ...metric.Observation) {
func (m *Accumulator) CollectAsync(kv []label.KeyValue, obs ...otel.Observation) {
labels := label.NewSetWithSortable(kv, &m.asyncSortSlice)
for _, ob := range obs {
@ -538,7 +538,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 otel.SyncImpl) *syncInstrument {
if sync != nil {
if inst, ok := sync.Implementation().(*syncInstrument); ok {
return inst
@ -550,7 +550,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 otel.AsyncImpl) *asyncInstrument {
if async != nil {
if inst, ok := async.Implementation().(*asyncInstrument); ok {
return inst

View File

@ -15,7 +15,7 @@
package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
import (
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
@ -94,11 +94,11 @@ func lastValueAggs(aggPtrs []*export.Aggregator) {
}
}
func (selectorInexpensive) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (selectorInexpensive) AggregatorFor(descriptor *otel.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() {
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
lastValueAggs(aggPtrs)
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
aggs := minmaxsumcount.New(len(aggPtrs), descriptor)
for i := range aggPtrs {
*aggPtrs[i] = &aggs[i]
@ -108,11 +108,11 @@ func (selectorInexpensive) AggregatorFor(descriptor *metric.Descriptor, aggPtrs
}
}
func (s selectorSketch) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (s selectorSketch) AggregatorFor(descriptor *otel.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() {
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
lastValueAggs(aggPtrs)
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
aggs := ddsketch.New(len(aggPtrs), descriptor, s.config)
for i := range aggPtrs {
*aggPtrs[i] = &aggs[i]
@ -122,11 +122,11 @@ func (s selectorSketch) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...
}
}
func (selectorExact) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (selectorExact) AggregatorFor(descriptor *otel.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() {
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
lastValueAggs(aggPtrs)
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
aggs := array.New(len(aggPtrs))
for i := range aggPtrs {
*aggPtrs[i] = &aggs[i]
@ -136,11 +136,11 @@ func (selectorExact) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*ex
}
}
func (s selectorHistogram) AggregatorFor(descriptor *metric.Descriptor, aggPtrs ...*export.Aggregator) {
func (s selectorHistogram) AggregatorFor(descriptor *otel.Descriptor, aggPtrs ...*export.Aggregator) {
switch descriptor.InstrumentKind() {
case metric.ValueObserverInstrumentKind:
case otel.ValueObserverInstrumentKind:
lastValueAggs(aggPtrs)
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
aggs := histogram.New(len(aggPtrs), descriptor, s.boundaries)
for i := range aggPtrs {
*aggPtrs[i] = &aggs[i]

View File

@ -19,7 +19,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/array"
"go.opentelemetry.io/otel/sdk/metric/aggregator/ddsketch"
@ -31,15 +31,15 @@ import (
)
var (
testCounterDesc = metric.NewDescriptor("counter", metric.CounterInstrumentKind, metric.Int64NumberKind)
testUpDownCounterDesc = metric.NewDescriptor("updowncounter", metric.UpDownCounterInstrumentKind, metric.Int64NumberKind)
testSumObserverDesc = metric.NewDescriptor("sumobserver", metric.SumObserverInstrumentKind, metric.Int64NumberKind)
testUpDownSumObserverDesc = metric.NewDescriptor("updownsumobserver", metric.UpDownSumObserverInstrumentKind, metric.Int64NumberKind)
testValueRecorderDesc = metric.NewDescriptor("valuerecorder", metric.ValueRecorderInstrumentKind, metric.Int64NumberKind)
testValueObserverDesc = metric.NewDescriptor("valueobserver", metric.ValueObserverInstrumentKind, metric.Int64NumberKind)
testCounterDesc = otel.NewDescriptor("counter", otel.CounterInstrumentKind, otel.Int64NumberKind)
testUpDownCounterDesc = otel.NewDescriptor("updowncounter", otel.UpDownCounterInstrumentKind, otel.Int64NumberKind)
testSumObserverDesc = otel.NewDescriptor("sumobserver", otel.SumObserverInstrumentKind, otel.Int64NumberKind)
testUpDownSumObserverDesc = otel.NewDescriptor("updownsumobserver", otel.UpDownSumObserverInstrumentKind, otel.Int64NumberKind)
testValueRecorderDesc = otel.NewDescriptor("valuerecorder", otel.ValueRecorderInstrumentKind, otel.Int64NumberKind)
testValueObserverDesc = otel.NewDescriptor("valueobserver", otel.ValueObserverInstrumentKind, otel.Int64NumberKind)
)
func oneAgg(sel export.AggregatorSelector, desc *metric.Descriptor) export.Aggregator {
func oneAgg(sel export.AggregatorSelector, desc *otel.Descriptor) export.Aggregator {
var agg export.Aggregator
sel.AggregatorFor(desc, &agg)
return agg

View File

@ -31,8 +31,7 @@ import (
"testing"
"time"
"go.opentelemetry.io/otel/api/metric"
api "go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
@ -46,7 +45,7 @@ const (
epsilon = 1e-10
)
var Must = api.Must
var Must = otel.Must
type (
testFixture struct {
@ -69,26 +68,26 @@ type (
testKey struct {
labels string
descriptor *metric.Descriptor
descriptor *otel.Descriptor
}
testImpl struct {
newInstrument func(meter api.Meter, name string) SyncImpler
getUpdateValue func() api.Number
operate func(interface{}, context.Context, api.Number, []label.KeyValue)
newInstrument func(meter otel.Meter, name string) SyncImpler
getUpdateValue func() otel.Number
operate func(interface{}, context.Context, otel.Number, []label.KeyValue)
newStore func() interface{}
// storeCollect and storeExpect are the same for
// counters, different for lastValues, to ensure we are
// testing the timestamps correctly.
storeCollect func(store interface{}, value api.Number, ts time.Time)
storeExpect func(store interface{}, value api.Number)
readStore func(store interface{}) api.Number
equalValues func(a, b api.Number) bool
storeCollect func(store interface{}, value otel.Number, ts time.Time)
storeExpect func(store interface{}, value otel.Number)
readStore func(store interface{}) otel.Number
equalValues func(a, b otel.Number) bool
}
SyncImpler interface {
SyncImpl() metric.SyncImpl
SyncImpl() otel.SyncImpl
}
// lastValueState supports merging lastValue values, for the case
@ -96,7 +95,7 @@ type (
// take the later timestamp.
lastValueState struct {
// raw has to be aligned for 64-bit atomic operations.
raw api.Number
raw otel.Number
ts time.Time
}
)
@ -157,11 +156,11 @@ func (f *testFixture) someLabels() []label.KeyValue {
}
}
func (f *testFixture) startWorker(impl *Accumulator, meter api.Meter, wg *sync.WaitGroup, i int) {
func (f *testFixture) startWorker(impl *Accumulator, meter otel.Meter, wg *sync.WaitGroup, i int) {
ctx := context.Background()
name := fmt.Sprint("test_", i)
instrument := f.impl.newInstrument(meter, name)
var descriptor *metric.Descriptor
var descriptor *otel.Descriptor
if ii, ok := instrument.SyncImpl().(*syncInstrument); ok {
descriptor = &ii.descriptor
}
@ -265,13 +264,13 @@ func (f *testFixture) Process(accumulation export.Accumulation) error {
agg := accumulation.Aggregator()
switch accumulation.Descriptor().InstrumentKind() {
case metric.CounterInstrumentKind:
case otel.CounterInstrumentKind:
sum, err := agg.(aggregation.Sum).Sum()
if err != nil {
f.T.Fatal("Sum error: ", err)
}
f.impl.storeCollect(actual, sum, time.Time{})
case metric.ValueRecorderInstrumentKind:
case otel.ValueRecorderInstrumentKind:
lv, ts, err := agg.(aggregation.LastValue).LastValue()
if err != nil && err != aggregation.ErrNoData {
f.T.Fatal("Last value error: ", err)
@ -294,7 +293,7 @@ func stressTest(t *testing.T, impl testImpl) {
}
cc := concurrency()
sdk := NewAccumulator(fixture)
meter := metric.WrapMeterImpl(sdk, "stress_test")
meter := otel.WrapMeterImpl(sdk, "stress_test")
fixture.wg.Add(cc + 1)
for i := 0; i < cc; i++ {
@ -326,11 +325,11 @@ func stressTest(t *testing.T, impl testImpl) {
fixture.assertTest(numCollect)
}
func int64sEqual(a, b api.Number) bool {
func int64sEqual(a, b otel.Number) bool {
return a.AsInt64() == b.AsInt64()
}
func float64sEqual(a, b api.Number) bool {
func float64sEqual(a, b otel.Number) bool {
diff := math.Abs(a.AsFloat64() - b.AsFloat64())
return diff < math.Abs(a.AsFloat64())*epsilon
}
@ -339,33 +338,33 @@ func float64sEqual(a, b api.Number) bool {
func intCounterTestImpl() testImpl {
return testImpl{
newInstrument: func(meter api.Meter, name string) SyncImpler {
newInstrument: func(meter otel.Meter, name string) SyncImpler {
return Must(meter).NewInt64Counter(name + ".sum")
},
getUpdateValue: func() api.Number {
getUpdateValue: func() otel.Number {
for {
x := int64(rand.Intn(100))
if x != 0 {
return api.NewInt64Number(x)
return otel.NewInt64Number(x)
}
}
},
operate: func(inst interface{}, ctx context.Context, value api.Number, labels []label.KeyValue) {
counter := inst.(api.Int64Counter)
operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
counter := inst.(otel.Int64Counter)
counter.Add(ctx, value.AsInt64(), labels...)
},
newStore: func() interface{} {
n := api.NewInt64Number(0)
n := otel.NewInt64Number(0)
return &n
},
storeCollect: func(store interface{}, value api.Number, _ time.Time) {
store.(*api.Number).AddInt64Atomic(value.AsInt64())
storeCollect: func(store interface{}, value otel.Number, _ time.Time) {
store.(*otel.Number).AddInt64Atomic(value.AsInt64())
},
storeExpect: func(store interface{}, value api.Number) {
store.(*api.Number).AddInt64Atomic(value.AsInt64())
storeExpect: func(store interface{}, value otel.Number) {
store.(*otel.Number).AddInt64Atomic(value.AsInt64())
},
readStore: func(store interface{}) api.Number {
return store.(*api.Number).AsNumberAtomic()
readStore: func(store interface{}) otel.Number {
return store.(*otel.Number).AsNumberAtomic()
},
equalValues: int64sEqual,
}
@ -377,33 +376,33 @@ func TestStressInt64Counter(t *testing.T) {
func floatCounterTestImpl() testImpl {
return testImpl{
newInstrument: func(meter api.Meter, name string) SyncImpler {
newInstrument: func(meter otel.Meter, name string) SyncImpler {
return Must(meter).NewFloat64Counter(name + ".sum")
},
getUpdateValue: func() api.Number {
getUpdateValue: func() otel.Number {
for {
x := rand.Float64()
if x != 0 {
return api.NewFloat64Number(x)
return otel.NewFloat64Number(x)
}
}
},
operate: func(inst interface{}, ctx context.Context, value api.Number, labels []label.KeyValue) {
counter := inst.(api.Float64Counter)
operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
counter := inst.(otel.Float64Counter)
counter.Add(ctx, value.AsFloat64(), labels...)
},
newStore: func() interface{} {
n := api.NewFloat64Number(0.0)
n := otel.NewFloat64Number(0.0)
return &n
},
storeCollect: func(store interface{}, value api.Number, _ time.Time) {
store.(*api.Number).AddFloat64Atomic(value.AsFloat64())
storeCollect: func(store interface{}, value otel.Number, _ time.Time) {
store.(*otel.Number).AddFloat64Atomic(value.AsFloat64())
},
storeExpect: func(store interface{}, value api.Number) {
store.(*api.Number).AddFloat64Atomic(value.AsFloat64())
storeExpect: func(store interface{}, value otel.Number) {
store.(*otel.Number).AddFloat64Atomic(value.AsFloat64())
},
readStore: func(store interface{}) api.Number {
return store.(*api.Number).AsNumberAtomic()
readStore: func(store interface{}) otel.Number {
return store.(*otel.Number).AsNumberAtomic()
},
equalValues: float64sEqual,
}
@ -417,23 +416,23 @@ func TestStressFloat64Counter(t *testing.T) {
func intLastValueTestImpl() testImpl {
return testImpl{
newInstrument: func(meter api.Meter, name string) SyncImpler {
newInstrument: func(meter otel.Meter, name string) SyncImpler {
return Must(meter).NewInt64ValueRecorder(name + ".lastvalue")
},
getUpdateValue: func() api.Number {
getUpdateValue: func() otel.Number {
r1 := rand.Int63()
return api.NewInt64Number(rand.Int63() - r1)
return otel.NewInt64Number(rand.Int63() - r1)
},
operate: func(inst interface{}, ctx context.Context, value api.Number, labels []label.KeyValue) {
valuerecorder := inst.(api.Int64ValueRecorder)
operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
valuerecorder := inst.(otel.Int64ValueRecorder)
valuerecorder.Record(ctx, value.AsInt64(), labels...)
},
newStore: func() interface{} {
return &lastValueState{
raw: api.NewInt64Number(0),
raw: otel.NewInt64Number(0),
}
},
storeCollect: func(store interface{}, value api.Number, ts time.Time) {
storeCollect: func(store interface{}, value otel.Number, ts time.Time) {
gs := store.(*lastValueState)
if !ts.Before(gs.ts) {
@ -441,11 +440,11 @@ func intLastValueTestImpl() testImpl {
gs.raw.SetInt64Atomic(value.AsInt64())
}
},
storeExpect: func(store interface{}, value api.Number) {
storeExpect: func(store interface{}, value otel.Number) {
gs := store.(*lastValueState)
gs.raw.SetInt64Atomic(value.AsInt64())
},
readStore: func(store interface{}) api.Number {
readStore: func(store interface{}) otel.Number {
gs := store.(*lastValueState)
return gs.raw.AsNumberAtomic()
},
@ -459,22 +458,22 @@ func TestStressInt64LastValue(t *testing.T) {
func floatLastValueTestImpl() testImpl {
return testImpl{
newInstrument: func(meter api.Meter, name string) SyncImpler {
newInstrument: func(meter otel.Meter, name string) SyncImpler {
return Must(meter).NewFloat64ValueRecorder(name + ".lastvalue")
},
getUpdateValue: func() api.Number {
return api.NewFloat64Number((-0.5 + rand.Float64()) * 100000)
getUpdateValue: func() otel.Number {
return otel.NewFloat64Number((-0.5 + rand.Float64()) * 100000)
},
operate: func(inst interface{}, ctx context.Context, value api.Number, labels []label.KeyValue) {
valuerecorder := inst.(api.Float64ValueRecorder)
operate: func(inst interface{}, ctx context.Context, value otel.Number, labels []label.KeyValue) {
valuerecorder := inst.(otel.Float64ValueRecorder)
valuerecorder.Record(ctx, value.AsFloat64(), labels...)
},
newStore: func() interface{} {
return &lastValueState{
raw: api.NewFloat64Number(0),
raw: otel.NewFloat64Number(0),
}
},
storeCollect: func(store interface{}, value api.Number, ts time.Time) {
storeCollect: func(store interface{}, value otel.Number, ts time.Time) {
gs := store.(*lastValueState)
if !ts.Before(gs.ts) {
@ -482,11 +481,11 @@ func floatLastValueTestImpl() testImpl {
gs.raw.SetFloat64Atomic(value.AsFloat64())
}
},
storeExpect: func(store interface{}, value api.Number) {
storeExpect: func(store interface{}, value otel.Number) {
gs := store.(*lastValueState)
gs.raw.SetFloat64Atomic(value.AsFloat64())
},
readStore: func(store interface{}) api.Number {
readStore: func(store interface{}) otel.Number {
gs := store.(*lastValueState)
return gs.raw.AsNumberAtomic()
},