Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype OTel-Go metrics APIv2 proposal #2044

Closed
wants to merge 20 commits into from
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.15
require (
github.com/google/go-cmp v0.5.6
github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel/metric v0.21.0
go.opentelemetry.io/otel/oteltest v1.0.0-RC1
go.opentelemetry.io/otel/trace v1.0.0-RC1
)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io v0.1.0 h1:EANZoRCOP+A3faIlw/iN6YEWoYb1vleZRKm1EvH8T48=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
27 changes: 27 additions & 0 deletions metric2/async/asyncmetric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package async
jmacd marked this conversation as resolved.
Show resolved Hide resolved

import (
"context"

metric "go.opentelemetry.io/otel/metric2"
asyncfloat64metric "go.opentelemetry.io/otel/metric2/async/float64"
asyncint64metric "go.opentelemetry.io/otel/metric2/async/int64"
)

type Meter struct {
}

type Callback struct {
}

func (m Meter) Callback(func(context.Context, Meter), ...metric.Instrument) Callback {
return Callback{}
}

func (m Meter) Integer() asyncint64metric.Meter {
return asyncint64metric.Meter{}
}

func (m Meter) FloatingPoint() asyncfloat64metric.Meter {
return asyncfloat64metric.Meter{}
}
66 changes: 66 additions & 0 deletions metric2/async/float64/asyncfloat64metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package asyncfloat64metric

import (
"context"

"go.opentelemetry.io/otel/attribute"
metric "go.opentelemetry.io/otel/metric2"
)

type Meter struct {
}

type Counter struct {
}

type UpDownCounter struct {
}

type Gauge struct {
}

type Instrument interface {
metric.Instrument

Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue)
Measure(x float64) metric.Measurement
}

var (
_ Instrument = Counter{}
_ Instrument = UpDownCounter{}
_ Instrument = Gauge{}
)

func (m Meter) Counter(name string) (Counter, error) {
return Counter{}, nil
}

func (m Meter) UpDownCounter(name string) (UpDownCounter, error) {
return UpDownCounter{}, nil
}

func (m Meter) Gauge(name string) (Gauge, error) {
return Gauge{}, nil
}

func (c Counter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (u UpDownCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (g Gauge) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (c Counter) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}

func (u UpDownCounter) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}

func (g Gauge) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}
66 changes: 66 additions & 0 deletions metric2/async/int64/asyncint64metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package asyncint64metric

import (
"context"

"go.opentelemetry.io/otel/attribute"
metric "go.opentelemetry.io/otel/metric2"
)

type Meter struct {
}

type Counter struct {
}

type UpDownCounter struct {
}

type Gauge struct {
}

type Instrument interface {
metric.Instrument

Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue)
Measure(x int64) metric.Measurement
}

var (
_ Instrument = Counter{}
_ Instrument = UpDownCounter{}
_ Instrument = Gauge{}
)

func (m Meter) Counter(name string) (Counter, error) {
return Counter{}, nil
}

func (m Meter) UpDownCounter(name string) (UpDownCounter, error) {
return UpDownCounter{}, nil
}

func (m Meter) Gauge(name string) (Gauge, error) {
return Gauge{}, nil
}

func (c Counter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (u UpDownCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (g Gauge) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (c Counter) Measure(x int64) metric.Measurement {
return metric.Measurement{}
}

func (u UpDownCounter) Measure(x int64) metric.Measurement {
return metric.Measurement{}
}

func (g Gauge) Measure(x int64) metric.Measurement {
return metric.Measurement{}
}
13 changes: 13 additions & 0 deletions metric2/instrument.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package metric2

import (
"go.opentelemetry.io/otel/metric/number"
)

type Measurement struct {
Instrument
number.Number
}

type Instrument interface {
}
53 changes: 53 additions & 0 deletions metric2/meter/meter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package meter

import (
"context"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric2/async"
"go.opentelemetry.io/otel/metric2/sync"
)

// MeterProvider supports creating named Meter instances, for
// instrumenting an application containing multiple libraries of code.
type MeterProvider interface {
Meter(instrumentationName string /*, opts ...MeterOption*/) Meter
}

// Meter is an instance of an OpenTelemetry metrics interface for an
// individual named library of code. This is the top-level entry
// point for creating instruments.
type Meter struct {
}

// Asynchronous provides access to an async.Meter for constructing
// asynchronous metric instruments.
func (m Meter) Asynchronous() async.Meter {
jmacd marked this conversation as resolved.
Show resolved Hide resolved
return async.Meter{}
}

// Synchronous provides access to a sync.Meter for constructing
// synchronous metric instruments.
func (m Meter) Synchronous() sync.Meter {
return sync.Meter{}
}

// ProcessBatch processes a batch of measurements as a single logical
// event.
func (m Meter) ProcessBatch(
ctx context.Context,
attrs []attribute.KeyValue,
batch ...metric.Measurement) {
}

// Process processes a single measurement. This offers the
// convenience of passing a variable length list of attributes for a
// processing a single measurement.
func (m Meter) Process(
ctx context.Context,
ms metric.Measurement,
attrs ...attribute.KeyValue) {
// Process a singleton batch
m.ProcessBatch(ctx, attrs, ms)
}
65 changes: 65 additions & 0 deletions metric2/sync/float64/syncfloat64metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package syncfloat64metric

import (
"context"

"go.opentelemetry.io/otel/attribute"
metric "go.opentelemetry.io/otel/metric2"
)

type Meter struct {
}

type Counter struct {
}

type UpDownCounter struct {
}

type Histogram struct {
}

type Instrument interface {
metric.Instrument

Measure(x float64) metric.Measurement
}

var (
_ Instrument = Counter{}
_ Instrument = UpDownCounter{}
_ Instrument = Histogram{}
)

func (m Meter) Counter(name string) (Counter, error) {
return Counter{}, nil
}

func (m Meter) UpDownCounter(name string) (UpDownCounter, error) {
return UpDownCounter{}, nil
}

func (m Meter) Histogram(name string) (Histogram, error) {
return Histogram{}, nil
}

func (c Counter) Add(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (u UpDownCounter) Add(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (h Histogram) Record(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
}

func (c Counter) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}

func (u UpDownCounter) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}

func (h Histogram) Measure(x float64) metric.Measurement {
return metric.Measurement{}
}
67 changes: 67 additions & 0 deletions metric2/sync/int64/syncint64metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package syncint64metric

import (
"context"

"go.opentelemetry.io/otel/attribute"
metric "go.opentelemetry.io/otel/metric2"
)

// TODO instrument options

type Meter struct {
}

type Counter struct {
}

type UpDownCounter struct {
}

type Histogram struct {
}

type Instrument interface {
metric.Instrument

Measure(x int64) metric.Measurement
}

var (
_ Instrument = Counter{}
_ Instrument = UpDownCounter{}
_ Instrument = Histogram{}
)

func (m Meter) Counter(name string) (Counter, error) {
return Counter{}, nil
}

func (m Meter) UpDownCounter(name string) (UpDownCounter, error) {
return UpDownCounter{}, nil
}

func (m Meter) Histogram(name string) (Histogram, error) {
return Histogram{}, nil
}

func (c Counter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (u UpDownCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (h Histogram) Record(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
}

func (c Counter) Measure(x int64) metric.Measurement {
return metric.Measurement{}
}

func (u UpDownCounter) Measure(x int64) metric.Measurement {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Measure do? Can it be removed? Maybe consider to be added later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Measure() creates a measurement for batch recording in both synchronous and asynchronous instruments, and it can be added later. My goal in sharing this prototype was to show how it would evolve to support batch measurements since that is an important way to optimize metrics costs. The other way that we know of to optimize at the API level involves binding instruments, which I left out of this proposal (and I consider less important than batch support).

return metric.Measurement{}
}

func (h Histogram) Measure(x int64) metric.Measurement {
return metric.Measurement{}
}
16 changes: 16 additions & 0 deletions metric2/sync/syncmetric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package sync

import (
syncfloat64metric "go.opentelemetry.io/otel/metric2/sync/float64"
syncint64metric "go.opentelemetry.io/otel/metric2/sync/int64"
)

type Meter struct{}

func (m Meter) Integer() syncint64metric.Meter {
return syncint64metric.Meter{}
}

func (m Meter) FloatingPoint() syncfloat64metric.Meter {
return syncfloat64metric.Meter{}
}