// Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package metric import ( "context" "go.opentelemetry.io/otel/api/kv" ) // The file is organized as follows: // // - Provider interface // - Meter struct // - RecordBatch // - BatchObserver // - Synchronous instrument constructors (2 x int64,float64) // - Asynchronous instrument constructors (1 x int64,float64) // - Batch asynchronous constructors (1 x int64,float64) // - Internals // Provider supports named Meter instances. type Provider interface { // 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` // implementation and the `Meter` library name. // // An uninitialized Meter is a no-op implementation. type Meter struct { impl MeterImpl name, version string } // RecordBatch atomically records a batch of measurements. func (m Meter) RecordBatch(ctx context.Context, ls []kv.KeyValue, ms ...Measurement) { if m.impl == nil { return } m.impl.RecordBatch(ctx, ls, ms...) } // NewBatchObserver creates a new BatchObserver that supports // making batches of observations for multiple instruments. func (m Meter) NewBatchObserver(callback BatchObserverCallback) BatchObserver { return BatchObserver{ meter: m, runner: newBatchAsyncRunner(callback), } } // NewInt64Counter creates a new integer Counter instrument with the // 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 ...InstrumentOption) (Int64Counter, error) { return wrapInt64CounterInstrument( m.newSync(name, CounterKind, Int64NumberKind, options)) } // NewFloat64Counter creates a new floating point Counter with the // 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 ...InstrumentOption) (Float64Counter, error) { return wrapFloat64CounterInstrument( m.newSync(name, CounterKind, Float64NumberKind, options)) } // NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the // 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 ...InstrumentOption) (Int64UpDownCounter, error) { return wrapInt64UpDownCounterInstrument( m.newSync(name, UpDownCounterKind, Int64NumberKind, options)) } // NewFloat64UpDownCounter creates a new floating point UpDownCounter with the // 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 ...InstrumentOption) (Float64UpDownCounter, error) { return wrapFloat64UpDownCounterInstrument( m.newSync(name, UpDownCounterKind, Float64NumberKind, options)) } // NewInt64ValueRecorder creates a new integer ValueRecorder instrument with the // 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 ...InstrumentOption) (Int64ValueRecorder, error) { return wrapInt64ValueRecorderInstrument( m.newSync(name, ValueRecorderKind, Int64NumberKind, opts)) } // NewFloat64ValueRecorder creates a new floating point ValueRecorder with the // 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 ...InstrumentOption) (Float64ValueRecorder, error) { return wrapFloat64ValueRecorderInstrument( m.newSync(name, ValueRecorderKind, Float64NumberKind, opts)) } // NewInt64ValueObserver creates a new integer ValueObserver instrument // 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 ...InstrumentOption) (Int64ValueObserver, error) { if callback == nil { return wrapInt64ValueObserverInstrument(NoopAsync{}, nil) } return wrapInt64ValueObserverInstrument( m.newAsync(name, ValueObserverKind, Int64NumberKind, opts, newInt64AsyncRunner(callback))) } // NewFloat64ValueObserver creates a new floating point ValueObserver 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) NewFloat64ValueObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64ValueObserver, error) { if callback == nil { return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil) } return wrapFloat64ValueObserverInstrument( m.newAsync(name, ValueObserverKind, Float64NumberKind, opts, newFloat64AsyncRunner(callback))) } // NewInt64SumObserver creates a new integer SumObserver instrument // 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 ...InstrumentOption) (Int64SumObserver, error) { if callback == nil { return wrapInt64SumObserverInstrument(NoopAsync{}, nil) } return wrapInt64SumObserverInstrument( m.newAsync(name, SumObserverKind, Int64NumberKind, opts, newInt64AsyncRunner(callback))) } // NewFloat64SumObserver creates a new floating point SumObserver 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) NewFloat64SumObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64SumObserver, error) { if callback == nil { return wrapFloat64SumObserverInstrument(NoopAsync{}, nil) } return wrapFloat64SumObserverInstrument( m.newAsync(name, SumObserverKind, Float64NumberKind, opts, newFloat64AsyncRunner(callback))) } // NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument // 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 ...InstrumentOption) (Int64UpDownSumObserver, error) { if callback == nil { return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil) } return wrapInt64UpDownSumObserverInstrument( m.newAsync(name, UpDownSumObserverKind, Int64NumberKind, opts, newInt64AsyncRunner(callback))) } // NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver 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) NewFloat64UpDownSumObserver(name string, callback Float64ObserverCallback, opts ...InstrumentOption) (Float64UpDownSumObserver, error) { if callback == nil { return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil) } return wrapFloat64UpDownSumObserverInstrument( m.newAsync(name, UpDownSumObserverKind, Float64NumberKind, opts, newFloat64AsyncRunner(callback))) } // NewInt64ValueObserver creates a new integer ValueObserver instrument // 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 ...InstrumentOption) (Int64ValueObserver, error) { if b.runner == nil { return wrapInt64ValueObserverInstrument(NoopAsync{}, nil) } return wrapInt64ValueObserverInstrument( b.meter.newAsync(name, ValueObserverKind, Int64NumberKind, opts, b.runner)) } // NewFloat64ValueObserver creates a new floating point ValueObserver 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) NewFloat64ValueObserver(name string, opts ...InstrumentOption) (Float64ValueObserver, error) { if b.runner == nil { return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil) } return wrapFloat64ValueObserverInstrument( b.meter.newAsync(name, ValueObserverKind, Float64NumberKind, opts, b.runner)) } // NewInt64SumObserver creates a new integer SumObserver instrument // 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 ...InstrumentOption) (Int64SumObserver, error) { if b.runner == nil { return wrapInt64SumObserverInstrument(NoopAsync{}, nil) } return wrapInt64SumObserverInstrument( b.meter.newAsync(name, SumObserverKind, Int64NumberKind, opts, b.runner)) } // NewFloat64SumObserver creates a new floating point SumObserver 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) NewFloat64SumObserver(name string, opts ...InstrumentOption) (Float64SumObserver, error) { if b.runner == nil { return wrapFloat64SumObserverInstrument(NoopAsync{}, nil) } return wrapFloat64SumObserverInstrument( b.meter.newAsync(name, SumObserverKind, Float64NumberKind, opts, b.runner)) } // NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument // 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 ...InstrumentOption) (Int64UpDownSumObserver, error) { if b.runner == nil { return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil) } return wrapInt64UpDownSumObserverInstrument( b.meter.newAsync(name, UpDownSumObserverKind, Int64NumberKind, opts, b.runner)) } // NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver 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) NewFloat64UpDownSumObserver(name string, opts ...InstrumentOption) (Float64UpDownSumObserver, error) { if b.runner == nil { return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil) } return wrapFloat64UpDownSumObserverInstrument( b.meter.newAsync(name, UpDownSumObserverKind, Float64NumberKind, opts, b.runner)) } // MeterImpl returns the underlying MeterImpl of this Meter. func (m Meter) MeterImpl() MeterImpl { return m.impl } // newAsync constructs one new asynchronous instrument. func (m Meter) newAsync( name string, mkind Kind, nkind NumberKind, opts []InstrumentOption, runner AsyncRunner, ) ( AsyncImpl, error, ) { if m.impl == nil { return NoopAsync{}, nil } desc := NewDescriptor(name, mkind, nkind, opts...) desc.config.InstrumentationName = m.name desc.config.InstrumentationVersion = m.version return m.impl.NewAsyncInstrument(desc, runner) } // newSync constructs one new synchronous instrument. func (m Meter) newSync( name string, metricKind Kind, numberKind NumberKind, opts []InstrumentOption, ) ( SyncImpl, error, ) { if m.impl == nil { return NoopSync{}, nil } desc := NewDescriptor(name, metricKind, numberKind, opts...) desc.config.InstrumentationName = m.name desc.config.InstrumentationVersion = m.version return m.impl.NewSyncInstrument(desc) }