diff --git a/vendor/go.opentelemetry.io/otel/api/metric/meter.go b/vendor/go.opentelemetry.io/otel/api/metric/meter.go
new file mode 100644
index 0000000..d174913
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/api/metric/meter.go
@@ -0,0 +1,320 @@
+// 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/label"
+)
+
+// The file is organized as follows:
+//
+//  - MeterProvider 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
+
+// MeterProvider supports named Meter instances.
+type MeterProvider 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 []label.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 BatchObserverFunc) 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 Int64ObserverFunc, 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 Float64ObserverFunc, 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 Int64ObserverFunc, 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 Float64ObserverFunc, 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 Int64ObserverFunc, 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 Float64ObserverFunc, 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)
+}
