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 }
