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

Add embedded private method interfaces in metric API (#3916)

* PoC of embedded private method ifaces

* Rename embed to embedded

* Add an embedded iface for all instruments

* Fix metric/instrument tests

* Fix global and otel

* Fix SDK

* Comment the embedded pkg types

* Update the embedded pkg docs

* Update otel/metric docs about impls

* Update otel/metric type docs on impl

* Update docs in otel/metric/instrument on default

* Add changes to changelog

* Apply suggestions from code review

Co-authored-by: Robert Pająk <pellared@hotmail.com>

* Apply feedback on URLs

* Reword based on feedback

* Make it clear we only recommended embedding noop

* Ignore links with godot linter

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
This commit is contained in:
Tyler Yahn 2023-04-03 07:33:19 -07:00 committed by GitHub
parent 5f13db5ca6
commit 65ebe5e50f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 565 additions and 50 deletions

View File

@ -85,6 +85,8 @@ linters-settings:
- "**/internal/matchers/*.go"
godot:
exclude:
# Exclude links.
- '^ *\[[^]]+\]:'
# Exclude sentence fragments for lists.
- '^[ ]*[-•]'
# Exclude sentences prefixing a list.

View File

@ -10,11 +10,14 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Added
- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916)
- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949)
### Changed
- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870)
- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`.
This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916)
- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941)
- `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider`

View File

@ -20,6 +20,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
)
@ -29,6 +30,7 @@ type unwrapper interface {
}
type afCounter struct {
embedded.Float64ObservableCounter
instrument.Float64Observable
name string
@ -57,6 +59,7 @@ func (i *afCounter) Unwrap() instrument.Observable {
}
type afUpDownCounter struct {
embedded.Float64ObservableUpDownCounter
instrument.Float64Observable
name string
@ -85,6 +88,7 @@ func (i *afUpDownCounter) Unwrap() instrument.Observable {
}
type afGauge struct {
embedded.Float64ObservableGauge
instrument.Float64Observable
name string
@ -113,6 +117,7 @@ func (i *afGauge) Unwrap() instrument.Observable {
}
type aiCounter struct {
embedded.Int64ObservableCounter
instrument.Int64Observable
name string
@ -141,6 +146,7 @@ func (i *aiCounter) Unwrap() instrument.Observable {
}
type aiUpDownCounter struct {
embedded.Int64ObservableUpDownCounter
instrument.Int64Observable
name string
@ -169,6 +175,7 @@ func (i *aiUpDownCounter) Unwrap() instrument.Observable {
}
type aiGauge struct {
embedded.Int64ObservableGauge
instrument.Int64Observable
name string
@ -198,6 +205,8 @@ func (i *aiGauge) Unwrap() instrument.Observable {
// Sync Instruments.
type sfCounter struct {
embedded.Float64Counter
name string
opts []instrument.Float64CounterOption
@ -222,6 +231,8 @@ func (i *sfCounter) Add(ctx context.Context, incr float64, attrs ...attribute.Ke
}
type sfUpDownCounter struct {
embedded.Float64UpDownCounter
name string
opts []instrument.Float64UpDownCounterOption
@ -246,6 +257,8 @@ func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, attrs ...attrib
}
type sfHistogram struct {
embedded.Float64Histogram
name string
opts []instrument.Float64HistogramOption
@ -270,6 +283,8 @@ func (i *sfHistogram) Record(ctx context.Context, x float64, attrs ...attribute.
}
type siCounter struct {
embedded.Int64Counter
name string
opts []instrument.Int64CounterOption
@ -294,6 +309,8 @@ func (i *siCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValu
}
type siUpDownCounter struct {
embedded.Int64UpDownCounter
name string
opts []instrument.Int64UpDownCounterOption
@ -318,6 +335,8 @@ func (i *siUpDownCounter) Add(ctx context.Context, x int64, attrs ...attribute.K
}
type siHistogram struct {
embedded.Int64Histogram
name string
opts []instrument.Int64HistogramOption

View File

@ -20,6 +20,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/noop"
)
@ -146,6 +147,12 @@ type testCountingFloatInstrument struct {
count int
instrument.Float64Observable
embedded.Float64Counter
embedded.Float64UpDownCounter
embedded.Float64Histogram
embedded.Float64ObservableCounter
embedded.Float64ObservableUpDownCounter
embedded.Float64ObservableGauge
}
func (i *testCountingFloatInstrument) observe() {
@ -162,6 +169,12 @@ type testCountingIntInstrument struct {
count int
instrument.Int64Observable
embedded.Int64Counter
embedded.Int64UpDownCounter
embedded.Int64Histogram
embedded.Int64ObservableCounter
embedded.Int64ObservableUpDownCounter
embedded.Int64ObservableGauge
}
func (i *testCountingIntInstrument) observe() {

View File

@ -20,6 +20,7 @@ import (
"sync/atomic"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
)
@ -28,6 +29,8 @@ import (
// All MeterProvider functionality is forwarded to a delegate once
// configured.
type meterProvider struct {
embedded.MeterProvider
mtx sync.Mutex
meters map[il]*meter
@ -94,6 +97,8 @@ func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Me
// All Meter functionality is forwarded to a delegate once configured.
// Otherwise, all functionality is forwarded to a NoopMeter.
type meter struct {
embedded.Meter
name string
opts []metric.MeterOption
@ -308,6 +313,8 @@ func unwrapInstruments(instruments []instrument.Observable) []instrument.Observa
}
type registration struct {
embedded.Registration
instruments []instrument.Observable
function metric.Callback

View File

@ -19,10 +19,13 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
)
type testMeterProvider struct {
embedded.MeterProvider
count int
}
@ -33,6 +36,8 @@ func (p *testMeterProvider) Meter(name string, opts ...metric.MeterOption) metri
}
type testMeter struct {
embedded.Meter
afCount int
afUDCount int
afGauge int
@ -123,6 +128,8 @@ func (m *testMeter) RegisterCallback(f metric.Callback, i ...instrument.Observab
}
type testReg struct {
embedded.Registration
f func()
}
@ -134,7 +141,7 @@ func (r testReg) Unregister() error {
// This enables async collection.
func (m *testMeter) collect() {
ctx := context.Background()
o := observationRecorder{ctx}
o := observationRecorder{ctx: ctx}
for _, f := range m.callbacks {
if f == nil {
// Unregister.
@ -145,6 +152,8 @@ func (m *testMeter) collect() {
}
type observationRecorder struct {
embedded.Observer
ctx context.Context
}

View File

@ -30,6 +30,69 @@ can then be built from the [Meter]'s instruments. See
[go.opentelemetry.io/otel/metric/instrument] for documentation on each
instrument and its intended use.
# API Implementations
This package does not conform to the standard Go versioning policy, all of its
interfaces may have methods added to them without a package major version bump.
This non-standard API evolution could surprise an uninformed implementation
author. They could unknowingly build their implementation in a way that would
result in a runtime panic for their users that update to the new API.
The API is designed to help inform an instrumentation author about this
non-standard API evolution. It requires them to choose a default behavior for
unimplemented interface methods. There are three behavior choices they can
make:
- Compilation failure
- Panic
- Default to another implementation
All interfaces in this API embed a corresponding interface from
[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default
behavior of their implementations to be a compilation failure, signaling to
their users they need to update to the latest version of that implementation,
they need to embed the corresponding interface from
[go.opentelemetry.io/otel/metric/embedded] in their implementation. For
example,
import "go.opentelemetry.io/otel/metric/embedded"
type MeterProvider struct {
embedded.MeterProvider
// ...
}
If an author wants the default behavior of their implementations to a panic,
they need to embed the API interface directly.
import "go.opentelemetry.io/otel/metric"
type MeterProvider struct {
metric.MeterProvider
// ...
}
This is not a recommended behavior as it could lead to publishing packages that
contain runtime panics when users update other package that use newer versions
of [go.opentelemetry.io/otel/metric].
Finally, an author can embed another implementation in theirs. The embedded
implementation will be used for methods not defined by the author. For example,
an author who want to default to silently dropping the call can use
[go.opentelemetry.io/otel/metric/noop]:
import "go.opentelemetry.io/otel/metric/noop"
type MeterProvider struct {
noop.MeterProvider
// ...
}
It is strongly recommended that authors only embed
[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior.
That implementation is the only one OpenTelemetry authors can guarantee will
fully implement all the API interfaces when a user updates their API.
[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider
*/
package metric // import "go.opentelemetry.io/otel/metric"

233
metric/embedded/embedded.go Normal file
View File

@ -0,0 +1,233 @@
// 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 embedded provides interfaces embedded within the [OpenTelemetry
// metric API].
//
// Implementers of the [OpenTelemetry metric API] can embed the relevant type
// from this package into their implementation directly. Doing so will result
// in a compilation error for users when the [OpenTelemetry metric API] is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [OpenTelemetry metric API]: go.opentelemetry.io/otel/metric
package embedded // import "go.opentelemetry.io/otel/metric/embedded"
// MeterProvider is embedded in the OpenTelemetry metric API [MeterProvider].
//
// Embed this interface in your implementation of the [MeterProvider] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [MeterProvider] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [MeterProvider]: go.opentelemetry.io/otel/metric.MeterProvider
type MeterProvider interface{ meterProvider() }
// Meter is embedded in the OpenTelemetry metric API [Meter].
//
// Embed this interface in your implementation of the [Meter] if you want users
// to experience a compilation error, signaling they need to update to your
// latest implementation, when the [Meter] interface is extended (which is
// something that can happen without a major version bump of the API package).
//
// [Meter]: go.opentelemetry.io/otel/metric.Meter
type Meter interface{ meter() }
// Float64Observer is embedded in the OpenTelemetry metric API
// [Float64Observer].
//
// Embed this interface in your implementation of the [Float64Observer] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Float64Observer] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Float64Observer]: go.opentelemetry.io/otel/metric.Float64Observer
type Float64Observer interface{ float64Observer() }
// Int64Observer is embedded in the OpenTelemetry metric API [Int64Observer].
//
// Embed this interface in your implementation of the [Int64Observer] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Int64Observer] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Int64Observer]: go.opentelemetry.io/otel/metric.Int64Observer
type Int64Observer interface{ int64Observer() }
// Observer is embedded in the OpenTelemetry metric API [Observer].
//
// Embed this interface in your implementation of the [Observer] if you want
// users to experience a compilation error, signaling they need to update to
// your latest implementation, when the [Observer] interface is extended (which
// is something that can happen without a major version bump of the API
// package).
//
// [Observer]: go.opentelemetry.io/otel/metric.Observer
type Observer interface{ observer() }
// Registration is embedded in the OpenTelemetry metric API [Registration].
//
// Embed this interface in your implementation of the [Registration] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Registration] interface is extended
// (which is something that can happen without a major version bump of the API
// package).
//
// [Registration]: go.opentelemetry.io/otel/metric.Registration
type Registration interface{ registration() }
// Float64Counter is embedded in the OpenTelemetry metric API [Float64Counter].
//
// Embed this interface in your implementation of the [Float64Counter] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Float64Counter] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Float64Counter]: go.opentelemetry.io/otel/metric.Float64Counter
type Float64Counter interface{ float64Counter() }
// Float64Histogram is embedded in the OpenTelemetry metric API
// [Float64Histogram].
//
// Embed this interface in your implementation of the [Float64Histogram] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Float64Histogram] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Float64Histogram]: go.opentelemetry.io/otel/metric.Float64Histogram
type Float64Histogram interface{ float64Histogram() }
// Float64ObservableCounter is embedded in the OpenTelemetry metric API
// [Float64ObservableCounter].
//
// Embed this interface in your implementation of the
// [Float64ObservableCounter] if you want users to experience a compilation
// error, signaling they need to update to your latest implementation, when the
// [Float64ObservableCounter] interface is extended (which is something that
// can happen without a major version bump of the API package).
//
// [Float64ObservableCounter]: go.opentelemetry.io/otel/metric.Float64ObservableCounter
type Float64ObservableCounter interface{ float64ObservableCounter() }
// Float64ObservableGauge is embedded in the OpenTelemetry metric API
// [Float64ObservableGauge].
//
// Embed this interface in your implementation of the [Float64ObservableGauge]
// if you want users to experience a compilation error, signaling they need to
// update to your latest implementation, when the [Float64ObservableGauge]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
//
// [Float64ObservableGauge]: go.opentelemetry.io/otel/metric.Float64ObservableGauge
type Float64ObservableGauge interface{ float64ObservableGauge() }
// Float64ObservableUpDownCounter is embedded in the OpenTelemetry metric API
// [Float64ObservableUpDownCounter].
//
// Embed this interface in your implementation of the
// [Float64ObservableUpDownCounter] if you want users to experience a
// compilation error, signaling they need to update to your latest
// implementation, when the [Float64ObservableUpDownCounter] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Float64ObservableUpDownCounter]: go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter
type Float64ObservableUpDownCounter interface{ float64ObservableUpDownCounter() }
// Float64UpDownCounter is embedded in the OpenTelemetry metric API
// [Float64UpDownCounter].
//
// Embed this interface in your implementation of the [Float64UpDownCounter] if
// you want users to experience a compilation error, signaling they need to
// update to your latest implementation, when the [Float64UpDownCounter]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
//
// [Float64UpDownCounter]: go.opentelemetry.io/otel/metric.Float64UpDownCounter
type Float64UpDownCounter interface{ float64UpDownCounter() }
// Int64Counter is embedded in the OpenTelemetry metric API [Int64Counter].
//
// Embed this interface in your implementation of the [Int64Counter] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Int64Counter] interface is extended
// (which is something that can happen without a major version bump of the API
// package).
//
// [Int64Counter]: go.opentelemetry.io/otel/metric.Int64Counter
type Int64Counter interface{ int64Counter() }
// Int64Histogram is embedded in the OpenTelemetry metric API [Int64Histogram].
//
// Embed this interface in your implementation of the [Int64Histogram] if you
// want users to experience a compilation error, signaling they need to update
// to your latest implementation, when the [Int64Histogram] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [Int64Histogram]: go.opentelemetry.io/otel/metric.Int64Histogram
type Int64Histogram interface{ int64Histogram() }
// Int64ObservableCounter is embedded in the OpenTelemetry metric API
// [Int64ObservableCounter].
//
// Embed this interface in your implementation of the [Int64ObservableCounter]
// if you want users to experience a compilation error, signaling they need to
// update to your latest implementation, when the [Int64ObservableCounter]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
//
// [Int64ObservableCounter]: go.opentelemetry.io/otel/metric.Int64ObservableCounter
type Int64ObservableCounter interface{ int64ObservableCounter() }
// Int64ObservableGauge is embedded in the OpenTelemetry metric API
// [Int64ObservableGauge].
//
// Embed this interface in your implementation of the [Int64ObservableGauge] if
// you want users to experience a compilation error, signaling they need to
// update to your latest implementation, when the [Int64ObservableGauge]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
//
// [Int64ObservableGauge]: go.opentelemetry.io/otel/metric.Int64ObservableGauge
type Int64ObservableGauge interface{ int64ObservableGauge() }
// Int64ObservableUpDownCounter is embedded in the OpenTelemetry metric API
// [Int64ObservableUpDownCounter].
//
// Embed this interface in your implementation of the
// [Int64ObservableUpDownCounter] if you want users to experience a compilation
// error, signaling they need to update to your latest implementation, when the
// [Int64ObservableUpDownCounter] interface is extended (which is something
// that can happen without a major version bump of the API package).
//
// [Int64ObservableUpDownCounter]: go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter
type Int64ObservableUpDownCounter interface{ int64ObservableUpDownCounter() }
// Int64UpDownCounter is embedded in the OpenTelemetry metric API
// [Int64UpDownCounter].
//
// Embed this interface in your implementation of the [Int64UpDownCounter] if
// you want users to experience a compilation error, signaling they need to
// update to your latest implementation, when the [Int64UpDownCounter]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
//
// [Int64UpDownCounter]: go.opentelemetry.io/otel/metric.Int64UpDownCounter
type Int64UpDownCounter interface{ int64UpDownCounter() }

View File

@ -18,13 +18,14 @@ import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
// 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.
// Warning: Methods may be added to this interface in minor releases.
type Float64Observable interface {
Observable
@ -36,8 +37,15 @@ type Float64Observable interface {
// 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{ Float64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64ObservableCounter interface {
embedded.Float64ObservableCounter
Float64Observable
}
// Float64ObservableCounterConfig contains options for asynchronous counter
// instruments that record int64 values.
@ -84,8 +92,15 @@ type Float64ObservableCounterOption interface {
// 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{ Float64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64ObservableUpDownCounter interface {
embedded.Float64ObservableUpDownCounter
Float64Observable
}
// Float64ObservableUpDownCounterConfig contains options for asynchronous
// counter instruments that record int64 values.
@ -132,8 +147,15 @@ type Float64ObservableUpDownCounterOption interface {
// 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{ Float64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64ObservableGauge interface {
embedded.Float64ObservableGauge
Float64Observable
}
// Float64ObservableGaugeConfig contains options for asynchronous counter
// instruments that record int64 values.
@ -178,8 +200,13 @@ type Float64ObservableGaugeOption interface {
// Float64Observer is a recorder of float64 measurements.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64Observer interface {
embedded.Float64Observer
// Observe records the float64 value with attributes.
Observe(value float64, attributes ...attribute.KeyValue)
}

View File

@ -22,6 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
func TestFloat64ObservableConfiguration(t *testing.T) {
@ -83,6 +84,7 @@ type float64ObservableConfig interface {
}
type float64Observer struct {
embedded.Float64Observer
Observable
got float64
}

View File

@ -18,13 +18,14 @@ import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
// 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.
// Warning: Methods may be added to this interface in minor releases.
type Int64Observable interface {
Observable
@ -36,8 +37,15 @@ type Int64Observable interface {
// 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{ Int64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64ObservableCounter interface {
embedded.Int64ObservableCounter
Int64Observable
}
// Int64ObservableCounterConfig contains options for asynchronous counter
// instruments that record int64 values.
@ -84,8 +92,15 @@ type Int64ObservableCounterOption interface {
// 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{ Int64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64ObservableUpDownCounter interface {
embedded.Int64ObservableUpDownCounter
Int64Observable
}
// Int64ObservableUpDownCounterConfig contains options for asynchronous counter
// instruments that record int64 values.
@ -132,8 +147,15 @@ type Int64ObservableUpDownCounterOption interface {
// 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{ Int64Observable }
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64ObservableGauge interface {
embedded.Int64ObservableGauge
Int64Observable
}
// Int64ObservableGaugeConfig contains options for asynchronous counter
// instruments that record int64 values.
@ -177,8 +199,13 @@ type Int64ObservableGaugeOption interface {
// Int64Observer is a recorder of int64 measurements.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64Observer interface {
embedded.Int64Observer
// Observe records the int64 value with attributes.
Observe(value int64, attributes ...attribute.KeyValue)
}

View File

@ -22,6 +22,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
func TestInt64ObservableConfiguration(t *testing.T) {
@ -83,6 +84,7 @@ type int64ObservableConfig interface {
}
type int64Observer struct {
embedded.Int64Observer
Observable
got int64
}

View File

@ -18,12 +18,18 @@ import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
// Float64Counter is an instrument that records increasing float64 values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64Counter interface {
embedded.Float64Counter
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
}
@ -64,8 +70,13 @@ type Float64CounterOption interface {
// Float64UpDownCounter is an instrument that records increasing or decreasing
// float64 values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64UpDownCounter interface {
embedded.Float64UpDownCounter
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
}
@ -107,8 +118,13 @@ type Float64UpDownCounterOption interface {
// Float64Histogram is an instrument that records a distribution of float64
// values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Float64Histogram interface {
embedded.Float64Histogram
// Record adds an additional value to the distribution.
Record(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
}

View File

@ -18,12 +18,18 @@ import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
)
// Int64Counter is an instrument that records increasing int64 values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64Counter interface {
embedded.Int64Counter
// Add records a change to the counter.
Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
}
@ -64,8 +70,13 @@ type Int64CounterOption interface {
// Int64UpDownCounter is an instrument that records increasing or decreasing
// int64 values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64UpDownCounter interface {
embedded.Int64UpDownCounter
// Add records a change to the counter.
Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
}
@ -107,8 +118,13 @@ type Int64UpDownCounterOption interface {
// Int64Histogram is an instrument that records a distribution of int64
// values.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// [go.opentelemetry.io/otel/metric] package documentation on API
// implementation for information on how to set default behavior for
// unimplemented methods.
type Int64Histogram interface {
embedded.Int64Histogram
// Record adds an additional value to the distribution.
Record(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
}

View File

@ -18,14 +18,19 @@ import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
)
// MeterProvider provides access to named Meter instances, for instrumenting
// an application or package.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type MeterProvider interface {
embedded.MeterProvider
// Meter returns a new Meter with the provided name and configuration.
//
// A Meter should be scoped at most to a single package. The name needs to
@ -40,8 +45,12 @@ type MeterProvider interface {
// Meter provides access to instrument instances for recording metrics.
//
// Warning: methods may be added to this interface in minor releases.
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Meter interface {
embedded.Meter
// Int64Counter returns a new instrument identified by name and configured
// with options. The instrument is used to synchronously record increasing
// int64 measurements during a computational operation.
@ -125,7 +134,13 @@ type Meter interface {
type Callback func(context.Context, Observer) error
// Observer records measurements for multiple instruments in a Callback.
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Observer interface {
embedded.Observer
// ObserveFloat64 records the float64 value with attributes for obsrv.
ObserveFloat64(obsrv instrument.Float64Observable, value float64, attributes ...attribute.KeyValue)
// ObserveInt64 records the int64 value with attributes for obsrv.
@ -134,7 +149,13 @@ type Observer interface {
// Registration is an token representing the unique registration of a callback
// for a set of instruments with a Meter.
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type Registration interface {
embedded.Registration
// Unregister removes the callback registration from a Meter.
//
// This method needs to be idempotent and concurrent safe.

View File

@ -28,6 +28,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
)
@ -55,7 +56,7 @@ var (
)
// MeterProvider is an OpenTelemetry No-Op MeterProvider.
type MeterProvider struct{}
type MeterProvider struct{ embedded.MeterProvider }
// NewMeterProvider returns a MeterProvider that does not record any telemetry.
func NewMeterProvider() MeterProvider {
@ -68,7 +69,7 @@ func (MeterProvider) Meter(string, ...metric.MeterOption) metric.Meter {
}
// Meter is an OpenTelemetry No-Op Meter.
type Meter struct{}
type Meter struct{ embedded.Meter }
// Int64Counter returns a Counter used to record int64 measurements that
// produces no telemetry.
@ -149,7 +150,7 @@ func (Meter) RegisterCallback(metric.Callback, ...instrument.Observable) (metric
// Observer acts as a recorder of measurements for multiple instruments in a
// Callback, it performing no operation.
type Observer struct{}
type Observer struct{ embedded.Observer }
// ObserveFloat64 performs no operation.
func (Observer) ObserveFloat64(instrument.Float64Observable, float64, ...attribute.KeyValue) {
@ -160,7 +161,7 @@ func (Observer) ObserveInt64(instrument.Int64Observable, int64, ...attribute.Key
}
// Registration is the registration of a Callback with a No-Op Meter.
type Registration struct{}
type Registration struct{ embedded.Registration }
// Unregister unregisters the Callback the Registration represents with the
// No-Op Meter. This will always return nil because the No-Op Meter performs no
@ -169,79 +170,97 @@ func (Registration) Unregister() error { return nil }
// Int64Counter is an OpenTelemetry Counter used to record int64 measurements.
// It produces no telemetry.
type Int64Counter struct{}
type Int64Counter struct{ embedded.Int64Counter }
// Add performs no operation.
func (Int64Counter) Add(context.Context, int64, ...attribute.KeyValue) {}
// Float64Counter is an OpenTelemetry Counter used to record float64
// measurements. It produces no telemetry.
type Float64Counter struct{}
type Float64Counter struct{ embedded.Float64Counter }
// Add performs no operation.
func (Float64Counter) Add(context.Context, float64, ...attribute.KeyValue) {}
// Int64UpDownCounter is an OpenTelemetry UpDownCounter used to record int64
// measurements. It produces no telemetry.
type Int64UpDownCounter struct{}
type Int64UpDownCounter struct{ embedded.Int64UpDownCounter }
// Add performs no operation.
func (Int64UpDownCounter) Add(context.Context, int64, ...attribute.KeyValue) {}
// Float64UpDownCounter is an OpenTelemetry UpDownCounter used to record
// float64 measurements. It produces no telemetry.
type Float64UpDownCounter struct{}
type Float64UpDownCounter struct{ embedded.Float64UpDownCounter }
// Add performs no operation.
func (Float64UpDownCounter) Add(context.Context, float64, ...attribute.KeyValue) {}
// Int64Histogram is an OpenTelemetry Histogram used to record int64
// measurements. It produces no telemetry.
type Int64Histogram struct{}
type Int64Histogram struct{ embedded.Int64Histogram }
// Record performs no operation.
func (Int64Histogram) Record(context.Context, int64, ...attribute.KeyValue) {}
// Float64Histogram is an OpenTelemetry Histogram used to record float64
// measurements. It produces no telemetry.
type Float64Histogram struct{}
type Float64Histogram struct{ embedded.Float64Histogram }
// Record performs no operation.
func (Float64Histogram) Record(context.Context, float64, ...attribute.KeyValue) {}
// Int64ObservableCounter is an OpenTelemetry ObservableCounter used to record
// int64 measurements. It produces no telemetry.
type Int64ObservableCounter struct{ instrument.Int64Observable }
type Int64ObservableCounter struct {
instrument.Int64Observable
embedded.Int64ObservableCounter
}
// Float64ObservableCounter is an OpenTelemetry ObservableCounter used to record
// float64 measurements. It produces no telemetry.
type Float64ObservableCounter struct{ instrument.Float64Observable }
type Float64ObservableCounter struct {
instrument.Float64Observable
embedded.Float64ObservableCounter
}
// Int64ObservableGauge is an OpenTelemetry ObservableGauge used to record
// int64 measurements. It produces no telemetry.
type Int64ObservableGauge struct{ instrument.Int64Observable }
type Int64ObservableGauge struct {
instrument.Int64Observable
embedded.Int64ObservableGauge
}
// Float64ObservableGauge is an OpenTelemetry ObservableGauge used to record
// float64 measurements. It produces no telemetry.
type Float64ObservableGauge struct{ instrument.Float64Observable }
type Float64ObservableGauge struct {
instrument.Float64Observable
embedded.Float64ObservableGauge
}
// Int64ObservableUpDownCounter is an OpenTelemetry ObservableUpDownCounter
// used to record int64 measurements. It produces no telemetry.
type Int64ObservableUpDownCounter struct{ instrument.Int64Observable }
type Int64ObservableUpDownCounter struct {
instrument.Int64Observable
embedded.Int64ObservableUpDownCounter
}
// Float64ObservableUpDownCounter is an OpenTelemetry ObservableUpDownCounter
// used to record float64 measurements. It produces no telemetry.
type Float64ObservableUpDownCounter struct{ instrument.Float64Observable }
type Float64ObservableUpDownCounter struct {
instrument.Float64Observable
embedded.Float64ObservableUpDownCounter
}
// Int64Observer is a recorder of int64 measurements that performs no operation.
type Int64Observer struct{}
type Int64Observer struct{ embedded.Int64Observer }
// Observe performs no operation.
func (Int64Observer) Observe(int64, ...attribute.KeyValue) {}
// Float64Observer is a recorder of float64 measurements that performs no
// operation.
type Float64Observer struct{}
type Float64Observer struct{ embedded.Float64Observer }
// Observe performs no operation.
func (Float64Observer) Observe(float64, ...attribute.KeyValue) {}

View File

@ -20,10 +20,11 @@ import (
"github.com/stretchr/testify/assert"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/noop"
)
type testMeterProvider struct{}
type testMeterProvider struct{ embedded.MeterProvider }
var _ metric.MeterProvider = &testMeterProvider{}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric/aggregation"
@ -171,6 +172,13 @@ type streamID struct {
type instrumentImpl[N int64 | float64] struct {
aggregators []internal.Aggregator[N]
embedded.Float64Counter
embedded.Float64UpDownCounter
embedded.Float64Histogram
embedded.Int64Counter
embedded.Int64UpDownCounter
embedded.Int64Histogram
}
var _ instrument.Float64Counter = (*instrumentImpl[float64])(nil)
@ -213,6 +221,10 @@ type observablID[N int64 | float64] struct {
type float64Observable struct {
instrument.Float64Observable
*observable[float64]
embedded.Float64ObservableCounter
embedded.Float64ObservableUpDownCounter
embedded.Float64ObservableGauge
}
var _ instrument.Float64ObservableCounter = float64Observable{}
@ -228,6 +240,10 @@ func newFloat64Observable(scope instrumentation.Scope, kind InstrumentKind, name
type int64Observable struct {
instrument.Int64Observable
*observable[int64]
embedded.Int64ObservableCounter
embedded.Int64ObservableUpDownCounter
embedded.Int64ObservableGauge
}
var _ instrument.Int64ObservableCounter = int64Observable{}

View File

@ -19,6 +19,7 @@ import (
"fmt"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/sdk/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
@ -87,6 +88,10 @@ func (p *meter) Int64Histogram(string, ...instrument.Int64HistogramOption) (inst
// histogram used for demonstration purposes only.
type inst struct {
aggregateFunc func(int64, attribute.Set)
embedded.Int64Counter
embedded.Int64UpDownCounter
embedded.Int64Histogram
}
func (inst) Add(context.Context, int64, ...attribute.KeyValue) {}

View File

@ -22,6 +22,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/internal/global"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric/internal"
@ -32,6 +33,8 @@ import (
// produced by an instrumentation scope will use metric instruments from a
// single meter.
type meter struct {
embedded.Meter
scope instrumentation.Scope
pipes pipelines
@ -264,6 +267,8 @@ func (m *meter) RegisterCallback(f metric.Callback, insts ...instrument.Observab
}
type observer struct {
embedded.Observer
float64 map[observablID[float64]]struct{}
int64 map[observablID[int64]]struct{}
}
@ -356,7 +361,7 @@ func (r observer) ObserveInt64(o instrument.Int64Observable, v int64, a ...attri
oImpl.observe(v, a)
}
type noopRegister struct{}
type noopRegister struct{ embedded.Registration }
func (noopRegister) Unregister() error {
return nil
@ -409,11 +414,12 @@ func (p int64ObservProvider) registerCallbacks(inst int64Observable, cBacks []in
}
func (p int64ObservProvider) callback(i int64Observable, f instrument.Int64Callback) func(context.Context) error {
inst := int64Observer{i}
inst := int64Observer{int64Observable: i}
return func(ctx context.Context) error { return f(ctx, inst) }
}
type int64Observer struct {
embedded.Int64Observer
int64Observable
}
@ -440,11 +446,12 @@ func (p float64ObservProvider) registerCallbacks(inst float64Observable, cBacks
}
func (p float64ObservProvider) callback(i float64Observable, f instrument.Float64Callback) func(context.Context) error {
inst := float64Observer{i}
inst := float64Observer{float64Observable: i}
return func(ctx context.Context) error { return f(ctx, inst) }
}
type float64Observer struct {
embedded.Float64Observer
float64Observable
}

View File

@ -24,6 +24,7 @@ import (
"go.opentelemetry.io/otel/internal/global"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/internal"
@ -503,13 +504,16 @@ func (p pipelines) registerMultiCallback(c multiCallback) metric.Registration {
for i, pipe := range p {
unregs[i] = pipe.addMultiCallback(c)
}
return unregisterFuncs(unregs)
return unregisterFuncs{f: unregs}
}
type unregisterFuncs []func()
type unregisterFuncs struct {
embedded.Registration
f []func()
}
func (u unregisterFuncs) Unregister() error {
for _, f := range u {
for _, f := range u.f {
f()
}
return nil

View File

@ -18,6 +18,7 @@ import (
"context"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/embedded"
"go.opentelemetry.io/otel/sdk/instrumentation"
)
@ -26,6 +27,8 @@ import (
// the same Views applied to them, and have their produced metric telemetry
// passed to the configured Readers.
type MeterProvider struct {
embedded.MeterProvider
pipes pipelines
meters cache[instrumentation.Scope, *meter]