diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
index 6b5c0c2..b4f85f4 100644
--- a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
@@ -1,338 +1,32 @@
 // 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.
+// SPDX-License-Identifier: Apache-2.0
 
-// Package baggage provides types and functions to manage W3C Baggage.
-package baggage
+/*
+Package baggage provides base types and functionality to store and retrieve
+baggage in Go context. This package exists because the OpenTracing bridge to
+OpenTelemetry needs to synchronize state whenever baggage for a context is
+modified and that context contains an OpenTracing span. If it were not for
+this need this package would not need to exist and the
+`go.opentelemetry.io/otel/baggage` package would be the singular place where
+W3C baggage is handled.
+*/
+package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 
-import (
-	"context"
+// List is the collection of baggage members. The W3C allows for duplicates,
+// but OpenTelemetry does not, therefore, this is represented as a map.
+type List map[string]Item
 
-	"go.opentelemetry.io/otel/label"
-)
-
-type rawMap map[label.Key]label.Value
-type keySet map[label.Key]struct{}
-
-// Map is an immutable storage for correlations.
-type Map struct {
-	m rawMap
+// Item is the value and metadata properties part of a list-member.
+type Item struct {
+	Value      string
+	Properties []Property
 }
 
-// MapUpdate contains information about correlation changes to be
-// made.
-type MapUpdate struct {
-	// DropSingleK contains a single key to be dropped from
-	// correlations. Use this to avoid an overhead of a slice
-	// allocation if there is only one key to drop.
-	DropSingleK label.Key
-	// DropMultiK contains all the keys to be dropped from
-	// correlations.
-	DropMultiK []label.Key
+// Property is a metadata entry for a list-member.
+type Property struct {
+	Key, Value string
 
-	// SingleKV contains a single key-value pair to be added to
-	// correlations. Use this to avoid an overhead of a slice
-	// allocation if there is only one key-value pair to add.
-	SingleKV label.KeyValue
-	// MultiKV contains all the key-value pairs to be added to
-	// correlations.
-	MultiKV []label.KeyValue
-}
-
-func newMap(raw rawMap) Map {
-	return Map{
-		m: raw,
-	}
-}
-
-// NewEmptyMap creates an empty correlations map.
-func NewEmptyMap() Map {
-	return newMap(nil)
-}
-
-// NewMap creates a map with the contents of the update applied. In
-// this function, having an update with DropSingleK or DropMultiK
-// makes no sense - those fields are effectively ignored.
-func NewMap(update MapUpdate) Map {
-	return NewEmptyMap().Apply(update)
-}
-
-// Apply creates a copy of the map with the contents of the update
-// applied. Apply will first drop the keys from DropSingleK and
-// DropMultiK, then add key-value pairs from SingleKV and MultiKV.
-func (m Map) Apply(update MapUpdate) Map {
-	delSet, addSet := getModificationSets(update)
-	mapSize := getNewMapSize(m.m, delSet, addSet)
-
-	r := make(rawMap, mapSize)
-	for k, v := range m.m {
-		// do not copy items we want to drop
-		if _, ok := delSet[k]; ok {
-			continue
-		}
-		// do not copy items we would overwrite
-		if _, ok := addSet[k]; ok {
-			continue
-		}
-		r[k] = v
-	}
-	if update.SingleKV.Key.Defined() {
-		r[update.SingleKV.Key] = update.SingleKV.Value
-	}
-	for _, kv := range update.MultiKV {
-		r[kv.Key] = kv.Value
-	}
-	if len(r) == 0 {
-		r = nil
-	}
-	return newMap(r)
-}
-
-func getModificationSets(update MapUpdate) (delSet, addSet keySet) {
-	deletionsCount := len(update.DropMultiK)
-	if update.DropSingleK.Defined() {
-		deletionsCount++
-	}
-	if deletionsCount > 0 {
-		delSet = make(map[label.Key]struct{}, deletionsCount)
-		for _, k := range update.DropMultiK {
-			delSet[k] = struct{}{}
-		}
-		if update.DropSingleK.Defined() {
-			delSet[update.DropSingleK] = struct{}{}
-		}
-	}
-
-	additionsCount := len(update.MultiKV)
-	if update.SingleKV.Key.Defined() {
-		additionsCount++
-	}
-	if additionsCount > 0 {
-		addSet = make(map[label.Key]struct{}, additionsCount)
-		for _, k := range update.MultiKV {
-			addSet[k.Key] = struct{}{}
-		}
-		if update.SingleKV.Key.Defined() {
-			addSet[update.SingleKV.Key] = struct{}{}
-		}
-	}
-
-	return
-}
-
-func getNewMapSize(m rawMap, delSet, addSet keySet) int {
-	mapSizeDiff := 0
-	for k := range addSet {
-		if _, ok := m[k]; !ok {
-			mapSizeDiff++
-		}
-	}
-	for k := range delSet {
-		if _, ok := m[k]; ok {
-			if _, inAddSet := addSet[k]; !inAddSet {
-				mapSizeDiff--
-			}
-		}
-	}
-	return len(m) + mapSizeDiff
-}
-
-// Value gets a value from correlations map and returns a boolean
-// value indicating whether the key exist in the map.
-func (m Map) Value(k label.Key) (label.Value, bool) {
-	value, ok := m.m[k]
-	return value, ok
-}
-
-// HasValue returns a boolean value indicating whether the key exist
-// in the map.
-func (m Map) HasValue(k label.Key) bool {
-	_, has := m.Value(k)
-	return has
-}
-
-// Len returns a length of the map.
-func (m Map) Len() int {
-	return len(m.m)
-}
-
-// Foreach calls a passed callback once on each key-value pair until
-// all the key-value pairs of the map were iterated or the callback
-// returns false, whichever happens first.
-func (m Map) Foreach(f func(label.KeyValue) bool) {
-	for k, v := range m.m {
-		if !f(label.KeyValue{
-			Key:   k,
-			Value: v,
-		}) {
-			return
-		}
-	}
-}
-
-type correlationsType struct{}
-
-// SetHookFunc describes a type of a callback that is called when
-// storing baggage in the context.
-type SetHookFunc func(context.Context) context.Context
-
-// GetHookFunc describes a type of a callback that is called when
-// getting baggage from the context.
-type GetHookFunc func(context.Context, Map) Map
-
-// value under this key is either of type Map or correlationsData
-var correlationsKey = &correlationsType{}
-
-type correlationsData struct {
-	m       Map
-	setHook SetHookFunc
-	getHook GetHookFunc
-}
-
-func (d correlationsData) isHookless() bool {
-	return d.setHook == nil && d.getHook == nil
-}
-
-type hookKind int
-
-const (
-	hookKindSet hookKind = iota
-	hookKindGet
-)
-
-func (d *correlationsData) overrideHook(kind hookKind, setHook SetHookFunc, getHook GetHookFunc) {
-	switch kind {
-	case hookKindSet:
-		d.setHook = setHook
-	case hookKindGet:
-		d.getHook = getHook
-	}
-}
-
-// ContextWithSetHook installs a hook function that will be invoked
-// every time ContextWithMap is called. To avoid unnecessary callback
-// invocations (recursive or not), the callback can temporarily clear
-// the hooks from the context with the ContextWithNoHooks function.
-//
-// Note that NewContext also calls ContextWithMap, so the hook will be
-// invoked.
-//
-// Passing nil SetHookFunc creates a context with no set hook to call.
-//
-// This function should not be used by applications or libraries. It
-// is mostly for interoperation with other observability APIs.
-func ContextWithSetHook(ctx context.Context, hook SetHookFunc) context.Context {
-	return contextWithHook(ctx, hookKindSet, hook, nil)
-}
-
-// ContextWithGetHook installs a hook function that will be invoked
-// every time MapFromContext is called. To avoid unnecessary callback
-// invocations (recursive or not), the callback can temporarily clear
-// the hooks from the context with the ContextWithNoHooks function.
-//
-// Note that NewContext also calls MapFromContext, so the hook will be
-// invoked.
-//
-// Passing nil GetHookFunc creates a context with no get hook to call.
-//
-// This function should not be used by applications or libraries. It
-// is mostly for interoperation with other observability APIs.
-func ContextWithGetHook(ctx context.Context, hook GetHookFunc) context.Context {
-	return contextWithHook(ctx, hookKindGet, nil, hook)
-}
-
-func contextWithHook(ctx context.Context, kind hookKind, setHook SetHookFunc, getHook GetHookFunc) context.Context {
-	switch v := ctx.Value(correlationsKey).(type) {
-	case correlationsData:
-		v.overrideHook(kind, setHook, getHook)
-		if v.isHookless() {
-			return context.WithValue(ctx, correlationsKey, v.m)
-		}
-		return context.WithValue(ctx, correlationsKey, v)
-	case Map:
-		return contextWithOneHookAndMap(ctx, kind, setHook, getHook, v)
-	default:
-		m := NewEmptyMap()
-		return contextWithOneHookAndMap(ctx, kind, setHook, getHook, m)
-	}
-}
-
-func contextWithOneHookAndMap(ctx context.Context, kind hookKind, setHook SetHookFunc, getHook GetHookFunc, m Map) context.Context {
-	d := correlationsData{m: m}
-	d.overrideHook(kind, setHook, getHook)
-	if d.isHookless() {
-		return ctx
-	}
-	return context.WithValue(ctx, correlationsKey, d)
-}
-
-// ContextWithNoHooks creates a context with all the hooks
-// disabled. Also returns old set and get hooks. This function can be
-// used to temporarily clear the context from hooks and then reinstate
-// them by calling ContextWithSetHook and ContextWithGetHook functions
-// passing the hooks returned by this function.
-//
-// This function should not be used by applications or libraries. It
-// is mostly for interoperation with other observability APIs.
-func ContextWithNoHooks(ctx context.Context) (context.Context, SetHookFunc, GetHookFunc) {
-	switch v := ctx.Value(correlationsKey).(type) {
-	case correlationsData:
-		return context.WithValue(ctx, correlationsKey, v.m), v.setHook, v.getHook
-	default:
-		return ctx, nil, nil
-	}
-}
-
-// ContextWithMap returns a context with the Map entered into it.
-func ContextWithMap(ctx context.Context, m Map) context.Context {
-	switch v := ctx.Value(correlationsKey).(type) {
-	case correlationsData:
-		v.m = m
-		ctx = context.WithValue(ctx, correlationsKey, v)
-		if v.setHook != nil {
-			ctx = v.setHook(ctx)
-		}
-		return ctx
-	default:
-		return context.WithValue(ctx, correlationsKey, m)
-	}
-}
-
-// ContextWithNoCorrelationData returns a context stripped of correlation
-// data.
-func ContextWithNoCorrelationData(ctx context.Context) context.Context {
-	return context.WithValue(ctx, correlationsKey, nil)
-}
-
-// NewContext returns a context with the map from passed context
-// updated with the passed key-value pairs.
-func NewContext(ctx context.Context, keyvalues ...label.KeyValue) context.Context {
-	return ContextWithMap(ctx, MapFromContext(ctx).Apply(MapUpdate{
-		MultiKV: keyvalues,
-	}))
-}
-
-// MapFromContext gets the current Map from a Context.
-func MapFromContext(ctx context.Context) Map {
-	switch v := ctx.Value(correlationsKey).(type) {
-	case correlationsData:
-		if v.getHook != nil {
-			return v.getHook(ctx, v.m)
-		}
-		return v.m
-	case Map:
-		return v
-	default:
-		return NewEmptyMap()
-	}
+	// HasValue indicates if a zero-value value means the property does not
+	// have a value or if it was the zero-value.
+	HasValue bool
 }
diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go
new file mode 100644
index 0000000..3aea9c4
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go
@@ -0,0 +1,81 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package baggage // import "go.opentelemetry.io/otel/internal/baggage"
+
+import "context"
+
+type baggageContextKeyType int
+
+const baggageKey baggageContextKeyType = iota
+
+// SetHookFunc is a callback called when storing baggage in the context.
+type SetHookFunc func(context.Context, List) context.Context
+
+// GetHookFunc is a callback called when getting baggage from the context.
+type GetHookFunc func(context.Context, List) List
+
+type baggageState struct {
+	list List
+
+	setHook SetHookFunc
+	getHook GetHookFunc
+}
+
+// ContextWithSetHook returns a copy of parent with hook configured to be
+// invoked every time ContextWithBaggage is called.
+//
+// Passing nil SetHookFunc creates a context with no set hook to call.
+func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {
+	var s baggageState
+	if v, ok := parent.Value(baggageKey).(baggageState); ok {
+		s = v
+	}
+
+	s.setHook = hook
+	return context.WithValue(parent, baggageKey, s)
+}
+
+// ContextWithGetHook returns a copy of parent with hook configured to be
+// invoked every time FromContext is called.
+//
+// Passing nil GetHookFunc creates a context with no get hook to call.
+func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {
+	var s baggageState
+	if v, ok := parent.Value(baggageKey).(baggageState); ok {
+		s = v
+	}
+
+	s.getHook = hook
+	return context.WithValue(parent, baggageKey, s)
+}
+
+// ContextWithList returns a copy of parent with baggage. Passing nil list
+// returns a context without any baggage.
+func ContextWithList(parent context.Context, list List) context.Context {
+	var s baggageState
+	if v, ok := parent.Value(baggageKey).(baggageState); ok {
+		s = v
+	}
+
+	s.list = list
+	ctx := context.WithValue(parent, baggageKey, s)
+	if s.setHook != nil {
+		ctx = s.setHook(ctx, list)
+	}
+
+	return ctx
+}
+
+// ListFromContext returns the baggage contained in ctx.
+func ListFromContext(ctx context.Context) List {
+	switch v := ctx.Value(baggageKey).(type) {
+	case baggageState:
+		if v.getHook != nil {
+			return v.getHook(ctx, v.list)
+		}
+		return v.list
+	default:
+		return nil
+	}
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go
new file mode 100644
index 0000000..2e47b29
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go
@@ -0,0 +1,37 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package global provides the OpenTelemetry global API.
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"log"
+	"sync/atomic"
+)
+
+// ErrorHandler handles irremediable events.
+type ErrorHandler interface {
+	// Handle handles any error deemed irremediable by an OpenTelemetry
+	// component.
+	Handle(error)
+}
+
+type ErrDelegator struct {
+	delegate atomic.Pointer[ErrorHandler]
+}
+
+// Compile-time check that delegator implements ErrorHandler.
+var _ ErrorHandler = (*ErrDelegator)(nil)
+
+func (d *ErrDelegator) Handle(err error) {
+	if eh := d.delegate.Load(); eh != nil {
+		(*eh).Handle(err)
+		return
+	}
+	log.Print(err)
+}
+
+// setDelegate sets the ErrorHandler delegate.
+func (d *ErrDelegator) setDelegate(eh ErrorHandler) {
+	d.delegate.Store(&eh)
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go
new file mode 100644
index 0000000..ae92a42
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go
@@ -0,0 +1,412 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"context"
+	"sync/atomic"
+
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// unwrapper unwraps to return the underlying instrument implementation.
+type unwrapper interface {
+	unwrap() metric.Observable
+}
+
+type afCounter struct {
+	embedded.Float64ObservableCounter
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableCounterOption
+
+	delegate atomic.Value // metric.Float64ObservableCounter
+}
+
+var (
+	_ unwrapper                       = (*afCounter)(nil)
+	_ metric.Float64ObservableCounter = (*afCounter)(nil)
+)
+
+func (i *afCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afCounter) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableCounter)
+	}
+	return nil
+}
+
+type afUpDownCounter struct {
+	embedded.Float64ObservableUpDownCounter
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableUpDownCounterOption
+
+	delegate atomic.Value // metric.Float64ObservableUpDownCounter
+}
+
+var (
+	_ unwrapper                             = (*afUpDownCounter)(nil)
+	_ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)
+)
+
+func (i *afUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afUpDownCounter) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableUpDownCounter)
+	}
+	return nil
+}
+
+type afGauge struct {
+	embedded.Float64ObservableGauge
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableGaugeOption
+
+	delegate atomic.Value // metric.Float64ObservableGauge
+}
+
+var (
+	_ unwrapper                     = (*afGauge)(nil)
+	_ metric.Float64ObservableGauge = (*afGauge)(nil)
+)
+
+func (i *afGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableGauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afGauge) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableGauge)
+	}
+	return nil
+}
+
+type aiCounter struct {
+	embedded.Int64ObservableCounter
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableCounterOption
+
+	delegate atomic.Value // metric.Int64ObservableCounter
+}
+
+var (
+	_ unwrapper                     = (*aiCounter)(nil)
+	_ metric.Int64ObservableCounter = (*aiCounter)(nil)
+)
+
+func (i *aiCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiCounter) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableCounter)
+	}
+	return nil
+}
+
+type aiUpDownCounter struct {
+	embedded.Int64ObservableUpDownCounter
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableUpDownCounterOption
+
+	delegate atomic.Value // metric.Int64ObservableUpDownCounter
+}
+
+var (
+	_ unwrapper                           = (*aiUpDownCounter)(nil)
+	_ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)
+)
+
+func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiUpDownCounter) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableUpDownCounter)
+	}
+	return nil
+}
+
+type aiGauge struct {
+	embedded.Int64ObservableGauge
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableGaugeOption
+
+	delegate atomic.Value // metric.Int64ObservableGauge
+}
+
+var (
+	_ unwrapper                   = (*aiGauge)(nil)
+	_ metric.Int64ObservableGauge = (*aiGauge)(nil)
+)
+
+func (i *aiGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableGauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiGauge) unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableGauge)
+	}
+	return nil
+}
+
+// Sync Instruments.
+type sfCounter struct {
+	embedded.Float64Counter
+
+	name string
+	opts []metric.Float64CounterOption
+
+	delegate atomic.Value // metric.Float64Counter
+}
+
+var _ metric.Float64Counter = (*sfCounter)(nil)
+
+func (i *sfCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Counter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Counter).Add(ctx, incr, opts...)
+	}
+}
+
+type sfUpDownCounter struct {
+	embedded.Float64UpDownCounter
+
+	name string
+	opts []metric.Float64UpDownCounterOption
+
+	delegate atomic.Value // metric.Float64UpDownCounter
+}
+
+var _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil)
+
+func (i *sfUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64UpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64UpDownCounter).Add(ctx, incr, opts...)
+	}
+}
+
+type sfHistogram struct {
+	embedded.Float64Histogram
+
+	name string
+	opts []metric.Float64HistogramOption
+
+	delegate atomic.Value // metric.Float64Histogram
+}
+
+var _ metric.Float64Histogram = (*sfHistogram)(nil)
+
+func (i *sfHistogram) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Histogram(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfHistogram) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Histogram).Record(ctx, x, opts...)
+	}
+}
+
+type sfGauge struct {
+	embedded.Float64Gauge
+
+	name string
+	opts []metric.Float64GaugeOption
+
+	delegate atomic.Value // metric.Float64Gauge
+}
+
+var _ metric.Float64Gauge = (*sfGauge)(nil)
+
+func (i *sfGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Gauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfGauge) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Gauge).Record(ctx, x, opts...)
+	}
+}
+
+type siCounter struct {
+	embedded.Int64Counter
+
+	name string
+	opts []metric.Int64CounterOption
+
+	delegate atomic.Value // metric.Int64Counter
+}
+
+var _ metric.Int64Counter = (*siCounter)(nil)
+
+func (i *siCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Counter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Counter).Add(ctx, x, opts...)
+	}
+}
+
+type siUpDownCounter struct {
+	embedded.Int64UpDownCounter
+
+	name string
+	opts []metric.Int64UpDownCounterOption
+
+	delegate atomic.Value // metric.Int64UpDownCounter
+}
+
+var _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil)
+
+func (i *siUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64UpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siUpDownCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64UpDownCounter).Add(ctx, x, opts...)
+	}
+}
+
+type siHistogram struct {
+	embedded.Int64Histogram
+
+	name string
+	opts []metric.Int64HistogramOption
+
+	delegate atomic.Value // metric.Int64Histogram
+}
+
+var _ metric.Int64Histogram = (*siHistogram)(nil)
+
+func (i *siHistogram) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Histogram(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siHistogram) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Histogram).Record(ctx, x, opts...)
+	}
+}
+
+type siGauge struct {
+	embedded.Int64Gauge
+
+	name string
+	opts []metric.Int64GaugeOption
+
+	delegate atomic.Value // metric.Int64Gauge
+}
+
+var _ metric.Int64Gauge = (*siGauge)(nil)
+
+func (i *siGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Gauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siGauge) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Gauge).Record(ctx, x, opts...)
+	}
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
new file mode 100644
index 0000000..adbca7d
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"log"
+	"os"
+	"sync/atomic"
+
+	"github.com/go-logr/logr"
+	"github.com/go-logr/stdr"
+)
+
+// globalLogger holds a reference to the [logr.Logger] used within
+// go.opentelemetry.io/otel.
+//
+// The default logger uses stdr which is backed by the standard `log.Logger`
+// interface. This logger will only show messages at the Error Level.
+var globalLogger = func() *atomic.Pointer[logr.Logger] {
+	l := stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))
+
+	p := new(atomic.Pointer[logr.Logger])
+	p.Store(&l)
+	return p
+}()
+
+// SetLogger sets the global Logger to l.
+//
+// To see Warn messages use a logger with `l.V(1).Enabled() == true`
+// To see Info messages use a logger with `l.V(4).Enabled() == true`
+// To see Debug messages use a logger with `l.V(8).Enabled() == true`.
+func SetLogger(l logr.Logger) {
+	globalLogger.Store(&l)
+}
+
+// GetLogger returns the global logger.
+func GetLogger() logr.Logger {
+	return *globalLogger.Load()
+}
+
+// Info prints messages about the general state of the API or SDK.
+// This should usually be less than 5 messages a minute.
+func Info(msg string, keysAndValues ...interface{}) {
+	GetLogger().V(4).Info(msg, keysAndValues...)
+}
+
+// Error prints messages about exceptional states of the API or SDK.
+func Error(err error, msg string, keysAndValues ...interface{}) {
+	GetLogger().Error(err, msg, keysAndValues...)
+}
+
+// Debug prints messages about all internal changes in the API or SDK.
+func Debug(msg string, keysAndValues ...interface{}) {
+	GetLogger().V(8).Info(msg, keysAndValues...)
+}
+
+// Warn prints messages about warnings in the API or SDK.
+// Not an error but is likely more important than an informational event.
+func Warn(msg string, keysAndValues ...interface{}) {
+	GetLogger().V(1).Info(msg, keysAndValues...)
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/meter.go b/vendor/go.opentelemetry.io/otel/internal/global/meter.go
new file mode 100644
index 0000000..adb37b5
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/meter.go
@@ -0,0 +1,625 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"container/list"
+	"context"
+	"reflect"
+	"sync"
+
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// meterProvider is a placeholder for a configured SDK MeterProvider.
+//
+// All MeterProvider functionality is forwarded to a delegate once
+// configured.
+type meterProvider struct {
+	embedded.MeterProvider
+
+	mtx    sync.Mutex
+	meters map[il]*meter
+
+	delegate metric.MeterProvider
+}
+
+// setDelegate configures p to delegate all MeterProvider functionality to
+// provider.
+//
+// All Meters provided prior to this function call are switched out to be
+// Meters provided by provider. All instruments and callbacks are recreated and
+// delegated.
+//
+// It is guaranteed by the caller that this happens only once.
+func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	p.delegate = provider
+
+	if len(p.meters) == 0 {
+		return
+	}
+
+	for _, meter := range p.meters {
+		meter.setDelegate(provider)
+	}
+
+	p.meters = nil
+}
+
+// Meter implements MeterProvider.
+func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	if p.delegate != nil {
+		return p.delegate.Meter(name, opts...)
+	}
+
+	// At this moment it is guaranteed that no sdk is installed, save the meter in the meters map.
+
+	c := metric.NewMeterConfig(opts...)
+	key := il{
+		name:    name,
+		version: c.InstrumentationVersion(),
+		schema:  c.SchemaURL(),
+		attrs:   c.InstrumentationAttributes(),
+	}
+
+	if p.meters == nil {
+		p.meters = make(map[il]*meter)
+	}
+
+	if val, ok := p.meters[key]; ok {
+		return val
+	}
+
+	t := &meter{name: name, opts: opts, instruments: make(map[instID]delegatedInstrument)}
+	p.meters[key] = t
+	return t
+}
+
+// meter is a placeholder for a metric.Meter.
+//
+// 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
+
+	mtx         sync.Mutex
+	instruments map[instID]delegatedInstrument
+
+	registry list.List
+
+	delegate metric.Meter
+}
+
+type delegatedInstrument interface {
+	setDelegate(metric.Meter)
+}
+
+// instID are the identifying properties of a instrument.
+type instID struct {
+	// name is the name of the stream.
+	name string
+	// description is the description of the stream.
+	description string
+	// kind defines the functional group of the instrument.
+	kind reflect.Type
+	// unit is the unit of the stream.
+	unit string
+}
+
+// setDelegate configures m to delegate all Meter functionality to Meters
+// created by provider.
+//
+// All subsequent calls to the Meter methods will be passed to the delegate.
+//
+// It is guaranteed by the caller that this happens only once.
+func (m *meter) setDelegate(provider metric.MeterProvider) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	meter := provider.Meter(m.name, m.opts...)
+	m.delegate = meter
+
+	for _, inst := range m.instruments {
+		inst.setDelegate(meter)
+	}
+
+	var n *list.Element
+	for e := m.registry.Front(); e != nil; e = n {
+		r := e.Value.(*registration)
+		r.setDelegate(meter)
+		n = e.Next()
+		m.registry.Remove(e)
+	}
+
+	m.instruments = nil
+	m.registry.Init()
+}
+
+func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64Counter(name, options...)
+	}
+
+	cfg := metric.NewInt64CounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*siCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64Counter), nil
+	}
+	i := &siCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64UpDownCounter(
+	name string,
+	options ...metric.Int64UpDownCounterOption,
+) (metric.Int64UpDownCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64UpDownCounter(name, options...)
+	}
+
+	cfg := metric.NewInt64UpDownCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*siUpDownCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64UpDownCounter), nil
+	}
+	i := &siUpDownCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64Histogram(name, options...)
+	}
+
+	cfg := metric.NewInt64HistogramConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*siHistogram)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64Histogram), nil
+	}
+	i := &siHistogram{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (metric.Int64Gauge, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64Gauge(name, options...)
+	}
+
+	cfg := metric.NewInt64GaugeConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*siGauge)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64Gauge), nil
+	}
+	i := &siGauge{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64ObservableCounter(
+	name string,
+	options ...metric.Int64ObservableCounterOption,
+) (metric.Int64ObservableCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64ObservableCounter(name, options...)
+	}
+
+	cfg := metric.NewInt64ObservableCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*aiCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64ObservableCounter), nil
+	}
+	i := &aiCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64ObservableUpDownCounter(
+	name string,
+	options ...metric.Int64ObservableUpDownCounterOption,
+) (metric.Int64ObservableUpDownCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64ObservableUpDownCounter(name, options...)
+	}
+
+	cfg := metric.NewInt64ObservableUpDownCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*aiUpDownCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64ObservableUpDownCounter), nil
+	}
+	i := &aiUpDownCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Int64ObservableGauge(
+	name string,
+	options ...metric.Int64ObservableGaugeOption,
+) (metric.Int64ObservableGauge, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Int64ObservableGauge(name, options...)
+	}
+
+	cfg := metric.NewInt64ObservableGaugeConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*aiGauge)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Int64ObservableGauge), nil
+	}
+	i := &aiGauge{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64Counter(name, options...)
+	}
+
+	cfg := metric.NewFloat64CounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*sfCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64Counter), nil
+	}
+	i := &sfCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64UpDownCounter(
+	name string,
+	options ...metric.Float64UpDownCounterOption,
+) (metric.Float64UpDownCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64UpDownCounter(name, options...)
+	}
+
+	cfg := metric.NewFloat64UpDownCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*sfUpDownCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64UpDownCounter), nil
+	}
+	i := &sfUpDownCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64Histogram(
+	name string,
+	options ...metric.Float64HistogramOption,
+) (metric.Float64Histogram, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64Histogram(name, options...)
+	}
+
+	cfg := metric.NewFloat64HistogramConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*sfHistogram)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64Histogram), nil
+	}
+	i := &sfHistogram{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption) (metric.Float64Gauge, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64Gauge(name, options...)
+	}
+
+	cfg := metric.NewFloat64GaugeConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*sfGauge)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64Gauge), nil
+	}
+	i := &sfGauge{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64ObservableCounter(
+	name string,
+	options ...metric.Float64ObservableCounterOption,
+) (metric.Float64ObservableCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64ObservableCounter(name, options...)
+	}
+
+	cfg := metric.NewFloat64ObservableCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*afCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64ObservableCounter), nil
+	}
+	i := &afCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64ObservableUpDownCounter(
+	name string,
+	options ...metric.Float64ObservableUpDownCounterOption,
+) (metric.Float64ObservableUpDownCounter, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64ObservableUpDownCounter(name, options...)
+	}
+
+	cfg := metric.NewFloat64ObservableUpDownCounterConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*afUpDownCounter)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64ObservableUpDownCounter), nil
+	}
+	i := &afUpDownCounter{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+func (m *meter) Float64ObservableGauge(
+	name string,
+	options ...metric.Float64ObservableGaugeOption,
+) (metric.Float64ObservableGauge, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.Float64ObservableGauge(name, options...)
+	}
+
+	cfg := metric.NewFloat64ObservableGaugeConfig(options...)
+	id := instID{
+		name:        name,
+		kind:        reflect.TypeOf((*afGauge)(nil)),
+		description: cfg.Description(),
+		unit:        cfg.Unit(),
+	}
+	if f, ok := m.instruments[id]; ok {
+		return f.(metric.Float64ObservableGauge), nil
+	}
+	i := &afGauge{name: name, opts: options}
+	m.instruments[id] = i
+	return i, nil
+}
+
+// RegisterCallback captures the function that will be called during Collect.
+func (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	if m.delegate != nil {
+		return m.delegate.RegisterCallback(unwrapCallback(f), unwrapInstruments(insts)...)
+	}
+
+	reg := &registration{instruments: insts, function: f}
+	e := m.registry.PushBack(reg)
+	reg.unreg = func() error {
+		m.mtx.Lock()
+		_ = m.registry.Remove(e)
+		m.mtx.Unlock()
+		return nil
+	}
+	return reg, nil
+}
+
+func unwrapInstruments(instruments []metric.Observable) []metric.Observable {
+	out := make([]metric.Observable, 0, len(instruments))
+
+	for _, inst := range instruments {
+		if in, ok := inst.(unwrapper); ok {
+			out = append(out, in.unwrap())
+		} else {
+			out = append(out, inst)
+		}
+	}
+
+	return out
+}
+
+type registration struct {
+	embedded.Registration
+
+	instruments []metric.Observable
+	function    metric.Callback
+
+	unreg   func() error
+	unregMu sync.Mutex
+}
+
+type unwrapObs struct {
+	embedded.Observer
+	obs metric.Observer
+}
+
+// unwrapFloat64Observable returns an expected metric.Float64Observable after
+// unwrapping the global object.
+func unwrapFloat64Observable(inst metric.Float64Observable) metric.Float64Observable {
+	if unwrapped, ok := inst.(unwrapper); ok {
+		if floatObs, ok := unwrapped.unwrap().(metric.Float64Observable); ok {
+			// Note: if the unwrapped object does not
+			// unwrap as an observable for either of the
+			// predicates here, it means an internal bug in
+			// this package.  We avoid logging an error in
+			// this case, because the SDK has to try its
+			// own type conversion on the object.  The SDK
+			// will see this and be forced to respond with
+			// its own error.
+			//
+			// This code uses a double-nested if statement
+			// to avoid creating a branch that is
+			// impossible to cover.
+			inst = floatObs
+		}
+	}
+	return inst
+}
+
+// unwrapInt64Observable returns an expected metric.Int64Observable after
+// unwrapping the global object.
+func unwrapInt64Observable(inst metric.Int64Observable) metric.Int64Observable {
+	if unwrapped, ok := inst.(unwrapper); ok {
+		if unint, ok := unwrapped.unwrap().(metric.Int64Observable); ok {
+			// See the comment in unwrapFloat64Observable().
+			inst = unint
+		}
+	}
+	return inst
+}
+
+func (uo *unwrapObs) ObserveFloat64(inst metric.Float64Observable, value float64, opts ...metric.ObserveOption) {
+	uo.obs.ObserveFloat64(unwrapFloat64Observable(inst), value, opts...)
+}
+
+func (uo *unwrapObs) ObserveInt64(inst metric.Int64Observable, value int64, opts ...metric.ObserveOption) {
+	uo.obs.ObserveInt64(unwrapInt64Observable(inst), value, opts...)
+}
+
+func unwrapCallback(f metric.Callback) metric.Callback {
+	return func(ctx context.Context, obs metric.Observer) error {
+		return f(ctx, &unwrapObs{obs: obs})
+	}
+}
+
+func (c *registration) setDelegate(m metric.Meter) {
+	c.unregMu.Lock()
+	defer c.unregMu.Unlock()
+
+	if c.unreg == nil {
+		// Unregister already called.
+		return
+	}
+
+	reg, err := m.RegisterCallback(unwrapCallback(c.function), unwrapInstruments(c.instruments)...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+
+	c.unreg = reg.Unregister
+}
+
+func (c *registration) Unregister() error {
+	c.unregMu.Lock()
+	defer c.unregMu.Unlock()
+	if c.unreg == nil {
+		// Unregister already called.
+		return nil
+	}
+
+	var err error
+	err, c.unreg = c.unreg(), nil
+	return err
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go
new file mode 100644
index 0000000..38560ff
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go
@@ -0,0 +1,71 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"context"
+	"sync"
+
+	"go.opentelemetry.io/otel/propagation"
+)
+
+// textMapPropagator is a default TextMapPropagator that delegates calls to a
+// registered delegate if one is set, otherwise it defaults to delegating the
+// calls to a the default no-op propagation.TextMapPropagator.
+type textMapPropagator struct {
+	mtx      sync.Mutex
+	once     sync.Once
+	delegate propagation.TextMapPropagator
+	noop     propagation.TextMapPropagator
+}
+
+// Compile-time guarantee that textMapPropagator implements the
+// propagation.TextMapPropagator interface.
+var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
+
+func newTextMapPropagator() *textMapPropagator {
+	return &textMapPropagator{
+		noop: propagation.NewCompositeTextMapPropagator(),
+	}
+}
+
+// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
+// forwarded to. Delegation can only be performed once, all subsequent calls
+// perform no delegation.
+func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
+	if delegate == nil {
+		return
+	}
+
+	p.mtx.Lock()
+	p.once.Do(func() { p.delegate = delegate })
+	p.mtx.Unlock()
+}
+
+// effectiveDelegate returns the current delegate of p if one is set,
+// otherwise the default noop TextMapPropagator is returned. This method
+// can be called concurrently.
+func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+	if p.delegate != nil {
+		return p.delegate
+	}
+	return p.noop
+}
+
+// Inject set cross-cutting concerns from the Context into the carrier.
+func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
+	p.effectiveDelegate().Inject(ctx, carrier)
+}
+
+// Extract reads cross-cutting concerns from the carrier into a Context.
+func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
+	return p.effectiveDelegate().Extract(ctx, carrier)
+}
+
+// Fields returns the keys whose values are set with Inject.
+func (p *textMapPropagator) Fields() []string {
+	return p.effectiveDelegate().Fields()
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/state.go b/vendor/go.opentelemetry.io/otel/internal/global/state.go
new file mode 100644
index 0000000..204ea14
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/state.go
@@ -0,0 +1,199 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"errors"
+	"sync"
+	"sync/atomic"
+
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/propagation"
+	"go.opentelemetry.io/otel/trace"
+)
+
+type (
+	errorHandlerHolder struct {
+		eh ErrorHandler
+	}
+
+	tracerProviderHolder struct {
+		tp trace.TracerProvider
+	}
+
+	propagatorsHolder struct {
+		tm propagation.TextMapPropagator
+	}
+
+	meterProviderHolder struct {
+		mp metric.MeterProvider
+	}
+)
+
+var (
+	globalErrorHandler  = defaultErrorHandler()
+	globalTracer        = defaultTracerValue()
+	globalPropagators   = defaultPropagatorsValue()
+	globalMeterProvider = defaultMeterProvider()
+
+	delegateErrorHandlerOnce      sync.Once
+	delegateTraceOnce             sync.Once
+	delegateTextMapPropagatorOnce sync.Once
+	delegateMeterOnce             sync.Once
+)
+
+// GetErrorHandler returns the global ErrorHandler instance.
+//
+// The default ErrorHandler instance returned will log all errors to STDERR
+// until an override ErrorHandler is set with SetErrorHandler. All
+// ErrorHandler returned prior to this will automatically forward errors to
+// the set instance instead of logging.
+//
+// Subsequent calls to SetErrorHandler after the first will not forward errors
+// to the new ErrorHandler for prior returned instances.
+func GetErrorHandler() ErrorHandler {
+	return globalErrorHandler.Load().(errorHandlerHolder).eh
+}
+
+// SetErrorHandler sets the global ErrorHandler to h.
+//
+// The first time this is called all ErrorHandler previously returned from
+// GetErrorHandler will send errors to h instead of the default logging
+// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
+// delegate errors to h.
+func SetErrorHandler(h ErrorHandler) {
+	current := GetErrorHandler()
+
+	if _, cOk := current.(*ErrDelegator); cOk {
+		if _, ehOk := h.(*ErrDelegator); ehOk && current == h {
+			// Do not assign to the delegate of the default ErrDelegator to be
+			// itself.
+			Error(
+				errors.New("no ErrorHandler delegate configured"),
+				"ErrorHandler remains its current value.",
+			)
+			return
+		}
+	}
+
+	delegateErrorHandlerOnce.Do(func() {
+		if def, ok := current.(*ErrDelegator); ok {
+			def.setDelegate(h)
+		}
+	})
+	globalErrorHandler.Store(errorHandlerHolder{eh: h})
+}
+
+// TracerProvider is the internal implementation for global.TracerProvider.
+func TracerProvider() trace.TracerProvider {
+	return globalTracer.Load().(tracerProviderHolder).tp
+}
+
+// SetTracerProvider is the internal implementation for global.SetTracerProvider.
+func SetTracerProvider(tp trace.TracerProvider) {
+	current := TracerProvider()
+
+	if _, cOk := current.(*tracerProvider); cOk {
+		if _, tpOk := tp.(*tracerProvider); tpOk && current == tp {
+			// Do not assign the default delegating TracerProvider to delegate
+			// to itself.
+			Error(
+				errors.New("no delegate configured in tracer provider"),
+				"Setting tracer provider to its current value. No delegate will be configured",
+			)
+			return
+		}
+	}
+
+	delegateTraceOnce.Do(func() {
+		if def, ok := current.(*tracerProvider); ok {
+			def.setDelegate(tp)
+		}
+	})
+	globalTracer.Store(tracerProviderHolder{tp: tp})
+}
+
+// TextMapPropagator is the internal implementation for global.TextMapPropagator.
+func TextMapPropagator() propagation.TextMapPropagator {
+	return globalPropagators.Load().(propagatorsHolder).tm
+}
+
+// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
+func SetTextMapPropagator(p propagation.TextMapPropagator) {
+	current := TextMapPropagator()
+
+	if _, cOk := current.(*textMapPropagator); cOk {
+		if _, pOk := p.(*textMapPropagator); pOk && current == p {
+			// Do not assign the default delegating TextMapPropagator to
+			// delegate to itself.
+			Error(
+				errors.New("no delegate configured in text map propagator"),
+				"Setting text map propagator to its current value. No delegate will be configured",
+			)
+			return
+		}
+	}
+
+	// For the textMapPropagator already returned by TextMapPropagator
+	// delegate to p.
+	delegateTextMapPropagatorOnce.Do(func() {
+		if def, ok := current.(*textMapPropagator); ok {
+			def.SetDelegate(p)
+		}
+	})
+	// Return p when subsequent calls to TextMapPropagator are made.
+	globalPropagators.Store(propagatorsHolder{tm: p})
+}
+
+// MeterProvider is the internal implementation for global.MeterProvider.
+func MeterProvider() metric.MeterProvider {
+	return globalMeterProvider.Load().(meterProviderHolder).mp
+}
+
+// SetMeterProvider is the internal implementation for global.SetMeterProvider.
+func SetMeterProvider(mp metric.MeterProvider) {
+	current := MeterProvider()
+	if _, cOk := current.(*meterProvider); cOk {
+		if _, mpOk := mp.(*meterProvider); mpOk && current == mp {
+			// Do not assign the default delegating MeterProvider to delegate
+			// to itself.
+			Error(
+				errors.New("no delegate configured in meter provider"),
+				"Setting meter provider to its current value. No delegate will be configured",
+			)
+			return
+		}
+	}
+
+	delegateMeterOnce.Do(func() {
+		if def, ok := current.(*meterProvider); ok {
+			def.setDelegate(mp)
+		}
+	})
+	globalMeterProvider.Store(meterProviderHolder{mp: mp})
+}
+
+func defaultErrorHandler() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(errorHandlerHolder{eh: &ErrDelegator{}})
+	return v
+}
+
+func defaultTracerValue() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(tracerProviderHolder{tp: &tracerProvider{}})
+	return v
+}
+
+func defaultPropagatorsValue() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(propagatorsHolder{tm: newTextMapPropagator()})
+	return v
+}
+
+func defaultMeterProvider() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(meterProviderHolder{mp: &meterProvider{}})
+	return v
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/trace.go b/vendor/go.opentelemetry.io/otel/internal/global/trace.go
new file mode 100644
index 0000000..49e4ac4
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/trace.go
@@ -0,0 +1,231 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+/*
+This file contains the forwarding implementation of the TracerProvider used as
+the default global instance. Prior to initialization of an SDK, Tracers
+returned by the global TracerProvider will provide no-op functionality. This
+means that all Span created prior to initialization are no-op Spans.
+
+Once an SDK has been initialized, all provided no-op Tracers are swapped for
+Tracers provided by the SDK defined TracerProvider. However, any Span started
+prior to this initialization does not change its behavior. Meaning, the Span
+remains a no-op Span.
+
+The implementation to track and swap Tracers locks all new Tracer creation
+until the swap is complete. This assumes that this operation is not
+performance-critical. If that assumption is incorrect, be sure to configure an
+SDK prior to any Tracer creation.
+*/
+
+import (
+	"context"
+	"sync"
+	"sync/atomic"
+
+	"go.opentelemetry.io/auto/sdk"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/trace"
+	"go.opentelemetry.io/otel/trace/embedded"
+)
+
+// tracerProvider is a placeholder for a configured SDK TracerProvider.
+//
+// All TracerProvider functionality is forwarded to a delegate once
+// configured.
+type tracerProvider struct {
+	embedded.TracerProvider
+
+	mtx      sync.Mutex
+	tracers  map[il]*tracer
+	delegate trace.TracerProvider
+}
+
+// Compile-time guarantee that tracerProvider implements the TracerProvider
+// interface.
+var _ trace.TracerProvider = &tracerProvider{}
+
+// setDelegate configures p to delegate all TracerProvider functionality to
+// provider.
+//
+// All Tracers provided prior to this function call are switched out to be
+// Tracers provided by provider.
+//
+// It is guaranteed by the caller that this happens only once.
+func (p *tracerProvider) setDelegate(provider trace.TracerProvider) {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	p.delegate = provider
+
+	if len(p.tracers) == 0 {
+		return
+	}
+
+	for _, t := range p.tracers {
+		t.setDelegate(provider)
+	}
+
+	p.tracers = nil
+}
+
+// Tracer implements TracerProvider.
+func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	if p.delegate != nil {
+		return p.delegate.Tracer(name, opts...)
+	}
+
+	// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
+
+	c := trace.NewTracerConfig(opts...)
+	key := il{
+		name:    name,
+		version: c.InstrumentationVersion(),
+		schema:  c.SchemaURL(),
+		attrs:   c.InstrumentationAttributes(),
+	}
+
+	if p.tracers == nil {
+		p.tracers = make(map[il]*tracer)
+	}
+
+	if val, ok := p.tracers[key]; ok {
+		return val
+	}
+
+	t := &tracer{name: name, opts: opts, provider: p}
+	p.tracers[key] = t
+	return t
+}
+
+type il struct {
+	name    string
+	version string
+	schema  string
+	attrs   attribute.Set
+}
+
+// tracer is a placeholder for a trace.Tracer.
+//
+// All Tracer functionality is forwarded to a delegate once configured.
+// Otherwise, all functionality is forwarded to a NoopTracer.
+type tracer struct {
+	embedded.Tracer
+
+	name     string
+	opts     []trace.TracerOption
+	provider *tracerProvider
+
+	delegate atomic.Value
+}
+
+// Compile-time guarantee that tracer implements the trace.Tracer interface.
+var _ trace.Tracer = &tracer{}
+
+// setDelegate configures t to delegate all Tracer functionality to Tracers
+// created by provider.
+//
+// All subsequent calls to the Tracer methods will be passed to the delegate.
+//
+// It is guaranteed by the caller that this happens only once.
+func (t *tracer) setDelegate(provider trace.TracerProvider) {
+	t.delegate.Store(provider.Tracer(t.name, t.opts...))
+}
+
+// Start implements trace.Tracer by forwarding the call to t.delegate if
+// set, otherwise it forwards the call to a NoopTracer.
+func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
+	delegate := t.delegate.Load()
+	if delegate != nil {
+		return delegate.(trace.Tracer).Start(ctx, name, opts...)
+	}
+
+	return t.newSpan(ctx, autoInstEnabled, name, opts)
+}
+
+// autoInstEnabled determines if the auto-instrumentation SDK span is returned
+// from the tracer when not backed by a delegate and auto-instrumentation has
+// attached to this process.
+//
+// The auto-instrumentation is expected to overwrite this value to true when it
+// attaches. By default, this will point to false and mean a tracer will return
+// a nonRecordingSpan by default.
+var autoInstEnabled = new(bool)
+
+// newSpan is called by tracer.Start so auto-instrumentation can attach an eBPF
+// uprobe to this code.
+//
+// "noinline" pragma prevents the method from ever being inlined.
+//
+//go:noinline
+func (t *tracer) newSpan(
+	ctx context.Context,
+	autoSpan *bool,
+	name string,
+	opts []trace.SpanStartOption,
+) (context.Context, trace.Span) {
+	// autoInstEnabled is passed to newSpan via the autoSpan parameter. This is
+	// so the auto-instrumentation can define a uprobe for (*t).newSpan and be
+	// provided with the address of the bool autoInstEnabled points to. It
+	// needs to be a parameter so that pointer can be reliably determined, it
+	// should not be read from the global.
+
+	if *autoSpan {
+		tracer := sdk.TracerProvider().Tracer(t.name, t.opts...)
+		return tracer.Start(ctx, name, opts...)
+	}
+
+	s := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}
+	ctx = trace.ContextWithSpan(ctx, s)
+	return ctx, s
+}
+
+// nonRecordingSpan is a minimal implementation of a Span that wraps a
+// SpanContext. It performs no operations other than to return the wrapped
+// SpanContext.
+type nonRecordingSpan struct {
+	embedded.Span
+
+	sc     trace.SpanContext
+	tracer *tracer
+}
+
+var _ trace.Span = nonRecordingSpan{}
+
+// SpanContext returns the wrapped SpanContext.
+func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
+
+// IsRecording always returns false.
+func (nonRecordingSpan) IsRecording() bool { return false }
+
+// SetStatus does nothing.
+func (nonRecordingSpan) SetStatus(codes.Code, string) {}
+
+// SetError does nothing.
+func (nonRecordingSpan) SetError(bool) {}
+
+// SetAttributes does nothing.
+func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
+
+// End does nothing.
+func (nonRecordingSpan) End(...trace.SpanEndOption) {}
+
+// RecordError does nothing.
+func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
+
+// AddEvent does nothing.
+func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
+
+// AddLink does nothing.
+func (nonRecordingSpan) AddLink(trace.Link) {}
+
+// SetName does nothing.
+func (nonRecordingSpan) SetName(string) {}
+
+func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
diff --git a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go b/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
deleted file mode 100644
index dae825e..0000000
--- a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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 internal
-
-import (
-	"math"
-	"unsafe"
-)
-
-func BoolToRaw(b bool) uint64 {
-	if b {
-		return 1
-	}
-	return 0
-}
-
-func RawToBool(r uint64) bool {
-	return r != 0
-}
-
-func Int64ToRaw(i int64) uint64 {
-	return uint64(i)
-}
-
-func RawToInt64(r uint64) int64 {
-	return int64(r)
-}
-
-func Uint64ToRaw(u uint64) uint64 {
-	return u
-}
-
-func RawToUint64(r uint64) uint64 {
-	return r
-}
-
-func Float64ToRaw(f float64) uint64 {
-	return math.Float64bits(f)
-}
-
-func RawToFloat64(r uint64) float64 {
-	return math.Float64frombits(r)
-}
-
-func Int32ToRaw(i int32) uint64 {
-	return uint64(i)
-}
-
-func RawToInt32(r uint64) int32 {
-	return int32(r)
-}
-
-func Uint32ToRaw(u uint32) uint64 {
-	return uint64(u)
-}
-
-func RawToUint32(r uint64) uint32 {
-	return uint32(r)
-}
-
-func Float32ToRaw(f float32) uint64 {
-	return Uint32ToRaw(math.Float32bits(f))
-}
-
-func RawToFloat32(r uint64) float32 {
-	return math.Float32frombits(RawToUint32(r))
-}
-
-func RawPtrToFloat64Ptr(r *uint64) *float64 {
-	return (*float64)(unsafe.Pointer(r))
-}
-
-func RawPtrToInt64Ptr(r *uint64) *int64 {
-	return (*int64)(unsafe.Pointer(r))
-}
-
-func RawPtrToUint64Ptr(r *uint64) *uint64 {
-	return r
-}
diff --git a/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go b/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go
deleted file mode 100644
index c09a737..0000000
--- a/vendor/go.opentelemetry.io/otel/internal/trace/noop/noop.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 noop provides noop tracing implementations for tracer and span.
-package noop
-
-import (
-	"context"
-
-	"go.opentelemetry.io/otel/api/trace"
-)
-
-var (
-	// Tracer is a noop tracer that starts noop spans.
-	Tracer trace.Tracer
-
-	// Span is a noop Span.
-	Span trace.Span
-)
-
-func init() {
-	Tracer = trace.NoopTracerProvider().Tracer("")
-	_, Span = Tracer.Start(context.Background(), "")
-}
