1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-09-16 09:26:25 +02:00

Metrics instrumentation version (#811)

* Support instrumentation library in metrics

* Update stdout exporter to display instrumentation info

* Fix tests that use the STDOUT exporter

* Refactor to keep SDK out of API

* Update global Meter and test Meter version

* Revert unneeded import syntax change

* Fix Unit comment

* Update comments

* Update comment

* Revert no-op change to import
This commit is contained in:
Tyler Yahn
2020-06-12 09:11:17 -07:00
committed by GitHub
parent 7d5117fafd
commit 288a3dd435
18 changed files with 338 additions and 209 deletions

View File

@@ -82,7 +82,7 @@ func (*benchFixture) CheckpointSet() export.CheckpointSet {
func (*benchFixture) FinishedCollection() {
}
func (fix *benchFixture) Meter(name string) metric.Meter {
func (fix *benchFixture) Meter(_ string, _ ...metric.MeterOption) metric.Meter {
return fix.meter
}

View File

@@ -46,6 +46,10 @@ import (
// Metric uniqueness checking is implemented by calling the exported
// methods of the api/metric/registry package.
type meterKey struct {
Name, Version string
}
type meterProvider struct {
delegate metric.Provider
@@ -54,7 +58,7 @@ type meterProvider struct {
// meters maintains a unique entry for every named Meter
// that has been registered through the global instance.
meters map[string]*meterEntry
meters map[meterKey]*meterEntry
}
type meterImpl struct {
@@ -123,7 +127,7 @@ func (inst *instrument) Descriptor() metric.Descriptor {
func newMeterProvider() *meterProvider {
return &meterProvider{
meters: map[string]*meterEntry{},
meters: map[meterKey]*meterEntry{},
}
}
@@ -132,38 +136,42 @@ func (p *meterProvider) setDelegate(provider metric.Provider) {
defer p.lock.Unlock()
p.delegate = provider
for name, entry := range p.meters {
entry.impl.setDelegate(name, provider)
for key, entry := range p.meters {
entry.impl.setDelegate(key.Name, key.Version, provider)
}
p.meters = nil
}
func (p *meterProvider) Meter(name string) metric.Meter {
func (p *meterProvider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
p.lock.Lock()
defer p.lock.Unlock()
if p.delegate != nil {
return p.delegate.Meter(name)
return p.delegate.Meter(instrumentationName, opts...)
}
entry, ok := p.meters[name]
key := meterKey{
Name: instrumentationName,
Version: metric.ConfigureMeter(opts).InstrumentationVersion,
}
entry, ok := p.meters[key]
if !ok {
entry = &meterEntry{}
entry.unique = registry.NewUniqueInstrumentMeterImpl(&entry.impl)
p.meters[name] = entry
p.meters[key] = entry
}
return metric.WrapMeterImpl(entry.unique, name)
return metric.WrapMeterImpl(entry.unique, key.Name, metric.WithInstrumentationVersion(key.Version))
}
// Meter interface and delegation
func (m *meterImpl) setDelegate(name string, provider metric.Provider) {
func (m *meterImpl) setDelegate(name, version string, provider metric.Provider) {
m.lock.Lock()
defer m.lock.Unlock()
d := new(metric.MeterImpl)
*d = provider.Meter(name).MeterImpl()
*d = provider.Meter(name, metric.WithInstrumentationVersion(version)).MeterImpl()
m.delegate = unsafe.Pointer(d)
for _, inst := range m.syncInsts {

View File

@@ -36,10 +36,11 @@ import (
// Note: Maybe this should be factored into ../../../internal/metric?
type measured struct {
Name string
LibraryName string
Labels map[kv.Key]value.Value
Number metric.Number
Name string
InstrumentationName string
InstrumentationVersion string
Labels map[kv.Key]value.Value
Number metric.Number
}
func asStructs(batches []metrictest.Batch) []measured {
@@ -47,10 +48,11 @@ func asStructs(batches []metrictest.Batch) []measured {
for _, batch := range batches {
for _, m := range batch.Measurements {
r = append(r, measured{
Name: m.Instrument.Descriptor().Name(),
LibraryName: m.Instrument.Descriptor().LibraryName(),
Labels: asMap(batch.Labels...),
Number: m.Number,
Name: m.Instrument.Descriptor().Name(),
InstrumentationName: m.Instrument.Descriptor().InstrumentationName(),
InstrumentationVersion: m.Instrument.Descriptor().InstrumentationVersion(),
Labels: asMap(batch.Labels...),
Number: m.Number,
})
}
}
@@ -72,7 +74,7 @@ func TestDirect(t *testing.T) {
internal.ResetForTest()
ctx := context.Background()
meter1 := global.Meter("test1")
meter1 := global.Meter("test1", metric.WithInstrumentationVersion("semver:v1.0.0"))
meter2 := global.Meter("test2")
labels1 := []kv.KeyValue{kv.String("A", "B")}
labels2 := []kv.KeyValue{kv.String("C", "D")}
@@ -114,46 +116,52 @@ func TestDirect(t *testing.T) {
require.EqualValues(t,
[]measured{
{
Name: "test.counter",
LibraryName: "test1",
Labels: asMap(labels1...),
Number: asInt(1),
Name: "test.counter",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels1...),
Number: asInt(1),
},
{
Name: "test.valuerecorder",
LibraryName: "test1",
Labels: asMap(labels1...),
Number: asFloat(3),
Name: "test.valuerecorder",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels1...),
Number: asFloat(3),
},
{
Name: "test.second",
LibraryName: "test2",
Labels: asMap(labels3...),
Number: asFloat(3),
Name: "test.second",
InstrumentationName: "test2",
Labels: asMap(labels3...),
Number: asFloat(3),
},
{
Name: "test.valueobserver.float",
LibraryName: "test1",
Labels: asMap(labels1...),
Number: asFloat(1),
Name: "test.valueobserver.float",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels1...),
Number: asFloat(1),
},
{
Name: "test.valueobserver.float",
LibraryName: "test1",
Labels: asMap(labels2...),
Number: asFloat(2),
Name: "test.valueobserver.float",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels2...),
Number: asFloat(2),
},
{
Name: "test.valueobserver.int",
LibraryName: "test1",
Labels: asMap(labels1...),
Number: asInt(1),
Name: "test.valueobserver.int",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels1...),
Number: asInt(1),
},
{
Name: "test.valueobserver.int",
LibraryName: "test1",
Labels: asMap(labels2...),
Number: asInt(2),
Name: "test.valueobserver.int",
InstrumentationName: "test1",
InstrumentationVersion: "semver:v1.0.0",
Labels: asMap(labels2...),
Number: asInt(2),
},
},
measurements,
@@ -188,16 +196,16 @@ func TestBound(t *testing.T) {
require.EqualValues(t,
[]measured{
{
Name: "test.counter",
LibraryName: "test",
Labels: asMap(labels1...),
Number: asFloat(1),
Name: "test.counter",
InstrumentationName: "test",
Labels: asMap(labels1...),
Number: asFloat(1),
},
{
Name: "test.valuerecorder",
LibraryName: "test",
Labels: asMap(labels1...),
Number: asInt(3),
Name: "test.valuerecorder",
InstrumentationName: "test",
Labels: asMap(labels1...),
Number: asInt(3),
},
},
asStructs(mock.MeasurementBatches))
@@ -254,7 +262,7 @@ func TestDefaultSDK(t *testing.T) {
pusher.Stop()
out.Close()
require.Equal(t, `{"updates":[{"name":"test.builtin{A=B}","sum":1}]}
require.Equal(t, `{"updates":[{"name":"test.builtin{instrumentation.name=builtin,A=B}","sum":1}]}
`, <-ch)
}
@@ -284,8 +292,8 @@ type meterWithConstructorError struct {
metric.MeterImpl
}
func (m *meterProviderWithConstructorError) Meter(name string) metric.Meter {
return metric.WrapMeterImpl(&meterWithConstructorError{m.Provider.Meter(name).MeterImpl()}, name)
func (m *meterProviderWithConstructorError) Meter(iName string, opts ...metric.MeterOption) metric.Meter {
return metric.WrapMeterImpl(&meterWithConstructorError{m.Provider.Meter(iName, opts...).MeterImpl()}, iName, opts...)
}
func (m *meterWithConstructorError) NewSyncInstrument(_ metric.Descriptor) (metric.SyncImpl, error) {
@@ -380,10 +388,10 @@ func TestRecordBatchMock(t *testing.T) {
require.EqualValues(t,
[]measured{
{
Name: "test.counter",
LibraryName: "builtin",
Labels: asMap(),
Number: asInt(1),
Name: "test.counter",
InstrumentationName: "builtin",
Labels: asMap(),
Number: asInt(1),
},
},
asStructs(mock.MeasurementBatches))
@@ -412,6 +420,6 @@ func TestRecordBatchRealSDK(t *testing.T) {
meter.RecordBatch(context.Background(), nil, counter.Measurement(1))
pusher.Stop()
require.Equal(t, `{"updates":[{"name":"test.counter","sum":1}]}
require.Equal(t, `{"updates":[{"name":"test.counter{instrumentation.name=builtin}","sum":1}]}
`, buf.String())
}

View File

@@ -19,12 +19,16 @@ import (
"go.opentelemetry.io/otel/api/metric"
)
// Meter gets a named Meter interface. If the name is an
// empty string, the provider uses a default name.
// Meter creates an implementation of the Meter interface from the global
// Provider. The instrumentationName must be the name of the library
// providing instrumentation. This name may be the same as the instrumented
// code only if that code provides built-in instrumentation. If the
// instrumentationName is empty, then a implementation defined default name
// will be used instead.
//
// This is short for MeterProvider().Meter(name)
func Meter(name string) metric.Meter {
return MeterProvider().Meter(name)
func Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
return MeterProvider().Meter(instrumentationName, opts...)
}
// MeterProvider returns the registered global meter provider. If

View File

@@ -25,7 +25,7 @@ type testMeterProvider struct{}
var _ metric.Provider = &testMeterProvider{}
func (*testMeterProvider) Meter(_ string) metric.Meter {
func (*testMeterProvider) Meter(_ string, _ ...metric.MeterOption) metric.Meter {
return metric.Meter{}
}

View File

@@ -36,7 +36,7 @@ var Must = metric.Must
func TestOptions(t *testing.T) {
type testcase struct {
name string
opts []metric.Option
opts []metric.InstrumentOption
desc string
unit unit.Unit
}
@@ -49,7 +49,7 @@ func TestOptions(t *testing.T) {
},
{
name: "description",
opts: []metric.Option{
opts: []metric.InstrumentOption{
metric.WithDescription("stuff"),
},
desc: "stuff",
@@ -57,7 +57,7 @@ func TestOptions(t *testing.T) {
},
{
name: "description override",
opts: []metric.Option{
opts: []metric.InstrumentOption{
metric.WithDescription("stuff"),
metric.WithDescription("things"),
},
@@ -66,7 +66,7 @@ func TestOptions(t *testing.T) {
},
{
name: "unit",
opts: []metric.Option{
opts: []metric.InstrumentOption{
metric.WithUnit("s"),
},
desc: "",
@@ -74,7 +74,7 @@ func TestOptions(t *testing.T) {
},
{
name: "unit override",
opts: []metric.Option{
opts: []metric.InstrumentOption{
metric.WithUnit("s"),
metric.WithUnit("h"),
},
@@ -84,7 +84,7 @@ func TestOptions(t *testing.T) {
}
for idx, tt := range testcases {
t.Logf("Testing counter case %s (%d)", tt.name, idx)
if diff := cmp.Diff(metric.Configure(tt.opts), metric.Config{
if diff := cmp.Diff(metric.ConfigureInstrument(tt.opts), metric.InstrumentConfig{
Description: tt.desc,
Unit: tt.unit,
}); diff != "" {

View File

@@ -16,69 +16,110 @@ package metric
import "go.opentelemetry.io/otel/api/unit"
// Config contains some options for metrics of any kind.
type Config struct {
// Description is an optional field describing the metric
// instrument.
// InstrumentConfig contains options for instrument descriptors.
type InstrumentConfig struct {
// Description describes the instrument in human-readable terms.
Description string
// Unit is an optional field describing the metric instrument.
// Unit describes the measurement unit for a instrument.
Unit unit.Unit
// LibraryName is the name given to the Meter that created
// this instrument. See `Provider`.
LibraryName string
// InstrumentationName is the name of the library providing
// instrumentation.
InstrumentationName string
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// Option is an interface for applying metric options.
type Option interface {
// Apply is used to set the Option value of a Config.
Apply(*Config)
// InstrumentOption is an interface for applying instrument options.
type InstrumentOption interface {
// ApplyMeter is used to set a InstrumentOption value of a
// InstrumentConfig.
ApplyInstrument(*InstrumentConfig)
}
// Configure is a helper that applies all the options to a Config.
func Configure(opts []Option) Config {
var config Config
// ConfigureInstrument is a helper that applies all the InstrumentOptions
// to an InstrumentConfig.
func ConfigureInstrument(opts []InstrumentOption) InstrumentConfig {
var config InstrumentConfig
for _, o := range opts {
o.Apply(&config)
o.ApplyInstrument(&config)
}
return config
}
// WithDescription applies provided description.
func WithDescription(desc string) Option {
func WithDescription(desc string) InstrumentOption {
return descriptionOption(desc)
}
type descriptionOption string
func (d descriptionOption) Apply(config *Config) {
func (d descriptionOption) ApplyInstrument(config *InstrumentConfig) {
config.Description = string(d)
}
// WithUnit applies provided unit.
func WithUnit(unit unit.Unit) Option {
func WithUnit(unit unit.Unit) InstrumentOption {
return unitOption(unit)
}
type unitOption unit.Unit
func (u unitOption) Apply(config *Config) {
func (u unitOption) ApplyInstrument(config *InstrumentConfig) {
config.Unit = unit.Unit(u)
}
// WithLibraryName applies provided library name. This is meant for
// use in `Provider` implementations that have not used
// `WrapMeterImpl`. Implementations built using `WrapMeterImpl` have
// instrument descriptors taken care of through this package.
//
// This option will have no effect when supplied by the user.
// Provider implementations are expected to append this option after
// the user-supplied options when building instrument descriptors.
func WithLibraryName(name string) Option {
return libraryNameOption(name)
// WithInstrumentationName sets the instrumentation name.
func WithInstrumentationName(name string) InstrumentOption {
return instrumentationNameOption(name)
}
type libraryNameOption string
type instrumentationNameOption string
func (r libraryNameOption) Apply(config *Config) {
config.LibraryName = string(r)
func (i instrumentationNameOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationName = string(i)
}
// MeterConfig contains options for Meters.
type MeterConfig struct {
// InstrumentationVersion is the version of the library providing
// instrumentation.
InstrumentationVersion string
}
// MeterOption is an interface for applying Meter options.
type MeterOption interface {
// ApplyMeter is used to set a MeterOption value of a MeterConfig.
ApplyMeter(*MeterConfig)
}
// ConfigureMeter is a helper that applies all the MeterOptions to a
// MeterConfig.
func ConfigureMeter(opts []MeterOption) MeterConfig {
var config MeterConfig
for _, o := range opts {
o.ApplyMeter(&config)
}
return config
}
// Option is an interface for applying Instrument or Meter options.
type Option interface {
InstrumentOption
MeterOption
}
// WithInstrumentationVersion sets the instrumentation version.
func WithInstrumentationVersion(version string) Option {
return instrumentationVersionOption(version)
}
type instrumentationVersionOption string
func (i instrumentationVersionOption) ApplyMeter(config *MeterConfig) {
config.InstrumentationVersion = string(i)
}
func (i instrumentationVersionOption) ApplyInstrument(config *InstrumentConfig) {
config.InstrumentationVersion = string(i)
}

View File

@@ -23,16 +23,16 @@ type Descriptor struct {
name string
kind Kind
numberKind NumberKind
config Config
config InstrumentConfig
}
// NewDescriptor returns a Descriptor with the given contents.
func NewDescriptor(name string, mkind Kind, nkind NumberKind, opts ...Option) Descriptor {
func NewDescriptor(name string, mkind Kind, nkind NumberKind, opts ...InstrumentOption) Descriptor {
return Descriptor{
name: name,
kind: mkind,
numberKind: nkind,
config: Configure(opts),
config: ConfigureInstrument(opts),
}
}
@@ -64,8 +64,14 @@ func (d Descriptor) NumberKind() NumberKind {
return d.numberKind
}
// LibraryName returns the metric instrument's library name, typically
// given via a call to Provider.Meter().
func (d Descriptor) LibraryName() string {
return d.config.LibraryName
// InstrumentationName returns the name of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationName() string {
return d.config.InstrumentationName
}
// InstrumentationVersion returns the version of the library that provided
// instrumentation for this instrument.
func (d Descriptor) InstrumentationVersion() string {
return d.config.InstrumentationVersion
}

View File

@@ -33,9 +33,13 @@ import (
// Provider supports named Meter instances.
type Provider interface {
// Meter gets a named Meter interface. If the name is an
// empty string, the provider uses a default name.
Meter(name string) Meter
// Meter creates an implementation of the Meter interface.
// The instrumentationName must be the name of the library providing
// instrumentation. This name may be the same as the instrumented code
// only if that code provides built-in instrumentation. If the
// instrumentationName is empty, then a implementation defined default
// name will be used instead.
Meter(instrumentationName string, opts ...MeterOption) Meter
}
// Meter is the OpenTelemetry metric API, based on a `MeterImpl`
@@ -43,8 +47,8 @@ type Provider interface {
//
// An uninitialized Meter is a no-op implementation.
type Meter struct {
impl MeterImpl
libraryName string
impl MeterImpl
name, version string
}
// RecordBatch atomically records a batch of measurements.
@@ -68,7 +72,7 @@ func (m Meter) NewBatchObserver(callback BatchObserverCallback) BatchObserver {
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewInt64Counter(name string, options ...Option) (Int64Counter, error) {
func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) {
return wrapInt64CounterInstrument(
m.newSync(name, CounterKind, Int64NumberKind, options))
}
@@ -77,7 +81,7 @@ func (m Meter) NewInt64Counter(name string, options ...Option) (Int64Counter, er
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewFloat64Counter(name string, options ...Option) (Float64Counter, error) {
func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) {
return wrapFloat64CounterInstrument(
m.newSync(name, CounterKind, Float64NumberKind, options))
}
@@ -86,7 +90,7 @@ func (m Meter) NewFloat64Counter(name string, options ...Option) (Float64Counter
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewInt64UpDownCounter(name string, options ...Option) (Int64UpDownCounter, error) {
func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) {
return wrapInt64UpDownCounterInstrument(
m.newSync(name, UpDownCounterKind, Int64NumberKind, options))
}
@@ -95,7 +99,7 @@ func (m Meter) NewInt64UpDownCounter(name string, options ...Option) (Int64UpDow
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewFloat64UpDownCounter(name string, options ...Option) (Float64UpDownCounter, error) {
func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) {
return wrapFloat64UpDownCounterInstrument(
m.newSync(name, UpDownCounterKind, Float64NumberKind, options))
}
@@ -104,7 +108,7 @@ func (m Meter) NewFloat64UpDownCounter(name string, options ...Option) (Float64U
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewInt64ValueRecorder(name string, opts ...Option) (Int64ValueRecorder, error) {
func (m Meter) NewInt64ValueRecorder(name string, opts ...InstrumentOption) (Int64ValueRecorder, error) {
return wrapInt64ValueRecorderInstrument(
m.newSync(name, ValueRecorderKind, Int64NumberKind, opts))
}
@@ -113,7 +117,7 @@ func (m Meter) NewInt64ValueRecorder(name string, opts ...Option) (Int64ValueRec
// given name, customized with options. May return an error if the
// name is invalid (e.g., empty) or improperly registered (e.g.,
// duplicate registration).
func (m Meter) NewFloat64ValueRecorder(name string, opts ...Option) (Float64ValueRecorder, error) {
func (m Meter) NewFloat64ValueRecorder(name string, opts ...InstrumentOption) (Float64ValueRecorder, error) {
return wrapFloat64ValueRecorderInstrument(
m.newSync(name, ValueRecorderKind, Float64NumberKind, opts))
}
@@ -122,7 +126,7 @@ func (m Meter) NewFloat64ValueRecorder(name string, opts ...Option) (Float64Valu
// with the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverCallback, opts ...Option) (Int64ValueObserver, error) {
func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverCallback, opts ...InstrumentOption) (Int64ValueObserver, error) {
if callback == nil {
return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
}
@@ -135,7 +139,7 @@ func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverCallback
// the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverCallback, opts ...Option) (Float64ValueObserver, error) {
func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64ValueObserver, error) {
if callback == nil {
return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
}
@@ -148,7 +152,7 @@ func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverCall
// with the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverCallback, opts ...Option) (Int64SumObserver, error) {
func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverCallback, opts ...InstrumentOption) (Int64SumObserver, error) {
if callback == nil {
return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
}
@@ -161,7 +165,7 @@ func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverCallback,
// the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverCallback, opts ...Option) (Float64SumObserver, error) {
func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64SumObserver, error) {
if callback == nil {
return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
}
@@ -174,7 +178,7 @@ func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverCallba
// with the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverCallback, opts ...Option) (Int64UpDownSumObserver, error) {
func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverCallback, opts ...InstrumentOption) (Int64UpDownSumObserver, error) {
if callback == nil {
return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
}
@@ -187,7 +191,7 @@ func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverCall
// the given name, running a given callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64ObserverCallback, opts ...Option) (Float64UpDownSumObserver, error) {
func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64UpDownSumObserver, error) {
if callback == nil {
return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
}
@@ -200,7 +204,7 @@ func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64Observer
// with the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64ValueObserver(name string, opts ...Option) (Int64ValueObserver, error) {
func (b BatchObserver) NewInt64ValueObserver(name string, opts ...InstrumentOption) (Int64ValueObserver, error) {
if b.runner == nil {
return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
}
@@ -212,7 +216,7 @@ func (b BatchObserver) NewInt64ValueObserver(name string, opts ...Option) (Int64
// the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...Option) (Float64ValueObserver, error) {
func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...InstrumentOption) (Float64ValueObserver, error) {
if b.runner == nil {
return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
}
@@ -225,7 +229,7 @@ func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...Option) (Flo
// with the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64SumObserver(name string, opts ...Option) (Int64SumObserver, error) {
func (b BatchObserver) NewInt64SumObserver(name string, opts ...InstrumentOption) (Int64SumObserver, error) {
if b.runner == nil {
return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
}
@@ -237,7 +241,7 @@ func (b BatchObserver) NewInt64SumObserver(name string, opts ...Option) (Int64Su
// the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64SumObserver(name string, opts ...Option) (Float64SumObserver, error) {
func (b BatchObserver) NewFloat64SumObserver(name string, opts ...InstrumentOption) (Float64SumObserver, error) {
if b.runner == nil {
return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
}
@@ -250,7 +254,7 @@ func (b BatchObserver) NewFloat64SumObserver(name string, opts ...Option) (Float
// with the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...Option) (Int64UpDownSumObserver, error) {
func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...InstrumentOption) (Int64UpDownSumObserver, error) {
if b.runner == nil {
return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
}
@@ -262,7 +266,7 @@ func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...Option) (I
// the given name, running in a batch callback, and customized with
// options. May return an error if the name is invalid (e.g., empty)
// or improperly registered (e.g., duplicate registration).
func (b BatchObserver) NewFloat64UpDownSumObserver(name string, opts ...Option) (Float64UpDownSumObserver, error) {
func (b BatchObserver) NewFloat64UpDownSumObserver(name string, opts ...InstrumentOption) (Float64UpDownSumObserver, error) {
if b.runner == nil {
return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
}
@@ -281,7 +285,7 @@ func (m Meter) newAsync(
name string,
mkind Kind,
nkind NumberKind,
opts []Option,
opts []InstrumentOption,
runner AsyncRunner,
) (
AsyncImpl,
@@ -291,7 +295,8 @@ func (m Meter) newAsync(
return NoopAsync{}, nil
}
desc := NewDescriptor(name, mkind, nkind, opts...)
desc.config.LibraryName = m.libraryName
desc.config.InstrumentationName = m.name
desc.config.InstrumentationVersion = m.version
return m.impl.NewAsyncInstrument(desc, runner)
}
@@ -300,7 +305,7 @@ func (m Meter) newSync(
name string,
metricKind Kind,
numberKind NumberKind,
opts []Option,
opts []InstrumentOption,
) (
SyncImpl,
error,
@@ -309,6 +314,7 @@ func (m Meter) newSync(
return NoopSync{}, nil
}
desc := NewDescriptor(name, metricKind, numberKind, opts...)
desc.config.LibraryName = m.libraryName
desc.config.InstrumentationName = m.name
desc.config.InstrumentationVersion = m.version
return m.impl.NewSyncInstrument(desc)
}

View File

@@ -35,7 +35,7 @@ func Must(meter Meter) MeterMust {
// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64Counter(name string, cos ...Option) Int64Counter {
func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter {
if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
panic(err)
} else {
@@ -45,7 +45,7 @@ func (mm MeterMust) NewInt64Counter(name string, cos ...Option) Int64Counter {
// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64Counter(name string, cos ...Option) Float64Counter {
func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter {
if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
panic(err)
} else {
@@ -55,7 +55,7 @@ func (mm MeterMust) NewFloat64Counter(name string, cos ...Option) Float64Counter
// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...Option) Int64UpDownCounter {
func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter {
if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
@@ -65,7 +65,7 @@ func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...Option) Int64UpDow
// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...Option) Float64UpDownCounter {
func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter {
if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil {
panic(err)
} else {
@@ -75,7 +75,7 @@ func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...Option) Float64U
// NewInt64ValueRecorder calls `Meter.NewInt64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...Option) Int64ValueRecorder {
func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...InstrumentOption) Int64ValueRecorder {
if inst, err := mm.meter.NewInt64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
@@ -85,7 +85,7 @@ func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...Option) Int64Value
// NewFloat64ValueRecorder calls `Meter.NewFloat64ValueRecorder` and returns the
// instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...Option) Float64ValueRecorder {
func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...InstrumentOption) Float64ValueRecorder {
if inst, err := mm.meter.NewFloat64ValueRecorder(name, mos...); err != nil {
panic(err)
} else {
@@ -95,7 +95,7 @@ func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...Option) Float64V
// NewInt64ValueObserver calls `Meter.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverCallback, oos ...Option) Int64ValueObserver {
func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverCallback, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := mm.meter.NewInt64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -105,7 +105,7 @@ func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverCal
// NewFloat64ValueObserver calls `Meter.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverCallback, oos ...Option) Float64ValueObserver {
func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverCallback, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := mm.meter.NewFloat64ValueObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -115,7 +115,7 @@ func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64Observe
// NewInt64SumObserver calls `Meter.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverCallback, oos ...Option) Int64SumObserver {
func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverCallback, oos ...InstrumentOption) Int64SumObserver {
if inst, err := mm.meter.NewInt64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -125,7 +125,7 @@ func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverCallb
// NewFloat64SumObserver calls `Meter.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverCallback, oos ...Option) Float64SumObserver {
func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverCallback, oos ...InstrumentOption) Float64SumObserver {
if inst, err := mm.meter.NewFloat64SumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -135,7 +135,7 @@ func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverC
// NewInt64UpDownSumObserver calls `Meter.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverCallback, oos ...Option) Int64UpDownSumObserver {
func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverCallback, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := mm.meter.NewInt64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -145,7 +145,7 @@ func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64Observe
// NewFloat64UpDownSumObserver calls `Meter.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverCallback, oos ...Option) Float64UpDownSumObserver {
func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverCallback, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := mm.meter.NewFloat64UpDownSumObserver(name, callback, oos...); err != nil {
panic(err)
} else {
@@ -163,7 +163,7 @@ func (mm MeterMust) NewBatchObserver(callback BatchObserverCallback) BatchObserv
// NewInt64ValueObserver calls `BatchObserver.NewInt64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...Option) Int64ValueObserver {
func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...InstrumentOption) Int64ValueObserver {
if inst, err := bm.batch.NewInt64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
@@ -173,7 +173,7 @@ func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...Option) In
// NewFloat64ValueObserver calls `BatchObserver.NewFloat64ValueObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...Option) Float64ValueObserver {
func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...InstrumentOption) Float64ValueObserver {
if inst, err := bm.batch.NewFloat64ValueObserver(name, oos...); err != nil {
panic(err)
} else {
@@ -183,7 +183,7 @@ func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...Option)
// NewInt64SumObserver calls `BatchObserver.NewInt64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...Option) Int64SumObserver {
func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...InstrumentOption) Int64SumObserver {
if inst, err := bm.batch.NewInt64SumObserver(name, oos...); err != nil {
panic(err)
} else {
@@ -193,7 +193,7 @@ func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...Option) Int6
// NewFloat64SumObserver calls `BatchObserver.NewFloat64SumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...Option) Float64SumObserver {
func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...InstrumentOption) Float64SumObserver {
if inst, err := bm.batch.NewFloat64SumObserver(name, oos...); err != nil {
panic(err)
} else {
@@ -203,7 +203,7 @@ func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...Option) Fl
// NewInt64UpDownSumObserver calls `BatchObserver.NewInt64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...Option) Int64UpDownSumObserver {
func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...InstrumentOption) Int64UpDownSumObserver {
if inst, err := bm.batch.NewInt64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {
@@ -213,7 +213,7 @@ func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...Option
// NewFloat64UpDownSumObserver calls `BatchObserver.NewFloat64UpDownSumObserver` and
// returns the instrument, panicking if it encounters an error.
func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...Option) Float64UpDownSumObserver {
func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...InstrumentOption) Float64UpDownSumObserver {
if inst, err := bm.batch.NewFloat64UpDownSumObserver(name, oos...); err != nil {
panic(err)
} else {

View File

@@ -32,7 +32,7 @@ var _ SyncImpl = NoopSync{}
var _ BoundSyncImpl = noopBoundInstrument{}
var _ AsyncImpl = NoopAsync{}
func (NoopProvider) Meter(name string) Meter {
func (NoopProvider) Meter(_ string, _ ...MeterOption) Meter {
return Meter{}
}

View File

@@ -42,8 +42,9 @@ type uniqueInstrumentMeterImpl struct {
var _ metric.MeterImpl = (*uniqueInstrumentMeterImpl)(nil)
type key struct {
name string
libraryName string
instrumentName string
instrumentationName string
InstrumentationVersion string
}
// NewProvider returns a new provider that implements instrument
@@ -55,8 +56,8 @@ func NewProvider(impl metric.MeterImpl) *Provider {
}
// Meter implements metric.Provider.
func (p *Provider) Meter(name string) metric.Meter {
return metric.WrapMeterImpl(p.impl, name)
func (p *Provider) Meter(instrumentationName string, opts ...metric.MeterOption) metric.Meter {
return metric.WrapMeterImpl(p.impl, instrumentationName, opts...)
}
// ErrMetricKindMismatch is the standard error for mismatched metric
@@ -81,16 +82,18 @@ func (u *uniqueInstrumentMeterImpl) RecordBatch(ctx context.Context, labels []kv
func keyOf(descriptor metric.Descriptor) key {
return key{
descriptor.Name(),
descriptor.LibraryName(),
descriptor.InstrumentationName(),
descriptor.InstrumentationVersion(),
}
}
// NewMetricKindMismatchError formats an error that describes a
// mismatched metric instrument definition.
func NewMetricKindMismatchError(desc metric.Descriptor) error {
return fmt.Errorf("Metric was %s (%s) registered as a %s %s: %w",
return fmt.Errorf("Metric was %s (%s %s)registered as a %s %s: %w",
desc.Name(),
desc.LibraryName(),
desc.InstrumentationName(),
desc.InstrumentationVersion(),
desc.NumberKind(),
desc.MetricKind(),
ErrMetricKindMismatch)

View File

@@ -85,9 +85,10 @@ type AsyncImpl interface {
// WrapMeterImpl constructs a `Meter` implementation from a
// `MeterImpl` implementation.
func WrapMeterImpl(impl MeterImpl, libraryName string) Meter {
func WrapMeterImpl(impl MeterImpl, instrumentatioName string, opts ...MeterOption) Meter {
return Meter{
impl: impl,
libraryName: libraryName,
impl: impl,
name: instrumentatioName,
version: ConfigureMeter(opts).InstrumentationVersion,
}
}

View File

@@ -37,7 +37,10 @@ func ExampleNewExportPipeline() {
ctx := context.Background()
key := kv.Key("key")
meter := pusher.Provider().Meter("example")
meter := pusher.Provider().Meter(
"github.com/instrumentron",
metric.WithInstrumentationVersion("v0.1.0"),
)
// Create and update a single counter:
counter := metric.Must(meter).NewInt64Counter("a.counter")
@@ -49,7 +52,7 @@ func ExampleNewExportPipeline() {
// {
// "updates": [
// {
// "name": "a.counter{key=value}",
// "name": "a.counter{instrumentation.name=github.com/instrumentron,instrumentation.version=v0.1.0,key=value}",
// "sum": 100
// }
// ]

View File

@@ -24,6 +24,7 @@ import (
"time"
"go.opentelemetry.io/otel/api/global"
"go.opentelemetry.io/otel/api/kv"
"go.opentelemetry.io/otel/api/label"
export "go.opentelemetry.io/otel/sdk/export/metric"
@@ -162,6 +163,16 @@ func (e *Exporter) Export(_ context.Context, checkpointSet export.CheckpointSet)
kind := desc.NumberKind()
encodedResource := record.Resource().Encoded(e.config.LabelEncoder)
var instLabels []kv.KeyValue
if name := desc.InstrumentationName(); name != "" {
instLabels = append(instLabels, kv.String("instrumentation.name", name))
if version := desc.InstrumentationVersion(); version != "" {
instLabels = append(instLabels, kv.String("instrumentation.version", version))
}
}
instSet := label.NewSet(instLabels...)
encodedInstLabels := instSet.Encoded(e.config.LabelEncoder)
var expose expoLine
if sum, ok := agg.(aggregation.Sum); ok {
@@ -230,10 +241,14 @@ func (e *Exporter) Export(_ context.Context, checkpointSet export.CheckpointSet)
sb.WriteString(desc.Name())
if len(encodedLabels) > 0 || len(encodedResource) > 0 {
if len(encodedLabels) > 0 || len(encodedResource) > 0 || len(encodedInstLabels) > 0 {
sb.WriteRune('{')
sb.WriteString(encodedResource)
if len(encodedLabels) > 0 && len(encodedResource) > 0 {
if len(encodedInstLabels) > 0 && len(encodedResource) > 0 {
sb.WriteRune(',')
}
sb.WriteString(encodedInstLabels)
if len(encodedLabels) > 0 && (len(encodedInstLabels) > 0 || len(encodedResource) > 0) {
sb.WriteRune(',')
}
sb.WriteString(encodedLabels)

View File

@@ -31,6 +31,7 @@ import (
"go.opentelemetry.io/otel/api/metric"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/resource"
)
@@ -53,10 +54,10 @@ var (
// result is the product of transforming Records into OTLP Metrics.
type result struct {
Resource *resource.Resource
Library string
Metric *metricpb.Metric
Err error
Resource *resource.Resource
InstrumentationLibrary instrumentation.Library
Metric *metricpb.Metric
Err error
}
// CheckpointSet transforms all records contained in a checkpoint into
@@ -125,9 +126,12 @@ func transformer(ctx context.Context, in <-chan export.Record, out chan<- result
}
res := result{
Resource: r.Resource(),
Library: r.Descriptor().LibraryName(),
Metric: m,
Err: err,
InstrumentationLibrary: instrumentation.Library{
Name: r.Descriptor().InstrumentationName(),
Version: r.Descriptor().InstrumentationVersion(),
},
Metric: m,
Err: err,
}
select {
case <-ctx.Done():
@@ -148,7 +152,7 @@ func sink(ctx context.Context, in <-chan result) ([]*metricpb.ResourceMetrics, e
type resourceBatch struct {
Resource *resourcepb.Resource
// Group by instrumentation library name and then the MetricDescriptor.
InstrumentationLibraryBatches map[string]map[string]*metricpb.Metric
InstrumentationLibraryBatches map[instrumentation.Library]map[string]*metricpb.Metric
}
// group by unique Resource string.
@@ -164,15 +168,15 @@ func sink(ctx context.Context, in <-chan result) ([]*metricpb.ResourceMetrics, e
if !ok {
rb = resourceBatch{
Resource: Resource(res.Resource),
InstrumentationLibraryBatches: make(map[string]map[string]*metricpb.Metric),
InstrumentationLibraryBatches: make(map[instrumentation.Library]map[string]*metricpb.Metric),
}
grouped[rID] = rb
}
mb, ok := rb.InstrumentationLibraryBatches[res.Library]
mb, ok := rb.InstrumentationLibraryBatches[res.InstrumentationLibrary]
if !ok {
mb = make(map[string]*metricpb.Metric)
rb.InstrumentationLibraryBatches[res.Library] = mb
rb.InstrumentationLibraryBatches[res.InstrumentationLibrary] = mb
}
mID := res.Metric.GetMetricDescriptor().String()
@@ -202,12 +206,15 @@ func sink(ctx context.Context, in <-chan result) ([]*metricpb.ResourceMetrics, e
var rms []*metricpb.ResourceMetrics
for _, rb := range grouped {
rm := &metricpb.ResourceMetrics{Resource: rb.Resource}
for ilName, mb := range rb.InstrumentationLibraryBatches {
for il, mb := range rb.InstrumentationLibraryBatches {
ilm := &metricpb.InstrumentationLibraryMetrics{
Metrics: make([]*metricpb.Metric, 0, len(mb)),
}
if ilName != "" {
ilm.InstrumentationLibrary = &commonpb.InstrumentationLibrary{Name: ilName}
if il != (instrumentation.Library{}) {
ilm.InstrumentationLibrary = &commonpb.InstrumentationLibrary{
Name: il.Name,
Version: il.Version,
}
}
for _, m := range mb {
ilm.Metrics = append(ilm.Metrics, m)

View File

@@ -79,7 +79,7 @@ type record struct {
mKind metric.Kind
nKind metric.NumberKind
resource *resource.Resource
opts []metric.Option
opts []metric.InstrumentOption
labels []kv.KeyValue
}
@@ -489,6 +489,17 @@ func TestResourceMetricGroupingExport(t *testing.T) {
}
func TestResourceInstLibMetricGroupingExport(t *testing.T) {
countingLib1 := []metric.InstrumentOption{
metric.WithInstrumentationName("counting-lib"),
metric.WithInstrumentationVersion("v1"),
}
countingLib2 := []metric.InstrumentOption{
metric.WithInstrumentationName("counting-lib"),
metric.WithInstrumentationVersion("v2"),
}
summingLib := []metric.InstrumentOption{
metric.WithInstrumentationName("summing-lib"),
}
runMetricExportTests(
t,
[]record{
@@ -497,9 +508,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
metric.CounterKind,
metric.Int64NumberKind,
testInstA,
[]metric.Option{
metric.WithLibraryName("couting-lib"),
},
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
},
{
@@ -507,9 +516,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
metric.CounterKind,
metric.Int64NumberKind,
testInstA,
[]metric.Option{
metric.WithLibraryName("couting-lib"),
},
countingLib2,
append(baseKeyValues, cpuKey.Int(1)),
},
{
@@ -517,9 +524,15 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
metric.CounterKind,
metric.Int64NumberKind,
testInstA,
[]metric.Option{
metric.WithLibraryName("couting-lib"),
},
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
},
{
"int64-count",
metric.CounterKind,
metric.Int64NumberKind,
testInstA,
countingLib1,
append(baseKeyValues, cpuKey.Int(2)),
},
{
@@ -527,9 +540,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
metric.CounterKind,
metric.Int64NumberKind,
testInstA,
[]metric.Option{
metric.WithLibraryName("summing-lib"),
},
summingLib,
append(baseKeyValues, cpuKey.Int(1)),
},
{
@@ -537,9 +548,7 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
metric.CounterKind,
metric.Int64NumberKind,
testInstB,
[]metric.Option{
metric.WithLibraryName("couting-lib"),
},
countingLib1,
append(baseKeyValues, cpuKey.Int(1)),
},
},
@@ -549,7 +558,8 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
InstrumentationLibraryMetrics: []*metricpb.InstrumentationLibraryMetrics{
{
InstrumentationLibrary: &commonpb.InstrumentationLibrary{
Name: "couting-lib",
Name: "counting-lib",
Version: "v1",
},
Metrics: []*metricpb.Metric{
{
@@ -573,6 +583,22 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
},
},
},
{
InstrumentationLibrary: &commonpb.InstrumentationLibrary{
Name: "counting-lib",
Version: "v2",
},
Metrics: []*metricpb.Metric{
{
MetricDescriptor: cpu1MD,
Int64DataPoints: []*metricpb.Int64DataPoint{
{
Value: 11,
},
},
},
},
},
{
InstrumentationLibrary: &commonpb.InstrumentationLibrary{
Name: "summing-lib",
@@ -595,7 +621,8 @@ func TestResourceInstLibMetricGroupingExport(t *testing.T) {
InstrumentationLibraryMetrics: []*metricpb.InstrumentationLibraryMetrics{
{
InstrumentationLibrary: &commonpb.InstrumentationLibrary{
Name: "couting-lib",
Name: "counting-lib",
Version: "v1",
},
Metrics: []*metricpb.Metric{
{

View File

@@ -47,7 +47,7 @@ func ExampleNew() {
// {
// "updates": [
// {
// "name": "a.counter{key=value}",
// "name": "a.counter{instrumentation.name=example,key=value}",
// "sum": 100
// }
// ]