diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/attr.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/attr.go
new file mode 100644
index 0000000..af6ef17
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/attr.go
@@ -0,0 +1,58 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+// Attr is a key-value pair.
+type Attr struct {
+	Key   string `json:"key,omitempty"`
+	Value Value  `json:"value,omitempty"`
+}
+
+// String returns an Attr for a string value.
+func String(key, value string) Attr {
+	return Attr{key, StringValue(value)}
+}
+
+// Int64 returns an Attr for an int64 value.
+func Int64(key string, value int64) Attr {
+	return Attr{key, Int64Value(value)}
+}
+
+// Int returns an Attr for an int value.
+func Int(key string, value int) Attr {
+	return Int64(key, int64(value))
+}
+
+// Float64 returns an Attr for a float64 value.
+func Float64(key string, value float64) Attr {
+	return Attr{key, Float64Value(value)}
+}
+
+// Bool returns an Attr for a bool value.
+func Bool(key string, value bool) Attr {
+	return Attr{key, BoolValue(value)}
+}
+
+// Bytes returns an Attr for a []byte value.
+// The passed slice must not be changed after it is passed.
+func Bytes(key string, value []byte) Attr {
+	return Attr{key, BytesValue(value)}
+}
+
+// Slice returns an Attr for a []Value value.
+// The passed slice must not be changed after it is passed.
+func Slice(key string, value ...Value) Attr {
+	return Attr{key, SliceValue(value...)}
+}
+
+// Map returns an Attr for a map value.
+// The passed slice must not be changed after it is passed.
+func Map(key string, value ...Attr) Attr {
+	return Attr{key, MapValue(value...)}
+}
+
+// Equal returns if a is equal to b.
+func (a Attr) Equal(b Attr) bool {
+	return a.Key == b.Key && a.Value.Equal(b.Value)
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/doc.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/doc.go
new file mode 100644
index 0000000..949e216
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/doc.go
@@ -0,0 +1,8 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+/*
+Package telemetry provides a lightweight representations of OpenTelemetry
+telemetry that is compatible with the OTLP JSON protobuf encoding.
+*/
+package telemetry
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/id.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/id.go
new file mode 100644
index 0000000..e854d7e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/id.go
@@ -0,0 +1,103 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"encoding/hex"
+	"errors"
+	"fmt"
+)
+
+const (
+	traceIDSize = 16
+	spanIDSize  = 8
+)
+
+// TraceID is a custom data type that is used for all trace IDs.
+type TraceID [traceIDSize]byte
+
+// String returns the hex string representation form of a TraceID.
+func (tid TraceID) String() string {
+	return hex.EncodeToString(tid[:])
+}
+
+// IsEmpty returns false if id contains at least one non-zero byte.
+func (tid TraceID) IsEmpty() bool {
+	return tid == [traceIDSize]byte{}
+}
+
+// MarshalJSON converts the trace ID into a hex string enclosed in quotes.
+func (tid TraceID) MarshalJSON() ([]byte, error) {
+	if tid.IsEmpty() {
+		return []byte(`""`), nil
+	}
+	return marshalJSON(tid[:])
+}
+
+// UnmarshalJSON inflates the trace ID from hex string, possibly enclosed in
+// quotes.
+func (tid *TraceID) UnmarshalJSON(data []byte) error {
+	*tid = [traceIDSize]byte{}
+	return unmarshalJSON(tid[:], data)
+}
+
+// SpanID is a custom data type that is used for all span IDs.
+type SpanID [spanIDSize]byte
+
+// String returns the hex string representation form of a SpanID.
+func (sid SpanID) String() string {
+	return hex.EncodeToString(sid[:])
+}
+
+// IsEmpty returns true if the span ID contains at least one non-zero byte.
+func (sid SpanID) IsEmpty() bool {
+	return sid == [spanIDSize]byte{}
+}
+
+// MarshalJSON converts span ID into a hex string enclosed in quotes.
+func (sid SpanID) MarshalJSON() ([]byte, error) {
+	if sid.IsEmpty() {
+		return []byte(`""`), nil
+	}
+	return marshalJSON(sid[:])
+}
+
+// UnmarshalJSON decodes span ID from hex string, possibly enclosed in quotes.
+func (sid *SpanID) UnmarshalJSON(data []byte) error {
+	*sid = [spanIDSize]byte{}
+	return unmarshalJSON(sid[:], data)
+}
+
+// marshalJSON converts id into a hex string enclosed in quotes.
+func marshalJSON(id []byte) ([]byte, error) {
+	// Plus 2 quote chars at the start and end.
+	hexLen := hex.EncodedLen(len(id)) + 2
+
+	b := make([]byte, hexLen)
+	hex.Encode(b[1:hexLen-1], id)
+	b[0], b[hexLen-1] = '"', '"'
+
+	return b, nil
+}
+
+// unmarshalJSON inflates trace id from hex string, possibly enclosed in quotes.
+func unmarshalJSON(dst []byte, src []byte) error {
+	if l := len(src); l >= 2 && src[0] == '"' && src[l-1] == '"' {
+		src = src[1 : l-1]
+	}
+	nLen := len(src)
+	if nLen == 0 {
+		return nil
+	}
+
+	if len(dst) != hex.DecodedLen(nLen) {
+		return errors.New("invalid length for ID")
+	}
+
+	_, err := hex.Decode(dst, src)
+	if err != nil {
+		return fmt.Errorf("cannot unmarshal ID from string '%s': %w", string(src), err)
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/number.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/number.go
new file mode 100644
index 0000000..29e629d
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/number.go
@@ -0,0 +1,67 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"encoding/json"
+	"strconv"
+)
+
+// protoInt64 represents the protobuf encoding of integers which can be either
+// strings or integers.
+type protoInt64 int64
+
+// Int64 returns the protoInt64 as an int64.
+func (i *protoInt64) Int64() int64 { return int64(*i) }
+
+// UnmarshalJSON decodes both strings and integers.
+func (i *protoInt64) UnmarshalJSON(data []byte) error {
+	if data[0] == '"' {
+		var str string
+		if err := json.Unmarshal(data, &str); err != nil {
+			return err
+		}
+		parsedInt, err := strconv.ParseInt(str, 10, 64)
+		if err != nil {
+			return err
+		}
+		*i = protoInt64(parsedInt)
+	} else {
+		var parsedInt int64
+		if err := json.Unmarshal(data, &parsedInt); err != nil {
+			return err
+		}
+		*i = protoInt64(parsedInt)
+	}
+	return nil
+}
+
+// protoUint64 represents the protobuf encoding of integers which can be either
+// strings or integers.
+type protoUint64 uint64
+
+// Int64 returns the protoUint64 as a uint64.
+func (i *protoUint64) Uint64() uint64 { return uint64(*i) }
+
+// UnmarshalJSON decodes both strings and integers.
+func (i *protoUint64) UnmarshalJSON(data []byte) error {
+	if data[0] == '"' {
+		var str string
+		if err := json.Unmarshal(data, &str); err != nil {
+			return err
+		}
+		parsedUint, err := strconv.ParseUint(str, 10, 64)
+		if err != nil {
+			return err
+		}
+		*i = protoUint64(parsedUint)
+	} else {
+		var parsedUint uint64
+		if err := json.Unmarshal(data, &parsedUint); err != nil {
+			return err
+		}
+		*i = protoUint64(parsedUint)
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/resource.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/resource.go
new file mode 100644
index 0000000..cecad8b
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/resource.go
@@ -0,0 +1,66 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// Resource information.
+type Resource struct {
+	// Attrs are the set of attributes that describe the resource. Attribute
+	// keys MUST be unique (it is not allowed to have more than one attribute
+	// with the same key).
+	Attrs []Attr `json:"attributes,omitempty"`
+	// DroppedAttrs is the number of dropped attributes. If the value
+	// is 0, then no attributes were dropped.
+	DroppedAttrs uint32 `json:"droppedAttributesCount,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.
+func (r *Resource) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid Resource type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid Resource field: %#v", keyIface)
+		}
+
+		switch key {
+		case "attributes":
+			err = decoder.Decode(&r.Attrs)
+		case "droppedAttributesCount", "dropped_attributes_count":
+			err = decoder.Decode(&r.DroppedAttrs)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/scope.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/scope.go
new file mode 100644
index 0000000..b6f2e28
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/scope.go
@@ -0,0 +1,67 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// Scope is the identifying values of the instrumentation scope.
+type Scope struct {
+	Name         string `json:"name,omitempty"`
+	Version      string `json:"version,omitempty"`
+	Attrs        []Attr `json:"attributes,omitempty"`
+	DroppedAttrs uint32 `json:"droppedAttributesCount,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.
+func (s *Scope) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid Scope type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid Scope field: %#v", keyIface)
+		}
+
+		switch key {
+		case "name":
+			err = decoder.Decode(&s.Name)
+		case "version":
+			err = decoder.Decode(&s.Version)
+		case "attributes":
+			err = decoder.Decode(&s.Attrs)
+		case "droppedAttributesCount", "dropped_attributes_count":
+			err = decoder.Decode(&s.DroppedAttrs)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/span.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/span.go
new file mode 100644
index 0000000..a13a6b7
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/span.go
@@ -0,0 +1,456 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"bytes"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"time"
+)
+
+// A Span represents a single operation performed by a single component of the
+// system.
+type Span struct {
+	// A unique identifier for a trace. All spans from the same trace share
+	// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR
+	// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON
+	// is zero-length and thus is also invalid).
+	//
+	// This field is required.
+	TraceID TraceID `json:"traceId,omitempty"`
+	// A unique identifier for a span within a trace, assigned when the span
+	// is created. The ID is an 8-byte array. An ID with all zeroes OR of length
+	// other than 8 bytes is considered invalid (empty string in OTLP/JSON
+	// is zero-length and thus is also invalid).
+	//
+	// This field is required.
+	SpanID SpanID `json:"spanId,omitempty"`
+	// trace_state conveys information about request position in multiple distributed tracing graphs.
+	// It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header
+	// See also https://github.com/w3c/distributed-tracing for more details about this field.
+	TraceState string `json:"traceState,omitempty"`
+	// The `span_id` of this span's parent span. If this is a root span, then this
+	// field must be empty. The ID is an 8-byte array.
+	ParentSpanID SpanID `json:"parentSpanId,omitempty"`
+	// Flags, a bit field.
+	//
+	// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace
+	// Context specification. To read the 8-bit W3C trace flag, use
+	// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.
+	//
+	// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+	//
+	// Bits 8 and 9 represent the 3 states of whether a span's parent
+	// is remote. The states are (unknown, is not remote, is remote).
+	// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.
+	// To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.
+	//
+	// When creating span messages, if the message is logically forwarded from another source
+	// with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD
+	// be copied as-is. If creating from a source that does not have an equivalent flags field
+	// (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST
+	// be set to zero.
+	// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.
+	//
+	// [Optional].
+	Flags uint32 `json:"flags,omitempty"`
+	// A description of the span's operation.
+	//
+	// For example, the name can be a qualified method name or a file name
+	// and a line number where the operation is called. A best practice is to use
+	// the same display name at the same call point in an application.
+	// This makes it easier to correlate spans in different traces.
+	//
+	// This field is semantically required to be set to non-empty string.
+	// Empty value is equivalent to an unknown span name.
+	//
+	// This field is required.
+	Name string `json:"name"`
+	// Distinguishes between spans generated in a particular context. For example,
+	// two spans with the same name may be distinguished using `CLIENT` (caller)
+	// and `SERVER` (callee) to identify queueing latency associated with the span.
+	Kind SpanKind `json:"kind,omitempty"`
+	// start_time_unix_nano is the start time of the span. On the client side, this is the time
+	// kept by the local machine where the span execution starts. On the server side, this
+	// is the time when the server's application handler starts running.
+	// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
+	//
+	// This field is semantically required and it is expected that end_time >= start_time.
+	StartTime time.Time `json:"startTimeUnixNano,omitempty"`
+	// end_time_unix_nano is the end time of the span. On the client side, this is the time
+	// kept by the local machine where the span execution ends. On the server side, this
+	// is the time when the server application handler stops running.
+	// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
+	//
+	// This field is semantically required and it is expected that end_time >= start_time.
+	EndTime time.Time `json:"endTimeUnixNano,omitempty"`
+	// attributes is a collection of key/value pairs. Note, global attributes
+	// like server name can be set using the resource API. Examples of attributes:
+	//
+	//     "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
+	//     "/http/server_latency": 300
+	//     "example.com/myattribute": true
+	//     "example.com/score": 10.239
+	//
+	// The OpenTelemetry API specification further restricts the allowed value types:
+	// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute
+	// Attribute keys MUST be unique (it is not allowed to have more than one
+	// attribute with the same key).
+	Attrs []Attr `json:"attributes,omitempty"`
+	// dropped_attributes_count is the number of attributes that were discarded. Attributes
+	// can be discarded because their keys are too long or because there are too many
+	// attributes. If this value is 0, then no attributes were dropped.
+	DroppedAttrs uint32 `json:"droppedAttributesCount,omitempty"`
+	// events is a collection of Event items.
+	Events []*SpanEvent `json:"events,omitempty"`
+	// dropped_events_count is the number of dropped events. If the value is 0, then no
+	// events were dropped.
+	DroppedEvents uint32 `json:"droppedEventsCount,omitempty"`
+	// links is a collection of Links, which are references from this span to a span
+	// in the same or different trace.
+	Links []*SpanLink `json:"links,omitempty"`
+	// dropped_links_count is the number of dropped links after the maximum size was
+	// enforced. If this value is 0, then no links were dropped.
+	DroppedLinks uint32 `json:"droppedLinksCount,omitempty"`
+	// An optional final status for this span. Semantically when Status isn't set, it means
+	// span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0).
+	Status *Status `json:"status,omitempty"`
+}
+
+// MarshalJSON encodes s into OTLP formatted JSON.
+func (s Span) MarshalJSON() ([]byte, error) {
+	startT := s.StartTime.UnixNano()
+	if s.StartTime.IsZero() || startT < 0 {
+		startT = 0
+	}
+
+	endT := s.EndTime.UnixNano()
+	if s.EndTime.IsZero() || endT < 0 {
+		endT = 0
+	}
+
+	// Override non-empty default SpanID marshal and omitempty.
+	var parentSpanId string
+	if !s.ParentSpanID.IsEmpty() {
+		b := make([]byte, hex.EncodedLen(spanIDSize))
+		hex.Encode(b, s.ParentSpanID[:])
+		parentSpanId = string(b)
+	}
+
+	type Alias Span
+	return json.Marshal(struct {
+		Alias
+		ParentSpanID string `json:"parentSpanId,omitempty"`
+		StartTime    uint64 `json:"startTimeUnixNano,omitempty"`
+		EndTime      uint64 `json:"endTimeUnixNano,omitempty"`
+	}{
+		Alias:        Alias(s),
+		ParentSpanID: parentSpanId,
+		StartTime:    uint64(startT),
+		EndTime:      uint64(endT),
+	})
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into s.
+func (s *Span) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid Span type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid Span field: %#v", keyIface)
+		}
+
+		switch key {
+		case "traceId", "trace_id":
+			err = decoder.Decode(&s.TraceID)
+		case "spanId", "span_id":
+			err = decoder.Decode(&s.SpanID)
+		case "traceState", "trace_state":
+			err = decoder.Decode(&s.TraceState)
+		case "parentSpanId", "parent_span_id":
+			err = decoder.Decode(&s.ParentSpanID)
+		case "flags":
+			err = decoder.Decode(&s.Flags)
+		case "name":
+			err = decoder.Decode(&s.Name)
+		case "kind":
+			err = decoder.Decode(&s.Kind)
+		case "startTimeUnixNano", "start_time_unix_nano":
+			var val protoUint64
+			err = decoder.Decode(&val)
+			s.StartTime = time.Unix(0, int64(val.Uint64()))
+		case "endTimeUnixNano", "end_time_unix_nano":
+			var val protoUint64
+			err = decoder.Decode(&val)
+			s.EndTime = time.Unix(0, int64(val.Uint64()))
+		case "attributes":
+			err = decoder.Decode(&s.Attrs)
+		case "droppedAttributesCount", "dropped_attributes_count":
+			err = decoder.Decode(&s.DroppedAttrs)
+		case "events":
+			err = decoder.Decode(&s.Events)
+		case "droppedEventsCount", "dropped_events_count":
+			err = decoder.Decode(&s.DroppedEvents)
+		case "links":
+			err = decoder.Decode(&s.Links)
+		case "droppedLinksCount", "dropped_links_count":
+			err = decoder.Decode(&s.DroppedLinks)
+		case "status":
+			err = decoder.Decode(&s.Status)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// SpanFlags represents constants used to interpret the
+// Span.flags field, which is protobuf 'fixed32' type and is to
+// be used as bit-fields. Each non-zero value defined in this enum is
+// a bit-mask.  To extract the bit-field, for example, use an
+// expression like:
+//
+//	(span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK)
+//
+// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+//
+// Note that Span flags were introduced in version 1.1 of the
+// OpenTelemetry protocol.  Older Span producers do not set this
+// field, consequently consumers should not rely on the absence of a
+// particular flag bit to indicate the presence of a particular feature.
+type SpanFlags int32
+
+const (
+	// Bits 0-7 are used for trace flags.
+	SpanFlagsTraceFlagsMask SpanFlags = 255
+	// Bits 8 and 9 are used to indicate that the parent span or link span is remote.
+	// Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.
+	// Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote.
+	SpanFlagsContextHasIsRemoteMask SpanFlags = 256
+	// SpanFlagsContextHasIsRemoteMask indicates the Span is remote.
+	SpanFlagsContextIsRemoteMask SpanFlags = 512
+)
+
+// SpanKind is the type of span. Can be used to specify additional relationships between spans
+// in addition to a parent/child relationship.
+type SpanKind int32
+
+const (
+	// Indicates that the span represents an internal operation within an application,
+	// as opposed to an operation happening at the boundaries. Default value.
+	SpanKindInternal SpanKind = 1
+	// Indicates that the span covers server-side handling of an RPC or other
+	// remote network request.
+	SpanKindServer SpanKind = 2
+	// Indicates that the span describes a request to some remote service.
+	SpanKindClient SpanKind = 3
+	// Indicates that the span describes a producer sending a message to a broker.
+	// Unlike CLIENT and SERVER, there is often no direct critical path latency relationship
+	// between producer and consumer spans. A PRODUCER span ends when the message was accepted
+	// by the broker while the logical processing of the message might span a much longer time.
+	SpanKindProducer SpanKind = 4
+	// Indicates that the span describes consumer receiving a message from a broker.
+	// Like the PRODUCER kind, there is often no direct critical path latency relationship
+	// between producer and consumer spans.
+	SpanKindConsumer SpanKind = 5
+)
+
+// Event is a time-stamped annotation of the span, consisting of user-supplied
+// text description and key-value pairs.
+type SpanEvent struct {
+	// time_unix_nano is the time the event occurred.
+	Time time.Time `json:"timeUnixNano,omitempty"`
+	// name of the event.
+	// This field is semantically required to be set to non-empty string.
+	Name string `json:"name,omitempty"`
+	// attributes is a collection of attribute key/value pairs on the event.
+	// Attribute keys MUST be unique (it is not allowed to have more than one
+	// attribute with the same key).
+	Attrs []Attr `json:"attributes,omitempty"`
+	// dropped_attributes_count is the number of dropped attributes. If the value is 0,
+	// then no attributes were dropped.
+	DroppedAttrs uint32 `json:"droppedAttributesCount,omitempty"`
+}
+
+// MarshalJSON encodes e into OTLP formatted JSON.
+func (e SpanEvent) MarshalJSON() ([]byte, error) {
+	t := e.Time.UnixNano()
+	if e.Time.IsZero() || t < 0 {
+		t = 0
+	}
+
+	type Alias SpanEvent
+	return json.Marshal(struct {
+		Alias
+		Time uint64 `json:"timeUnixNano,omitempty"`
+	}{
+		Alias: Alias(e),
+		Time:  uint64(t),
+	})
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into se.
+func (se *SpanEvent) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid SpanEvent type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid SpanEvent field: %#v", keyIface)
+		}
+
+		switch key {
+		case "timeUnixNano", "time_unix_nano":
+			var val protoUint64
+			err = decoder.Decode(&val)
+			se.Time = time.Unix(0, int64(val.Uint64()))
+		case "name":
+			err = decoder.Decode(&se.Name)
+		case "attributes":
+			err = decoder.Decode(&se.Attrs)
+		case "droppedAttributesCount", "dropped_attributes_count":
+			err = decoder.Decode(&se.DroppedAttrs)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// A pointer from the current span to another span in the same trace or in a
+// different trace. For example, this can be used in batching operations,
+// where a single batch handler processes multiple requests from different
+// traces or when the handler receives a request from a different project.
+type SpanLink struct {
+	// A unique identifier of a trace that this linked span is part of. The ID is a
+	// 16-byte array.
+	TraceID TraceID `json:"traceId,omitempty"`
+	// A unique identifier for the linked span. The ID is an 8-byte array.
+	SpanID SpanID `json:"spanId,omitempty"`
+	// The trace_state associated with the link.
+	TraceState string `json:"traceState,omitempty"`
+	// attributes is a collection of attribute key/value pairs on the link.
+	// Attribute keys MUST be unique (it is not allowed to have more than one
+	// attribute with the same key).
+	Attrs []Attr `json:"attributes,omitempty"`
+	// dropped_attributes_count is the number of dropped attributes. If the value is 0,
+	// then no attributes were dropped.
+	DroppedAttrs uint32 `json:"droppedAttributesCount,omitempty"`
+	// Flags, a bit field.
+	//
+	// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace
+	// Context specification. To read the 8-bit W3C trace flag, use
+	// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.
+	//
+	// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.
+	//
+	// Bits 8 and 9 represent the 3 states of whether the link is remote.
+	// The states are (unknown, is not remote, is remote).
+	// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.
+	// To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.
+	//
+	// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.
+	// When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero.
+	//
+	// [Optional].
+	Flags uint32 `json:"flags,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into sl.
+func (sl *SpanLink) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid SpanLink type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid SpanLink field: %#v", keyIface)
+		}
+
+		switch key {
+		case "traceId", "trace_id":
+			err = decoder.Decode(&sl.TraceID)
+		case "spanId", "span_id":
+			err = decoder.Decode(&sl.SpanID)
+		case "traceState", "trace_state":
+			err = decoder.Decode(&sl.TraceState)
+		case "attributes":
+			err = decoder.Decode(&sl.Attrs)
+		case "droppedAttributesCount", "dropped_attributes_count":
+			err = decoder.Decode(&sl.DroppedAttrs)
+		case "flags":
+			err = decoder.Decode(&sl.Flags)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/status.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/status.go
new file mode 100644
index 0000000..1217776
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/status.go
@@ -0,0 +1,40 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+// For the semantics of status codes see
+// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status
+type StatusCode int32
+
+const (
+	// The default status.
+	StatusCodeUnset StatusCode = 0
+	// The Span has been validated by an Application developer or Operator to
+	// have completed successfully.
+	StatusCodeOK StatusCode = 1
+	// The Span contains an error.
+	StatusCodeError StatusCode = 2
+)
+
+var statusCodeStrings = []string{
+	"Unset",
+	"OK",
+	"Error",
+}
+
+func (s StatusCode) String() string {
+	if s >= 0 && int(s) < len(statusCodeStrings) {
+		return statusCodeStrings[s]
+	}
+	return "<unknown telemetry.StatusCode>"
+}
+
+// The Status type defines a logical error model that is suitable for different
+// programming environments, including REST APIs and RPC APIs.
+type Status struct {
+	// A developer-facing human readable error message.
+	Message string `json:"message,omitempty"`
+	// The status code.
+	Code StatusCode `json:"code,omitempty"`
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/traces.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/traces.go
new file mode 100644
index 0000000..69a348f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/traces.go
@@ -0,0 +1,189 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package telemetry
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// Traces represents the traces data that can be stored in a persistent storage,
+// OR can be embedded by other protocols that transfer OTLP traces data but do
+// not implement the OTLP protocol.
+//
+// The main difference between this message and collector protocol is that
+// in this message there will not be any "control" or "metadata" specific to
+// OTLP protocol.
+//
+// When new fields are added into this message, the OTLP request MUST be updated
+// as well.
+type Traces struct {
+	// An array of ResourceSpans.
+	// For data coming from a single resource this array will typically contain
+	// one element. Intermediary nodes that receive data from multiple origins
+	// typically batch the data before forwarding further and in that case this
+	// array will contain multiple elements.
+	ResourceSpans []*ResourceSpans `json:"resourceSpans,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into td.
+func (td *Traces) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid TracesData type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid TracesData field: %#v", keyIface)
+		}
+
+		switch key {
+		case "resourceSpans", "resource_spans":
+			err = decoder.Decode(&td.ResourceSpans)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// A collection of ScopeSpans from a Resource.
+type ResourceSpans struct {
+	// The resource for the spans in this message.
+	// If this field is not set then no resource info is known.
+	Resource Resource `json:"resource"`
+	// A list of ScopeSpans that originate from a resource.
+	ScopeSpans []*ScopeSpans `json:"scopeSpans,omitempty"`
+	// This schema_url applies to the data in the "resource" field. It does not apply
+	// to the data in the "scope_spans" field which have their own schema_url field.
+	SchemaURL string `json:"schemaUrl,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into rs.
+func (rs *ResourceSpans) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid ResourceSpans type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid ResourceSpans field: %#v", keyIface)
+		}
+
+		switch key {
+		case "resource":
+			err = decoder.Decode(&rs.Resource)
+		case "scopeSpans", "scope_spans":
+			err = decoder.Decode(&rs.ScopeSpans)
+		case "schemaUrl", "schema_url":
+			err = decoder.Decode(&rs.SchemaURL)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// A collection of Spans produced by an InstrumentationScope.
+type ScopeSpans struct {
+	// The instrumentation scope information for the spans in this message.
+	// Semantically when InstrumentationScope isn't set, it is equivalent with
+	// an empty instrumentation scope name (unknown).
+	Scope *Scope `json:"scope"`
+	// A list of Spans that originate from an instrumentation scope.
+	Spans []*Span `json:"spans,omitempty"`
+	// The Schema URL, if known. This is the identifier of the Schema that the span data
+	// is recorded in. To learn more about Schema URL see
+	// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
+	// This schema_url applies to all spans and span events in the "spans" field.
+	SchemaURL string `json:"schemaUrl,omitempty"`
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into ss.
+func (ss *ScopeSpans) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid ScopeSpans type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid ScopeSpans field: %#v", keyIface)
+		}
+
+		switch key {
+		case "scope":
+			err = decoder.Decode(&ss.Scope)
+		case "spans":
+			err = decoder.Decode(&ss.Spans)
+		case "schemaUrl", "schema_url":
+			err = decoder.Decode(&ss.SchemaURL)
+		default:
+			// Skip unknown.
+		}
+
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/value.go b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/value.go
new file mode 100644
index 0000000..0dd01b0
--- /dev/null
+++ b/vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/value.go
@@ -0,0 +1,452 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+//go:generate stringer -type=ValueKind -trimprefix=ValueKind
+
+package telemetry
+
+import (
+	"bytes"
+	"cmp"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"slices"
+	"strconv"
+	"unsafe"
+)
+
+// A Value represents a structured value.
+// A zero value is valid and represents an empty value.
+type Value struct {
+	// Ensure forward compatibility by explicitly making this not comparable.
+	noCmp [0]func() //nolint: unused  // This is indeed used.
+
+	// num holds the value for Int64, Float64, and Bool. It holds the length
+	// for String, Bytes, Slice, Map.
+	num uint64
+	// any holds either the KindBool, KindInt64, KindFloat64, stringptr,
+	// bytesptr, sliceptr, or mapptr. If KindBool, KindInt64, or KindFloat64
+	// then the value of Value is in num as described above. Otherwise, it
+	// contains the value wrapped in the appropriate type.
+	any any
+}
+
+type (
+	// sliceptr represents a value in Value.any for KindString Values.
+	stringptr *byte
+	// bytesptr represents a value in Value.any for KindBytes Values.
+	bytesptr *byte
+	// sliceptr represents a value in Value.any for KindSlice Values.
+	sliceptr *Value
+	// mapptr represents a value in Value.any for KindMap Values.
+	mapptr *Attr
+)
+
+// ValueKind is the kind of a [Value].
+type ValueKind int
+
+// ValueKind values.
+const (
+	ValueKindEmpty ValueKind = iota
+	ValueKindBool
+	ValueKindFloat64
+	ValueKindInt64
+	ValueKindString
+	ValueKindBytes
+	ValueKindSlice
+	ValueKindMap
+)
+
+var valueKindStrings = []string{
+	"Empty",
+	"Bool",
+	"Float64",
+	"Int64",
+	"String",
+	"Bytes",
+	"Slice",
+	"Map",
+}
+
+func (k ValueKind) String() string {
+	if k >= 0 && int(k) < len(valueKindStrings) {
+		return valueKindStrings[k]
+	}
+	return "<unknown telemetry.ValueKind>"
+}
+
+// StringValue returns a new [Value] for a string.
+func StringValue(v string) Value {
+	return Value{
+		num: uint64(len(v)),
+		any: stringptr(unsafe.StringData(v)),
+	}
+}
+
+// IntValue returns a [Value] for an int.
+func IntValue(v int) Value { return Int64Value(int64(v)) }
+
+// Int64Value returns a [Value] for an int64.
+func Int64Value(v int64) Value {
+	return Value{num: uint64(v), any: ValueKindInt64}
+}
+
+// Float64Value returns a [Value] for a float64.
+func Float64Value(v float64) Value {
+	return Value{num: math.Float64bits(v), any: ValueKindFloat64}
+}
+
+// BoolValue returns a [Value] for a bool.
+func BoolValue(v bool) Value { //nolint:revive // Not a control flag.
+	var n uint64
+	if v {
+		n = 1
+	}
+	return Value{num: n, any: ValueKindBool}
+}
+
+// BytesValue returns a [Value] for a byte slice. The passed slice must not be
+// changed after it is passed.
+func BytesValue(v []byte) Value {
+	return Value{
+		num: uint64(len(v)),
+		any: bytesptr(unsafe.SliceData(v)),
+	}
+}
+
+// SliceValue returns a [Value] for a slice of [Value]. The passed slice must
+// not be changed after it is passed.
+func SliceValue(vs ...Value) Value {
+	return Value{
+		num: uint64(len(vs)),
+		any: sliceptr(unsafe.SliceData(vs)),
+	}
+}
+
+// MapValue returns a new [Value] for a slice of key-value pairs. The passed
+// slice must not be changed after it is passed.
+func MapValue(kvs ...Attr) Value {
+	return Value{
+		num: uint64(len(kvs)),
+		any: mapptr(unsafe.SliceData(kvs)),
+	}
+}
+
+// AsString returns the value held by v as a string.
+func (v Value) AsString() string {
+	if sp, ok := v.any.(stringptr); ok {
+		return unsafe.String(sp, v.num)
+	}
+	// TODO: error handle
+	return ""
+}
+
+// asString returns the value held by v as a string. It will panic if the Value
+// is not KindString.
+func (v Value) asString() string {
+	return unsafe.String(v.any.(stringptr), v.num)
+}
+
+// AsInt64 returns the value held by v as an int64.
+func (v Value) AsInt64() int64 {
+	if v.Kind() != ValueKindInt64 {
+		// TODO: error handle
+		return 0
+	}
+	return v.asInt64()
+}
+
+// asInt64 returns the value held by v as an int64. If v is not of KindInt64,
+// this will return garbage.
+func (v Value) asInt64() int64 {
+	// Assumes v.num was a valid int64 (overflow not checked).
+	return int64(v.num) // nolint: gosec
+}
+
+// AsBool returns the value held by v as a bool.
+func (v Value) AsBool() bool {
+	if v.Kind() != ValueKindBool {
+		// TODO: error handle
+		return false
+	}
+	return v.asBool()
+}
+
+// asBool returns the value held by v as a bool. If v is not of KindBool, this
+// will return garbage.
+func (v Value) asBool() bool { return v.num == 1 }
+
+// AsFloat64 returns the value held by v as a float64.
+func (v Value) AsFloat64() float64 {
+	if v.Kind() != ValueKindFloat64 {
+		// TODO: error handle
+		return 0
+	}
+	return v.asFloat64()
+}
+
+// asFloat64 returns the value held by v as a float64. If v is not of
+// KindFloat64, this will return garbage.
+func (v Value) asFloat64() float64 { return math.Float64frombits(v.num) }
+
+// AsBytes returns the value held by v as a []byte.
+func (v Value) AsBytes() []byte {
+	if sp, ok := v.any.(bytesptr); ok {
+		return unsafe.Slice((*byte)(sp), v.num)
+	}
+	// TODO: error handle
+	return nil
+}
+
+// asBytes returns the value held by v as a []byte. It will panic if the Value
+// is not KindBytes.
+func (v Value) asBytes() []byte {
+	return unsafe.Slice((*byte)(v.any.(bytesptr)), v.num)
+}
+
+// AsSlice returns the value held by v as a []Value.
+func (v Value) AsSlice() []Value {
+	if sp, ok := v.any.(sliceptr); ok {
+		return unsafe.Slice((*Value)(sp), v.num)
+	}
+	// TODO: error handle
+	return nil
+}
+
+// asSlice returns the value held by v as a []Value. It will panic if the Value
+// is not KindSlice.
+func (v Value) asSlice() []Value {
+	return unsafe.Slice((*Value)(v.any.(sliceptr)), v.num)
+}
+
+// AsMap returns the value held by v as a []Attr.
+func (v Value) AsMap() []Attr {
+	if sp, ok := v.any.(mapptr); ok {
+		return unsafe.Slice((*Attr)(sp), v.num)
+	}
+	// TODO: error handle
+	return nil
+}
+
+// asMap returns the value held by v as a []Attr. It will panic if the
+// Value is not KindMap.
+func (v Value) asMap() []Attr {
+	return unsafe.Slice((*Attr)(v.any.(mapptr)), v.num)
+}
+
+// Kind returns the Kind of v.
+func (v Value) Kind() ValueKind {
+	switch x := v.any.(type) {
+	case ValueKind:
+		return x
+	case stringptr:
+		return ValueKindString
+	case bytesptr:
+		return ValueKindBytes
+	case sliceptr:
+		return ValueKindSlice
+	case mapptr:
+		return ValueKindMap
+	default:
+		return ValueKindEmpty
+	}
+}
+
+// Empty returns if v does not hold any value.
+func (v Value) Empty() bool { return v.Kind() == ValueKindEmpty }
+
+// Equal returns if v is equal to w.
+func (v Value) Equal(w Value) bool {
+	k1 := v.Kind()
+	k2 := w.Kind()
+	if k1 != k2 {
+		return false
+	}
+	switch k1 {
+	case ValueKindInt64, ValueKindBool:
+		return v.num == w.num
+	case ValueKindString:
+		return v.asString() == w.asString()
+	case ValueKindFloat64:
+		return v.asFloat64() == w.asFloat64()
+	case ValueKindSlice:
+		return slices.EqualFunc(v.asSlice(), w.asSlice(), Value.Equal)
+	case ValueKindMap:
+		sv := sortMap(v.asMap())
+		sw := sortMap(w.asMap())
+		return slices.EqualFunc(sv, sw, Attr.Equal)
+	case ValueKindBytes:
+		return bytes.Equal(v.asBytes(), w.asBytes())
+	case ValueKindEmpty:
+		return true
+	default:
+		// TODO: error handle
+		return false
+	}
+}
+
+func sortMap(m []Attr) []Attr {
+	sm := make([]Attr, len(m))
+	copy(sm, m)
+	slices.SortFunc(sm, func(a, b Attr) int {
+		return cmp.Compare(a.Key, b.Key)
+	})
+
+	return sm
+}
+
+// String returns Value's value as a string, formatted like [fmt.Sprint].
+//
+// The returned string is meant for debugging;
+// the string representation is not stable.
+func (v Value) String() string {
+	switch v.Kind() {
+	case ValueKindString:
+		return v.asString()
+	case ValueKindInt64:
+		// Assumes v.num was a valid int64 (overflow not checked).
+		return strconv.FormatInt(int64(v.num), 10) // nolint: gosec
+	case ValueKindFloat64:
+		return strconv.FormatFloat(v.asFloat64(), 'g', -1, 64)
+	case ValueKindBool:
+		return strconv.FormatBool(v.asBool())
+	case ValueKindBytes:
+		return fmt.Sprint(v.asBytes())
+	case ValueKindMap:
+		return fmt.Sprint(v.asMap())
+	case ValueKindSlice:
+		return fmt.Sprint(v.asSlice())
+	case ValueKindEmpty:
+		return "<nil>"
+	default:
+		// Try to handle this as gracefully as possible.
+		//
+		// Don't panic here. The goal here is to have developers find this
+		// first if a slog.Kind is is not handled. It is
+		// preferable to have user's open issue asking why their attributes
+		// have a "unhandled: " prefix than say that their code is panicking.
+		return fmt.Sprintf("<unhandled telemetry.ValueKind: %s>", v.Kind())
+	}
+}
+
+// MarshalJSON encodes v into OTLP formatted JSON.
+func (v *Value) MarshalJSON() ([]byte, error) {
+	switch v.Kind() {
+	case ValueKindString:
+		return json.Marshal(struct {
+			Value string `json:"stringValue"`
+		}{v.asString()})
+	case ValueKindInt64:
+		return json.Marshal(struct {
+			Value string `json:"intValue"`
+		}{strconv.FormatInt(int64(v.num), 10)})
+	case ValueKindFloat64:
+		return json.Marshal(struct {
+			Value float64 `json:"doubleValue"`
+		}{v.asFloat64()})
+	case ValueKindBool:
+		return json.Marshal(struct {
+			Value bool `json:"boolValue"`
+		}{v.asBool()})
+	case ValueKindBytes:
+		return json.Marshal(struct {
+			Value []byte `json:"bytesValue"`
+		}{v.asBytes()})
+	case ValueKindMap:
+		return json.Marshal(struct {
+			Value struct {
+				Values []Attr `json:"values"`
+			} `json:"kvlistValue"`
+		}{struct {
+			Values []Attr `json:"values"`
+		}{v.asMap()}})
+	case ValueKindSlice:
+		return json.Marshal(struct {
+			Value struct {
+				Values []Value `json:"values"`
+			} `json:"arrayValue"`
+		}{struct {
+			Values []Value `json:"values"`
+		}{v.asSlice()}})
+	case ValueKindEmpty:
+		return nil, nil
+	default:
+		return nil, fmt.Errorf("unknown Value kind: %s", v.Kind().String())
+	}
+}
+
+// UnmarshalJSON decodes the OTLP formatted JSON contained in data into v.
+func (v *Value) UnmarshalJSON(data []byte) error {
+	decoder := json.NewDecoder(bytes.NewReader(data))
+
+	t, err := decoder.Token()
+	if err != nil {
+		return err
+	}
+	if t != json.Delim('{') {
+		return errors.New("invalid Value type")
+	}
+
+	for decoder.More() {
+		keyIface, err := decoder.Token()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				// Empty.
+				return nil
+			}
+			return err
+		}
+
+		key, ok := keyIface.(string)
+		if !ok {
+			return fmt.Errorf("invalid Value key: %#v", keyIface)
+		}
+
+		switch key {
+		case "stringValue", "string_value":
+			var val string
+			err = decoder.Decode(&val)
+			*v = StringValue(val)
+		case "boolValue", "bool_value":
+			var val bool
+			err = decoder.Decode(&val)
+			*v = BoolValue(val)
+		case "intValue", "int_value":
+			var val protoInt64
+			err = decoder.Decode(&val)
+			*v = Int64Value(val.Int64())
+		case "doubleValue", "double_value":
+			var val float64
+			err = decoder.Decode(&val)
+			*v = Float64Value(val)
+		case "bytesValue", "bytes_value":
+			var val64 string
+			if err := decoder.Decode(&val64); err != nil {
+				return err
+			}
+			var val []byte
+			val, err = base64.StdEncoding.DecodeString(val64)
+			*v = BytesValue(val)
+		case "arrayValue", "array_value":
+			var val struct{ Values []Value }
+			err = decoder.Decode(&val)
+			*v = SliceValue(val.Values...)
+		case "kvlistValue", "kvlist_value":
+			var val struct{ Values []Attr }
+			err = decoder.Decode(&val)
+			*v = MapValue(val.Values...)
+		default:
+			// Skip unknown.
+			continue
+		}
+		// Use first valid. Ignore the rest.
+		return err
+	}
+
+	// Only unknown fields. Return nil without unmarshaling any value.
+	return nil
+}
