mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-01-26 03:52:03 +02:00
Remove the unneeded Observe method from the async instruments (#3586)
* Update RegisterCallback and Callback decls RegisterCallback accept variadic Asynchronous instruments instead of a slice. Callback accept an observation result recorder to ensure instruments that are observed by a callback. * Update global impl * Update noop impl * Update SDK impl * Fix prometheus example * Fix metric API example_test * Remove unused registerabler * Rename ObservationRecorder to MultiObserver * Update Callback documentation about MultiObserver * Remove the Observe method from async inst * Revert to iface for Observers * Fix async inst docs * Update global async delegate race test * Restore removed observe doc * Remove TODO * Remove stale comment * Update changelog
This commit is contained in:
parent
c7e2679529
commit
c0fb8dec4c
@ -36,7 +36,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
- Add the `go.opentelemetry.io/otel/semconv/v1.16.0` package.
|
||||
The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579)
|
||||
- Metric instruments were added to `go.opentelemetry.io/otel/metric/instrument`.
|
||||
These instruments are use as replacements of the depreacted `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575)
|
||||
These instruments are use as replacements of the depreacted `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)
|
||||
- `Float64ObservableCounter` replaces the `asyncfloat64.Counter`
|
||||
- `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter`
|
||||
- `Float64ObservableGauge` replaces the `asyncfloat64.Gauge`
|
||||
|
@ -55,7 +55,7 @@ func ExampleMeter_asynchronous_single() {
|
||||
_, err := meter.Int64ObservableGauge(
|
||||
"DiskUsage",
|
||||
instrument.WithUnit(unit.Bytes),
|
||||
instrument.WithInt64Callback(func(ctx context.Context, inst instrument.Int64Observer) error {
|
||||
instrument.WithInt64Callback(func(_ context.Context, obsrv instrument.Int64Observer) error {
|
||||
// Do the real work here to get the real disk usage. For example,
|
||||
//
|
||||
// usage, err := GetDiskUsage(diskID)
|
||||
@ -69,7 +69,7 @@ func ExampleMeter_asynchronous_single() {
|
||||
//
|
||||
// For demonstration purpose, a static value is used here.
|
||||
usage := 75000
|
||||
inst.Observe(ctx, int64(usage), attribute.Int("disk.id", 3))
|
||||
obsrv.Observe(int64(usage), attribute.Int("disk.id", 3))
|
||||
return nil
|
||||
}),
|
||||
)
|
||||
|
@ -21,45 +21,51 @@ import (
|
||||
"go.opentelemetry.io/otel/metric/unit"
|
||||
)
|
||||
|
||||
// Float64Observer is a recorder of float64 measurement values.
|
||||
// Float64Observable describes a set of instruments used asynchronously to
|
||||
// record float64 measurements once per collection cycle. Observations of
|
||||
// these instruments are only made within a callback.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Float64Observer interface {
|
||||
type Float64Observable interface {
|
||||
Asynchronous
|
||||
|
||||
// Observe records the measurement value for a set of attributes.
|
||||
//
|
||||
// It is only valid to call this within a callback. If called outside of
|
||||
// the registered callback it should have no effect on the instrument, and
|
||||
// an error will be reported via the error handler.
|
||||
Observe(ctx context.Context, value float64, attributes ...attribute.KeyValue)
|
||||
float64Observable()
|
||||
}
|
||||
|
||||
// Float64ObservableCounter is an instrument used to asynchronously record
|
||||
// increasing float64 measurements once per a measurement collection cycle. The
|
||||
// Observe method is used to record the measured state of the instrument when
|
||||
// it is called. Implementations will assume the observed value to be the
|
||||
// cumulative sum of the count.
|
||||
// increasing float64 measurements once per collection cycle. Observations are
|
||||
// only made within a callback for this instrument. The value observed is
|
||||
// assumed the to be the cumulative sum of the count.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Float64ObservableCounter interface{ Float64Observer }
|
||||
type Float64ObservableCounter interface{ Float64Observable }
|
||||
|
||||
// Float64ObservableUpDownCounter is an instrument used to asynchronously
|
||||
// record float64 measurements once per a measurement collection cycle. The
|
||||
// Observe method is used to record the measured state of the instrument when
|
||||
// it is called. Implementations will assume the observed value to be the
|
||||
// cumulative sum of the count.
|
||||
// record float64 measurements once per collection cycle. Observations are only
|
||||
// made within a callback for this instrument. The value observed is assumed
|
||||
// the to be the cumulative sum of the count.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Float64ObservableUpDownCounter interface{ Float64Observer }
|
||||
type Float64ObservableUpDownCounter interface{ Float64Observable }
|
||||
|
||||
// Float64ObservableGauge is an instrument used to asynchronously record
|
||||
// instantaneous float64 measurements once per a measurement collection cycle.
|
||||
// instantaneous float64 measurements once per collection cycle. Observations
|
||||
// are only made within a callback for this instrument.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Float64ObservableGauge interface{ Float64Observer }
|
||||
type Float64ObservableGauge interface{ Float64Observable }
|
||||
|
||||
// Float64Observer is a recorder of float64 measurements.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Float64Observer interface {
|
||||
Observe(value float64, attributes ...attribute.KeyValue)
|
||||
}
|
||||
|
||||
// Float64Callback is a function registered with a Meter that makes
|
||||
// observations for a Float64Observer it is registered with.
|
||||
// observations for a Float64Observerable instrument it is registered with.
|
||||
// Calls to the Float64Observer record measurement values for the
|
||||
// Float64Observable.
|
||||
//
|
||||
// The function needs to complete in a finite amount of time and the deadline
|
||||
// of the passed context is expected to be honored.
|
||||
|
@ -35,8 +35,8 @@ func TestFloat64ObserverOptions(t *testing.T) {
|
||||
got := NewFloat64ObserverConfig(
|
||||
WithDescription(desc),
|
||||
WithUnit(uBytes),
|
||||
WithFloat64Callback(func(ctx context.Context, o Float64Observer) error {
|
||||
o.Observe(ctx, token)
|
||||
WithFloat64Callback(func(ctx context.Context, obsrv Float64Observer) error {
|
||||
obsrv.Observe(token)
|
||||
return nil
|
||||
}),
|
||||
)
|
||||
@ -57,6 +57,6 @@ type float64Observer struct {
|
||||
got float64
|
||||
}
|
||||
|
||||
func (o *float64Observer) Observe(_ context.Context, v float64, _ ...attribute.KeyValue) {
|
||||
func (o *float64Observer) Observe(v float64, _ ...attribute.KeyValue) {
|
||||
o.got = v
|
||||
}
|
||||
|
@ -21,46 +21,51 @@ import (
|
||||
"go.opentelemetry.io/otel/metric/unit"
|
||||
)
|
||||
|
||||
// Int64Observer is a recorder of int64 measurement values.
|
||||
// Int64Observable describes a set of instruments used asynchronously to record
|
||||
// int64 measurements once per collection cycle. Observations of these
|
||||
// instruments are only made within a callback.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Int64Observer interface {
|
||||
type Int64Observable interface {
|
||||
Asynchronous
|
||||
|
||||
// Observe records the measurement value for a set of attributes.
|
||||
//
|
||||
// It is only valid to call this within a callback. If called outside of
|
||||
// the registered callback it should have no effect on the instrument, and
|
||||
// an error will be reported via the error handler.
|
||||
Observe(ctx context.Context, value int64, attributes ...attribute.KeyValue)
|
||||
int64Observable()
|
||||
}
|
||||
|
||||
// Int64ObservableCounter is an instrument used to asynchronously record
|
||||
// increasing int64 measurements once per a measurement collection cycle. The
|
||||
// Observe method is used to record the measured state of the instrument when
|
||||
// it is called. Implementations will assume the observed value to be the
|
||||
// cumulative sum of the count.
|
||||
// increasing int64 measurements once per collection cycle. Observations are
|
||||
// only made within a callback for this instrument. The value observed is
|
||||
// assumed the to be the cumulative sum of the count.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Int64ObservableCounter interface{ Int64Observer }
|
||||
type Int64ObservableCounter interface{ Int64Observable }
|
||||
|
||||
// Int64ObservableUpDownCounter is an instrument used to asynchronously record
|
||||
// int64 measurements once per a measurement collection cycle. The Observe
|
||||
// method is used to record the measured state of the instrument when it is
|
||||
// called. Implementations will assume the observed value to be the cumulative
|
||||
// sum of the count.
|
||||
// int64 measurements once per collection cycle. Observations are only made
|
||||
// within a callback for this instrument. The value observed is assumed the to
|
||||
// be the cumulative sum of the count.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Int64ObservableUpDownCounter interface{ Int64Observer }
|
||||
type Int64ObservableUpDownCounter interface{ Int64Observable }
|
||||
|
||||
// Int64ObservableGauge is an instrument used to asynchronously record
|
||||
// instantaneous int64 measurements once per a measurement collection cycle.
|
||||
// instantaneous int64 measurements once per collection cycle. Observations are
|
||||
// only made within a callback for this instrument.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Int64ObservableGauge interface{ Int64Observer }
|
||||
type Int64ObservableGauge interface{ Int64Observable }
|
||||
|
||||
// Int64Observer is a recorder of int64 measurements.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
type Int64Observer interface {
|
||||
Observe(value int64, attributes ...attribute.KeyValue)
|
||||
}
|
||||
|
||||
// Int64Callback is a function registered with a Meter that makes
|
||||
// observations for an Int64Observer it is registered with.
|
||||
// observations for a Int64Observerable instrument it is registered with.
|
||||
// Calls to the Int64Observer record measurement values for the
|
||||
// Int64Observable.
|
||||
//
|
||||
// The function needs to complete in a finite amount of time and the deadline
|
||||
// of the passed context is expected to be honored.
|
||||
|
@ -35,8 +35,8 @@ func TestInt64ObserverOptions(t *testing.T) {
|
||||
got := NewInt64ObserverConfig(
|
||||
WithDescription(desc),
|
||||
WithUnit(uBytes),
|
||||
WithInt64Callback(func(ctx context.Context, o Int64Observer) error {
|
||||
o.Observe(ctx, token)
|
||||
WithInt64Callback(func(_ context.Context, obsrv Int64Observer) error {
|
||||
obsrv.Observe(token)
|
||||
return nil
|
||||
}),
|
||||
)
|
||||
@ -57,6 +57,6 @@ type int64Observer struct {
|
||||
got int64
|
||||
}
|
||||
|
||||
func (o *int64Observer) Observe(_ context.Context, v int64, _ ...attribute.KeyValue) {
|
||||
func (o *int64Observer) Observe(v int64, _ ...attribute.KeyValue) {
|
||||
o.got = v
|
||||
}
|
||||
|
@ -30,12 +30,12 @@ type unwrapper interface {
|
||||
}
|
||||
|
||||
type afCounter struct {
|
||||
instrument.Float64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Float64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Float64ObservableCounter
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afCounter)(nil)
|
||||
@ -50,12 +50,6 @@ func (i *afCounter) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
func (i *afCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Float64ObservableCounter).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *afCounter) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Float64ObservableCounter)
|
||||
@ -64,12 +58,12 @@ func (i *afCounter) Unwrap() instrument.Asynchronous {
|
||||
}
|
||||
|
||||
type afUpDownCounter struct {
|
||||
instrument.Float64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Float64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Float64ObservableUpDownCounter
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afUpDownCounter)(nil)
|
||||
@ -84,12 +78,6 @@ func (i *afUpDownCounter) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
func (i *afUpDownCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Float64ObservableUpDownCounter).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *afUpDownCounter) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Float64ObservableUpDownCounter)
|
||||
@ -98,14 +86,17 @@ func (i *afUpDownCounter) Unwrap() instrument.Asynchronous {
|
||||
}
|
||||
|
||||
type afGauge struct {
|
||||
instrument.Float64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Float64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Float64ObservableGauge
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afGauge)(nil)
|
||||
var _ instrument.Float64ObservableGauge = (*afGauge)(nil)
|
||||
|
||||
func (i *afGauge) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Float64ObservableGauge(i.name, i.opts...)
|
||||
if err != nil {
|
||||
@ -115,15 +106,6 @@ func (i *afGauge) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afGauge)(nil)
|
||||
var _ instrument.Float64ObservableGauge = (*afGauge)(nil)
|
||||
|
||||
func (i *afGauge) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Float64ObservableGauge).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *afGauge) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Float64ObservableGauge)
|
||||
@ -132,12 +114,12 @@ func (i *afGauge) Unwrap() instrument.Asynchronous {
|
||||
}
|
||||
|
||||
type aiCounter struct {
|
||||
instrument.Int64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Int64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Int64ObservableCounter
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiCounter)(nil)
|
||||
@ -152,12 +134,6 @@ func (i *aiCounter) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
func (i *aiCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Int64ObservableCounter).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *aiCounter) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Int64ObservableCounter)
|
||||
@ -166,12 +142,12 @@ func (i *aiCounter) Unwrap() instrument.Asynchronous {
|
||||
}
|
||||
|
||||
type aiUpDownCounter struct {
|
||||
instrument.Int64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Int64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Int64ObservableUpDownCounter
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiUpDownCounter)(nil)
|
||||
@ -186,12 +162,6 @@ func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
func (i *aiUpDownCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Int64ObservableUpDownCounter).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *aiUpDownCounter) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Int64ObservableUpDownCounter)
|
||||
@ -200,12 +170,12 @@ func (i *aiUpDownCounter) Unwrap() instrument.Asynchronous {
|
||||
}
|
||||
|
||||
type aiGauge struct {
|
||||
instrument.Int64Observable
|
||||
|
||||
name string
|
||||
opts []instrument.Int64ObserverOption
|
||||
|
||||
delegate atomic.Value //instrument.Int64ObservableGauge
|
||||
|
||||
instrument.Asynchronous
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiGauge)(nil)
|
||||
@ -220,12 +190,6 @@ func (i *aiGauge) setDelegate(m metric.Meter) {
|
||||
i.delegate.Store(ctr)
|
||||
}
|
||||
|
||||
func (i *aiGauge) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
ctr.(instrument.Int64ObservableGauge).Observe(ctx, x, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *aiGauge) Unwrap() instrument.Asynchronous {
|
||||
if ctr := i.delegate.Load(); ctr != nil {
|
||||
return ctr.(instrument.Int64ObservableGauge)
|
||||
|
@ -62,17 +62,20 @@ func TestAsyncInstrumentSetDelegateRace(t *testing.T) {
|
||||
t.Run("Float64", func(t *testing.T) {
|
||||
t.Run("Counter", func(t *testing.T) {
|
||||
delegate := &afCounter{}
|
||||
testFloat64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, float64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testFloat64Race(f, delegate.setDelegate)
|
||||
})
|
||||
|
||||
t.Run("UpDownCounter", func(t *testing.T) {
|
||||
delegate := &afUpDownCounter{}
|
||||
testFloat64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, float64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testFloat64Race(f, delegate.setDelegate)
|
||||
})
|
||||
|
||||
t.Run("Gauge", func(t *testing.T) {
|
||||
delegate := &afGauge{}
|
||||
testFloat64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, float64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testFloat64Race(f, delegate.setDelegate)
|
||||
})
|
||||
})
|
||||
|
||||
@ -81,17 +84,20 @@ func TestAsyncInstrumentSetDelegateRace(t *testing.T) {
|
||||
t.Run("Int64", func(t *testing.T) {
|
||||
t.Run("Counter", func(t *testing.T) {
|
||||
delegate := &aiCounter{}
|
||||
testInt64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, int64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testInt64Race(f, delegate.setDelegate)
|
||||
})
|
||||
|
||||
t.Run("UpDownCounter", func(t *testing.T) {
|
||||
delegate := &aiUpDownCounter{}
|
||||
testInt64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, int64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testInt64Race(f, delegate.setDelegate)
|
||||
})
|
||||
|
||||
t.Run("Gauge", func(t *testing.T) {
|
||||
delegate := &aiGauge{}
|
||||
testInt64Race(delegate.Observe, delegate.setDelegate)
|
||||
f := func(context.Context, int64, ...attribute.KeyValue) { _ = delegate.Unwrap() }
|
||||
testInt64Race(f, delegate.setDelegate)
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -138,11 +144,11 @@ func TestSyncInstrumentSetDelegateRace(t *testing.T) {
|
||||
type testCountingFloatInstrument struct {
|
||||
count int
|
||||
|
||||
instrument.Asynchronous
|
||||
instrument.Float64Observable
|
||||
instrument.Synchronous
|
||||
}
|
||||
|
||||
func (i *testCountingFloatInstrument) Observe(context.Context, float64, ...attribute.KeyValue) {
|
||||
func (i *testCountingFloatInstrument) observe() {
|
||||
i.count++
|
||||
}
|
||||
func (i *testCountingFloatInstrument) Add(context.Context, float64, ...attribute.KeyValue) {
|
||||
@ -155,11 +161,11 @@ func (i *testCountingFloatInstrument) Record(context.Context, float64, ...attrib
|
||||
type testCountingIntInstrument struct {
|
||||
count int
|
||||
|
||||
instrument.Asynchronous
|
||||
instrument.Int64Observable
|
||||
instrument.Synchronous
|
||||
}
|
||||
|
||||
func (i *testCountingIntInstrument) Observe(context.Context, int64, ...attribute.KeyValue) {
|
||||
func (i *testCountingIntInstrument) observe() {
|
||||
i.count++
|
||||
}
|
||||
func (i *testCountingIntInstrument) Add(context.Context, int64, ...attribute.KeyValue) {
|
||||
|
@ -148,10 +148,16 @@ type observationRecorder struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (o observationRecorder) ObserveFloat64(i instrument.Float64Observer, value float64, attr ...attribute.KeyValue) {
|
||||
i.Observe(o.ctx, value, attr...)
|
||||
func (o observationRecorder) ObserveFloat64(i instrument.Float64Observable, value float64, attr ...attribute.KeyValue) {
|
||||
iImpl, ok := i.(*testCountingFloatInstrument)
|
||||
if ok {
|
||||
iImpl.observe()
|
||||
}
|
||||
}
|
||||
|
||||
func (o observationRecorder) ObserveInt64(i instrument.Int64Observer, value int64, attr ...attribute.KeyValue) {
|
||||
i.Observe(o.ctx, value, attr...)
|
||||
func (o observationRecorder) ObserveInt64(i instrument.Int64Observable, value int64, attr ...attribute.KeyValue) {
|
||||
iImpl, ok := i.(*testCountingIntInstrument)
|
||||
if ok {
|
||||
iImpl.observe()
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ type Callback func(context.Context, Observer) error
|
||||
// Observer records measurements for multiple instruments in a Callback.
|
||||
type Observer interface {
|
||||
// ObserveFloat64 records the float64 value with attributes for obsrv.
|
||||
ObserveFloat64(obsrv instrument.Float64Observer, value float64, attributes ...attribute.KeyValue)
|
||||
ObserveFloat64(obsrv instrument.Float64Observable, value float64, attributes ...attribute.KeyValue)
|
||||
// ObserveInt64 records the int64 value with attributes for obsrv.
|
||||
ObserveInt64(obsrv instrument.Int64Observer, value int64, attributes ...attribute.KeyValue)
|
||||
ObserveInt64(obsrv instrument.Int64Observable, value int64, attributes ...attribute.KeyValue)
|
||||
}
|
||||
|
||||
// Registration is an token representing the unique registration of a callback
|
||||
|
@ -97,7 +97,7 @@ type noopReg struct{}
|
||||
func (noopReg) Unregister() error { return nil }
|
||||
|
||||
type nonrecordingAsyncFloat64Instrument struct {
|
||||
instrument.Asynchronous
|
||||
instrument.Float64Observable
|
||||
}
|
||||
|
||||
var (
|
||||
@ -118,12 +118,8 @@ func (n nonrecordingAsyncFloat64Instrument) Gauge(string, ...instrument.Float64O
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (nonrecordingAsyncFloat64Instrument) Observe(context.Context, float64, ...attribute.KeyValue) {
|
||||
|
||||
}
|
||||
|
||||
type nonrecordingAsyncInt64Instrument struct {
|
||||
instrument.Asynchronous
|
||||
instrument.Int64Observable
|
||||
}
|
||||
|
||||
var (
|
||||
@ -144,9 +140,6 @@ func (n nonrecordingAsyncInt64Instrument) Gauge(string, ...instrument.Int64Obser
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (nonrecordingAsyncInt64Instrument) Observe(context.Context, int64, ...attribute.KeyValue) {
|
||||
}
|
||||
|
||||
type nonrecordingSyncFloat64Instrument struct {
|
||||
instrument.Synchronous
|
||||
}
|
||||
|
@ -72,45 +72,3 @@ func TestSyncInt64(t *testing.T) {
|
||||
inst.Record(context.Background(), 1, attribute.String("key", "value"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestAsyncFloat64(t *testing.T) {
|
||||
meter := NewNoopMeterProvider().Meter("test instrumentation")
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Float64ObservableCounter("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), 1.0, attribute.String("key", "value"))
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Float64ObservableUpDownCounter("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), -1.0, attribute.String("key", "value"))
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Float64ObservableGauge("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), 1.0, attribute.String("key", "value"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestAsyncInt64(t *testing.T) {
|
||||
meter := NewNoopMeterProvider().Meter("test instrumentation")
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Int64ObservableCounter("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), 1, attribute.String("key", "value"))
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Int64ObservableUpDownCounter("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), -1, attribute.String("key", "value"))
|
||||
})
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
inst, err := meter.Int64ObservableGauge("test instrument")
|
||||
require.NoError(t, err)
|
||||
inst.Observe(context.Background(), 1, attribute.String("key", "value"))
|
||||
})
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
"go.opentelemetry.io/otel/metric/instrument"
|
||||
"go.opentelemetry.io/otel/metric/unit"
|
||||
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||
@ -211,6 +210,36 @@ type observablID[N int64 | float64] struct {
|
||||
scope instrumentation.Scope
|
||||
}
|
||||
|
||||
type float64Observable struct {
|
||||
instrument.Float64Observable
|
||||
*observable[float64]
|
||||
}
|
||||
|
||||
var _ instrument.Float64ObservableCounter = float64Observable{}
|
||||
var _ instrument.Float64ObservableUpDownCounter = float64Observable{}
|
||||
var _ instrument.Float64ObservableGauge = float64Observable{}
|
||||
|
||||
func newFloat64Observable(scope instrumentation.Scope, kind InstrumentKind, name, desc string, u unit.Unit, agg []internal.Aggregator[float64]) float64Observable {
|
||||
return float64Observable{
|
||||
observable: newObservable[float64](scope, kind, name, desc, u, agg),
|
||||
}
|
||||
}
|
||||
|
||||
type int64Observable struct {
|
||||
instrument.Int64Observable
|
||||
*observable[int64]
|
||||
}
|
||||
|
||||
var _ instrument.Int64ObservableCounter = int64Observable{}
|
||||
var _ instrument.Int64ObservableUpDownCounter = int64Observable{}
|
||||
var _ instrument.Int64ObservableGauge = int64Observable{}
|
||||
|
||||
func newInt64Observable(scope instrumentation.Scope, kind InstrumentKind, name, desc string, u unit.Unit, agg []internal.Aggregator[int64]) int64Observable {
|
||||
return int64Observable{
|
||||
observable: newObservable[int64](scope, kind, name, desc, u, agg),
|
||||
}
|
||||
}
|
||||
|
||||
type observable[N int64 | float64] struct {
|
||||
instrument.Asynchronous
|
||||
observablID[N]
|
||||
@ -231,25 +260,6 @@ func newObservable[N int64 | float64](scope instrumentation.Scope, kind Instrume
|
||||
}
|
||||
}
|
||||
|
||||
var _ instrument.Float64ObservableCounter = (*observable[float64])(nil)
|
||||
var _ instrument.Float64ObservableUpDownCounter = (*observable[float64])(nil)
|
||||
var _ instrument.Float64ObservableGauge = (*observable[float64])(nil)
|
||||
var _ instrument.Int64ObservableCounter = (*observable[int64])(nil)
|
||||
var _ instrument.Int64ObservableUpDownCounter = (*observable[int64])(nil)
|
||||
var _ instrument.Int64ObservableGauge = (*observable[int64])(nil)
|
||||
|
||||
// Observe logs an error.
|
||||
func (o *observable[N]) Observe(ctx context.Context, val N, attrs ...attribute.KeyValue) {
|
||||
var zero N
|
||||
err := errors.New("invalid observation")
|
||||
global.Error(err, "dropping observation made outside a callback",
|
||||
"name", o.name,
|
||||
"description", o.description,
|
||||
"unit", o.unit,
|
||||
"number", fmt.Sprintf("%T", zero),
|
||||
)
|
||||
}
|
||||
|
||||
// observe records the val for the set of attrs.
|
||||
func (o *observable[N]) observe(val N, attrs []attribute.KeyValue) {
|
||||
for _, agg := range o.aggregators {
|
||||
|
@ -232,7 +232,7 @@ func (m *meter) RegisterCallback(f metric.Callback, insts ...instrument.Asynchro
|
||||
}
|
||||
|
||||
switch o := inst.(type) {
|
||||
case *observable[int64]:
|
||||
case int64Observable:
|
||||
if err := o.registerable(m.scope); err != nil {
|
||||
if !errors.Is(err, errEmptyAgg) {
|
||||
errs.append(err)
|
||||
@ -240,7 +240,7 @@ func (m *meter) RegisterCallback(f metric.Callback, insts ...instrument.Asynchro
|
||||
continue
|
||||
}
|
||||
reg.registerInt64(o.observablID)
|
||||
case *observable[float64]:
|
||||
case float64Observable:
|
||||
if err := o.registerable(m.scope); err != nil {
|
||||
if !errors.Is(err, errEmptyAgg) {
|
||||
errs.append(err)
|
||||
@ -298,10 +298,10 @@ var (
|
||||
errUnregObserver = errors.New("observable instrument not registered for callback")
|
||||
)
|
||||
|
||||
func (r observer) ObserveFloat64(o instrument.Float64Observer, v float64, a ...attribute.KeyValue) {
|
||||
var oImpl *observable[float64]
|
||||
func (r observer) ObserveFloat64(o instrument.Float64Observable, v float64, a ...attribute.KeyValue) {
|
||||
var oImpl float64Observable
|
||||
switch conv := o.(type) {
|
||||
case *observable[float64]:
|
||||
case float64Observable:
|
||||
oImpl = conv
|
||||
case interface {
|
||||
Unwrap() instrument.Asynchronous
|
||||
@ -309,7 +309,7 @@ func (r observer) ObserveFloat64(o instrument.Float64Observer, v float64, a ...a
|
||||
// Unwrap any global.
|
||||
async := conv.Unwrap()
|
||||
var ok bool
|
||||
if oImpl, ok = async.(*observable[float64]); !ok {
|
||||
if oImpl, ok = async.(float64Observable); !ok {
|
||||
global.Error(errUnknownObserver, "failed to record asynchronous")
|
||||
return
|
||||
}
|
||||
@ -330,10 +330,10 @@ func (r observer) ObserveFloat64(o instrument.Float64Observer, v float64, a ...a
|
||||
oImpl.observe(v, a)
|
||||
}
|
||||
|
||||
func (r observer) ObserveInt64(o instrument.Int64Observer, v int64, a ...attribute.KeyValue) {
|
||||
var oImpl *observable[int64]
|
||||
func (r observer) ObserveInt64(o instrument.Int64Observable, v int64, a ...attribute.KeyValue) {
|
||||
var oImpl int64Observable
|
||||
switch conv := o.(type) {
|
||||
case *observable[int64]:
|
||||
case int64Observable:
|
||||
oImpl = conv
|
||||
case interface {
|
||||
Unwrap() instrument.Asynchronous
|
||||
@ -341,7 +341,7 @@ func (r observer) ObserveInt64(o instrument.Int64Observer, v int64, a ...attribu
|
||||
// Unwrap any global.
|
||||
async := conv.Unwrap()
|
||||
var ok bool
|
||||
if oImpl, ok = async.(*observable[int64]); !ok {
|
||||
if oImpl, ok = async.(int64Observable); !ok {
|
||||
global.Error(errUnknownObserver, "failed to record asynchronous")
|
||||
return
|
||||
}
|
||||
@ -398,13 +398,13 @@ func (p *instProvider[N]) lookup(kind InstrumentKind, name, desc string, u unit.
|
||||
|
||||
type int64ObservProvider struct{ *instProvider[int64] }
|
||||
|
||||
func (p int64ObservProvider) lookup(kind InstrumentKind, name, desc string, u unit.Unit) (*observable[int64], error) {
|
||||
func (p int64ObservProvider) lookup(kind InstrumentKind, name, desc string, u unit.Unit) (int64Observable, error) {
|
||||
aggs, err := p.aggs(kind, name, desc, u)
|
||||
return newObservable(p.scope, kind, name, desc, u, aggs), err
|
||||
return newInt64Observable(p.scope, kind, name, desc, u, aggs), err
|
||||
}
|
||||
|
||||
func (p int64ObservProvider) registerCallbacks(inst *observable[int64], cBacks []instrument.Int64Callback) {
|
||||
if inst == nil {
|
||||
func (p int64ObservProvider) registerCallbacks(inst int64Observable, cBacks []instrument.Int64Callback) {
|
||||
if inst.observable == nil || len(inst.aggregators) == 0 {
|
||||
// Drop aggregator.
|
||||
return
|
||||
}
|
||||
@ -414,20 +414,28 @@ func (p int64ObservProvider) registerCallbacks(inst *observable[int64], cBacks [
|
||||
}
|
||||
}
|
||||
|
||||
func (p int64ObservProvider) callback(i *observable[int64], f instrument.Int64Callback) func(context.Context) error {
|
||||
inst := callbackObserver[int64]{i}
|
||||
func (p int64ObservProvider) callback(i int64Observable, f instrument.Int64Callback) func(context.Context) error {
|
||||
inst := int64Observer{i}
|
||||
return func(ctx context.Context) error { return f(ctx, inst) }
|
||||
}
|
||||
|
||||
type int64Observer struct {
|
||||
int64Observable
|
||||
}
|
||||
|
||||
func (o int64Observer) Observe(val int64, attrs ...attribute.KeyValue) {
|
||||
o.observe(val, attrs)
|
||||
}
|
||||
|
||||
type float64ObservProvider struct{ *instProvider[float64] }
|
||||
|
||||
func (p float64ObservProvider) lookup(kind InstrumentKind, name, desc string, u unit.Unit) (*observable[float64], error) {
|
||||
func (p float64ObservProvider) lookup(kind InstrumentKind, name, desc string, u unit.Unit) (float64Observable, error) {
|
||||
aggs, err := p.aggs(kind, name, desc, u)
|
||||
return newObservable(p.scope, kind, name, desc, u, aggs), err
|
||||
return newFloat64Observable(p.scope, kind, name, desc, u, aggs), err
|
||||
}
|
||||
|
||||
func (p float64ObservProvider) registerCallbacks(inst *observable[float64], cBacks []instrument.Float64Callback) {
|
||||
if inst == nil {
|
||||
func (p float64ObservProvider) registerCallbacks(inst float64Observable, cBacks []instrument.Float64Callback) {
|
||||
if inst.observable == nil || len(inst.aggregators) == 0 {
|
||||
// Drop aggregator.
|
||||
return
|
||||
}
|
||||
@ -437,17 +445,15 @@ func (p float64ObservProvider) registerCallbacks(inst *observable[float64], cBac
|
||||
}
|
||||
}
|
||||
|
||||
func (p float64ObservProvider) callback(i *observable[float64], f instrument.Float64Callback) func(context.Context) error {
|
||||
inst := callbackObserver[float64]{i}
|
||||
func (p float64ObservProvider) callback(i float64Observable, f instrument.Float64Callback) func(context.Context) error {
|
||||
inst := float64Observer{i}
|
||||
return func(ctx context.Context) error { return f(ctx, inst) }
|
||||
}
|
||||
|
||||
// callbackObserver is an observer that records values for a wrapped
|
||||
// observable.
|
||||
type callbackObserver[N int64 | float64] struct {
|
||||
*observable[N]
|
||||
type float64Observer struct {
|
||||
float64Observable
|
||||
}
|
||||
|
||||
func (o callbackObserver[N]) Observe(_ context.Context, val N, attrs ...attribute.KeyValue) {
|
||||
func (o float64Observer) Observe(val float64, attrs ...attribute.KeyValue) {
|
||||
o.observe(val, attrs)
|
||||
}
|
||||
|
@ -179,8 +179,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableInt64Count",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
ctr, err := m.Int64ObservableCounter("aint", instrument.WithInt64Callback(cback))
|
||||
@ -190,9 +190,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, ctr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
ctr.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "aint",
|
||||
@ -209,8 +206,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableInt64UpDownCount",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
ctr, err := m.Int64ObservableUpDownCounter("aint", instrument.WithInt64Callback(cback))
|
||||
@ -220,9 +217,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, ctr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
ctr.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "aint",
|
||||
@ -239,8 +233,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableInt64Gauge",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Int64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
gauge, err := m.Int64ObservableGauge("agauge", instrument.WithInt64Callback(cback))
|
||||
@ -250,9 +244,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, gauge)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
gauge.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "agauge",
|
||||
@ -267,8 +258,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableFloat64Count",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
ctr, err := m.Float64ObservableCounter("afloat", instrument.WithFloat64Callback(cback))
|
||||
@ -278,9 +269,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, ctr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
ctr.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "afloat",
|
||||
@ -297,8 +285,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableFloat64UpDownCount",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
ctr, err := m.Float64ObservableUpDownCounter("afloat", instrument.WithFloat64Callback(cback))
|
||||
@ -308,9 +296,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, ctr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
ctr.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "afloat",
|
||||
@ -327,8 +312,8 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
{
|
||||
name: "ObservableFloat64Gauge",
|
||||
fn: func(t *testing.T, m metric.Meter) {
|
||||
cback := func(ctx context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(ctx, 4, attrs...)
|
||||
cback := func(_ context.Context, o instrument.Float64Observer) error {
|
||||
o.Observe(4, attrs...)
|
||||
return nil
|
||||
}
|
||||
gauge, err := m.Float64ObservableGauge("agauge", instrument.WithFloat64Callback(cback))
|
||||
@ -338,9 +323,6 @@ func TestMeterCreatesInstruments(t *testing.T) {
|
||||
return nil
|
||||
}, gauge)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Observed outside of a callback, it should be ignored.
|
||||
gauge.Observe(context.Background(), 19)
|
||||
},
|
||||
want: metricdata.Metrics{
|
||||
Name: "agauge",
|
||||
@ -564,10 +546,9 @@ func TestCallbackObserverNonRegistered(t *testing.T) {
|
||||
fCtr, err := m2.Float64ObservableCounter("float64 ctr")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Panics if Observe is called.
|
||||
type int64Obsrv struct{ instrument.Int64Observer }
|
||||
type int64Obsrv struct{ instrument.Int64Observable }
|
||||
int64Foreign := int64Obsrv{}
|
||||
type float64Obsrv struct{ instrument.Float64Observer }
|
||||
type float64Obsrv struct{ instrument.Float64Observable }
|
||||
float64Foreign := float64Obsrv{}
|
||||
|
||||
_, err = m1.RegisterCallback(
|
||||
@ -1311,9 +1292,9 @@ func TestAsynchronousExample(t *testing.T) {
|
||||
|
||||
observations := make(map[attribute.Set]int64)
|
||||
_, err := meter.Int64ObservableCounter(instName, instrument.WithInt64Callback(
|
||||
func(ctx context.Context, o instrument.Int64Observer) error {
|
||||
func(_ context.Context, o instrument.Int64Observer) error {
|
||||
for attrSet, val := range observations {
|
||||
o.Observe(ctx, val, attrSet.ToSlice()...)
|
||||
o.Observe(val, attrSet.ToSlice()...)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user