From 64bfb348d875fbd1e877a6c63371b5ed7d6b1717 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Mon, 25 Nov 2024 23:52:17 +0530
Subject: [PATCH 01/14] Add support for custom attributes function

---
 extra/redisotel/config.go  | 20 ++++++++++++++++----
 extra/redisotel/metrics.go |  4 ++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/extra/redisotel/config.go b/extra/redisotel/config.go
index c02ee0b31..1119780c1 100644
--- a/extra/redisotel/config.go
+++ b/extra/redisotel/config.go
@@ -1,6 +1,8 @@
 package redisotel
 
 import (
+	"context"
+
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/metric"
@@ -11,8 +13,9 @@ import (
 type config struct {
 	// Common options.
 
-	dbSystem string
-	attrs    []attribute.KeyValue
+	dbSystem  string
+	attrs     []attribute.KeyValue
+	attrsFunc func(context.Context) []attribute.KeyValue
 
 	// Tracing options.
 
@@ -51,8 +54,9 @@ func (fn option) metrics() {}
 
 func newConfig(opts ...baseOption) *config {
 	conf := &config{
-		dbSystem: "redis",
-		attrs:    []attribute.KeyValue{},
+		dbSystem:  "redis",
+		attrs:     []attribute.KeyValue{},
+		attrsFunc: func(ctx context.Context) []attribute.KeyValue { return []attribute.KeyValue{} },
 
 		tp:            otel.GetTracerProvider(),
 		mp:            otel.GetMeterProvider(),
@@ -81,6 +85,14 @@ func WithAttributes(attrs ...attribute.KeyValue) Option {
 	})
 }
 
+// WithAttributesFunc takes a function that returns additional attributes to be added using the context.
+// This is executed only in ProcessPipelineHook and ProcessHook
+func WithAttributesFunc(f func(context.Context) []attribute.KeyValue) Option {
+	return option(func(conf *config) {
+		conf.attrsFunc = f
+	})
+}
+
 //------------------------------------------------------------------------------
 
 type TracingOption interface {
diff --git a/extra/redisotel/metrics.go b/extra/redisotel/metrics.go
index 915838f34..1fb9e9b79 100644
--- a/extra/redisotel/metrics.go
+++ b/extra/redisotel/metrics.go
@@ -175,6 +175,7 @@ func addMetricsHook(rdb *redis.Client, conf *config) error {
 		createTime: createTime,
 		useTime:    useTime,
 		attrs:      conf.attrs,
+		attrsFunc: conf.attrsFunc,
 	})
 	return nil
 }
@@ -183,6 +184,7 @@ type metricsHook struct {
 	createTime metric.Float64Histogram
 	useTime    metric.Float64Histogram
 	attrs      []attribute.KeyValue
+	attrsFunc func(context.Context) []attribute.KeyValue
 }
 
 var _ redis.Hook = (*metricsHook)(nil)
@@ -214,6 +216,7 @@ func (mh *metricsHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 
 		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
 		attrs = append(attrs, mh.attrs...)
+		attrs = append(attrs, mh.attrsFunc(ctx)...)
 		attrs = append(attrs, attribute.String("type", "command"))
 		attrs = append(attrs, statusAttr(err))
 
@@ -235,6 +238,7 @@ func (mh *metricsHook) ProcessPipelineHook(
 
 		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
 		attrs = append(attrs, mh.attrs...)
+		attrs = append(attrs, mh.attrsFunc(ctx)...)
 		attrs = append(attrs, attribute.String("type", "pipeline"))
 		attrs = append(attrs, statusAttr(err))
 

From 103a07a35ea75145df5c668cd2dc6c00666ec598 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 26 Nov 2024 00:00:05 +0530
Subject: [PATCH 02/14] Formatting

---
 extra/redisotel/metrics.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/redisotel/metrics.go b/extra/redisotel/metrics.go
index 1fb9e9b79..6f5b9c8f4 100644
--- a/extra/redisotel/metrics.go
+++ b/extra/redisotel/metrics.go
@@ -175,7 +175,7 @@ func addMetricsHook(rdb *redis.Client, conf *config) error {
 		createTime: createTime,
 		useTime:    useTime,
 		attrs:      conf.attrs,
-		attrsFunc: conf.attrsFunc,
+		attrsFunc:  conf.attrsFunc,
 	})
 	return nil
 }
@@ -184,7 +184,7 @@ type metricsHook struct {
 	createTime metric.Float64Histogram
 	useTime    metric.Float64Histogram
 	attrs      []attribute.KeyValue
-	attrsFunc func(context.Context) []attribute.KeyValue
+	attrsFunc  func(context.Context) []attribute.KeyValue
 }
 
 var _ redis.Hook = (*metricsHook)(nil)

From bfba6541759f8b6fc06c55abcf9536e0d4094fca Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 17 Dec 2024 00:55:39 +0530
Subject: [PATCH 03/14] Update ordering

---
 extra/redisotel/metrics.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/redisotel/metrics.go b/extra/redisotel/metrics.go
index 6f5b9c8f4..5ec5128e9 100644
--- a/extra/redisotel/metrics.go
+++ b/extra/redisotel/metrics.go
@@ -215,8 +215,8 @@ func (mh *metricsHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 		dur := time.Since(start)
 
 		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
-		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, mh.attrsFunc(ctx)...)
+		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, attribute.String("type", "command"))
 		attrs = append(attrs, statusAttr(err))
 
@@ -237,8 +237,8 @@ func (mh *metricsHook) ProcessPipelineHook(
 		dur := time.Since(start)
 
 		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
-		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, mh.attrsFunc(ctx)...)
+		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, attribute.String("type", "pipeline"))
 		attrs = append(attrs, statusAttr(err))
 

From dffbe613abc88f162b59fca2ac20db1dd56f6193 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 17 Dec 2024 00:55:43 +0530
Subject: [PATCH 04/14] Add tests

---
 extra/redisotel/go.mod          |  17 ++--
 extra/redisotel/go.sum          |  26 ++++--
 extra/redisotel/metrics_test.go | 148 ++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 16 deletions(-)
 create mode 100644 extra/redisotel/metrics_test.go

diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod
index b2e30b394..75897c346 100644
--- a/extra/redisotel/go.mod
+++ b/extra/redisotel/go.mod
@@ -9,20 +9,23 @@ replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd
 require (
 	github.com/redis/go-redis/extra/rediscmd/v9 v9.6.2
 	github.com/redis/go-redis/v9 v9.6.2
-	go.opentelemetry.io/otel v1.22.0
-	go.opentelemetry.io/otel/metric v1.22.0
-	go.opentelemetry.io/otel/sdk v1.22.0
-	go.opentelemetry.io/otel/trace v1.22.0
+	github.com/stretchr/testify v1.10.0
+	go.opentelemetry.io/otel v1.23.0
+	go.opentelemetry.io/otel/metric v1.23.0
+	go.opentelemetry.io/otel/sdk v1.23.0
+	go.opentelemetry.io/otel/sdk/metric v1.23.0
+	go.opentelemetry.io/otel/trace v1.23.0
 )
 
 require (
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/go-logr/logr v1.4.1 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	golang.org/x/sys v0.16.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
 
-retract (
-	v9.5.3 // This version was accidentally released.
-)
+retract v9.5.3 // This version was accidentally released.
diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum
index 9eb9bcd4e..b689b6ff5 100644
--- a/extra/redisotel/go.sum
+++ b/extra/redisotel/go.sum
@@ -3,6 +3,7 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
 github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -12,15 +13,22 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
-go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
-go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
-go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
-go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
-go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
-go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
-go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
+go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
+go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
+go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
+go.opentelemetry.io/otel/sdk v1.23.0 h1:0KM9Zl2esnl+WSukEmlaAEjVY5HDZANOHferLq36BPc=
+go.opentelemetry.io/otel/sdk v1.23.0/go.mod h1:wUscup7byToqyKJSilEtMf34FgdCAsFpFOjXnAwFfO0=
+go.opentelemetry.io/otel/sdk/metric v1.23.0 h1:u81lMvmK6GMgN4Fty7K7S6cSKOZhMKJMK2TB+KaTs0I=
+go.opentelemetry.io/otel/sdk/metric v1.23.0/go.mod h1:2LUOToN/FdX6wtfpHybOnCZjoZ6ViYajJYMiJ1LKDtQ=
+go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
+go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
 golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
 golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/extra/redisotel/metrics_test.go b/extra/redisotel/metrics_test.go
new file mode 100644
index 000000000..5ebc987e8
--- /dev/null
+++ b/extra/redisotel/metrics_test.go
@@ -0,0 +1,148 @@
+package redisotel
+
+import (
+	"context"
+	"testing"
+
+	"github.com/redis/go-redis/v9"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/sdk/instrumentation"
+	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
+	"go.opentelemetry.io/otel/sdk/metric/metricdata"
+	"go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest"
+	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
+)
+
+var instrumentationScope = instrumentation.Scope{
+	Name:    instrumName,
+	Version: "semver:" + redis.Version(),
+}
+
+func setupMetrics(conf *config) (*sdkmetric.ManualReader, *redis.Client) {
+	reader := sdkmetric.NewManualReader()
+	mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
+	otel.SetMeterProvider(mp)
+
+	rdb := redis.NewClient(&redis.Options{
+		Addr: ":6379",
+	})
+	if conf.meter == nil {
+		conf.meter = conf.mp.Meter(
+			instrumName,
+			metric.WithInstrumentationVersion("semver:"+redis.Version()),
+		)
+	}
+	addMetricsHook(rdb, conf)
+	return reader, rdb
+}
+
+func TestMetrics(t *testing.T) {
+	reader, rdb := setupMetrics(newConfig())
+	rdb.Get(context.Background(), "key")
+
+	want := metricdata.ScopeMetrics{
+		Scope: instrumentationScope,
+		Metrics: []metricdata.Metrics{
+			{
+				Name:        "db.client.connections.create_time",
+				Description: "The time it took to create a new connection.",
+				Unit:        "ms",
+				Data: metricdata.Histogram[float64]{
+					Temporality: metricdata.CumulativeTemporality,
+					DataPoints: []metricdata.HistogramDataPoint[float64]{
+						{
+							Attributes: attribute.NewSet(
+								semconv.DBSystemRedis,
+								attribute.String("status", "error"),
+							),
+						},
+					},
+				},
+			},
+			{
+				Name:        "db.client.connections.use_time",
+				Description: "The time between borrowing a connection and returning it to the pool.",
+				Unit:        "ms",
+				Data: metricdata.Histogram[float64]{
+					Temporality: metricdata.CumulativeTemporality,
+					DataPoints: []metricdata.HistogramDataPoint[float64]{
+						{
+							Attributes: attribute.NewSet(
+								semconv.DBSystemRedis,
+								attribute.String("type", "command"),
+								attribute.String("status", "error"),
+							),
+						},
+					},
+				},
+			},
+		},
+	}
+	rm := metricdata.ResourceMetrics{}
+	err := reader.Collect(context.Background(), &rm)
+	assert.NoError(t, err)
+	require.Len(t, rm.ScopeMetrics, 1)
+	metricdatatest.AssertEqual(t, want, rm.ScopeMetrics[0], metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreValue())
+}
+
+func TestCustomAttributes(t *testing.T) {
+	customAttrFn := func(ctx context.Context) []attribute.KeyValue {
+		return []attribute.KeyValue{
+			attribute.String("custom", "value"),
+		}
+	}
+	config := newConfig(WithAttributesFunc(customAttrFn))
+	reader, rdb := setupMetrics(config)
+
+	rdb.Get(context.Background(), "key")
+
+	want := metricdata.ScopeMetrics{
+		Scope: instrumentationScope,
+		Metrics: []metricdata.Metrics{
+			{
+				Name:        "db.client.connections.create_time",
+				Description: "The time it took to create a new connection.",
+				Unit:        "ms",
+				Data: metricdata.Histogram[float64]{
+					Temporality: metricdata.CumulativeTemporality,
+					DataPoints: []metricdata.HistogramDataPoint[float64]{
+						{
+							Attributes: attribute.NewSet(
+								semconv.DBSystemRedis,
+								attribute.String("status", "error"),
+							),
+						},
+					},
+				},
+			},
+			{
+				Name:        "db.client.connections.use_time",
+				Description: "The time between borrowing a connection and returning it to the pool.",
+				Unit:        "ms",
+				Data: metricdata.Histogram[float64]{
+					Temporality: metricdata.CumulativeTemporality,
+					DataPoints: []metricdata.HistogramDataPoint[float64]{
+						{
+							Attributes: attribute.NewSet(
+								semconv.DBSystemRedis,
+								attribute.String("type", "command"),
+								attribute.String("status", "error"),
+								attribute.String("custom", "value"),
+							),
+						},
+					},
+				},
+			},
+		},
+	}
+	rm := metricdata.ResourceMetrics{}
+	err := reader.Collect(context.Background(), &rm)
+	assert.NoError(t, err)
+	require.Len(t, rm.ScopeMetrics, 1)
+	metricdatatest.AssertEqual(t, want, rm.ScopeMetrics[0], metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreValue())
+}

From f7d3f48e2e7c006c5e7436b607053a12745e0c9b Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 17 Dec 2024 19:03:13 +0530
Subject: [PATCH 05/14] Fix tests

---
 extra/redisotel/metrics_test.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/extra/redisotel/metrics_test.go b/extra/redisotel/metrics_test.go
index 5ebc987e8..0c8535ace 100644
--- a/extra/redisotel/metrics_test.go
+++ b/extra/redisotel/metrics_test.go
@@ -58,7 +58,7 @@ func TestMetrics(t *testing.T) {
 						{
 							Attributes: attribute.NewSet(
 								semconv.DBSystemRedis,
-								attribute.String("status", "error"),
+								attribute.String("status", "ok"),
 							),
 						},
 					},
@@ -75,7 +75,7 @@ func TestMetrics(t *testing.T) {
 							Attributes: attribute.NewSet(
 								semconv.DBSystemRedis,
 								attribute.String("type", "command"),
-								attribute.String("status", "error"),
+								attribute.String("status", "ok"),
 							),
 						},
 					},
@@ -114,7 +114,7 @@ func TestCustomAttributes(t *testing.T) {
 						{
 							Attributes: attribute.NewSet(
 								semconv.DBSystemRedis,
-								attribute.String("status", "error"),
+								attribute.String("status", "ok"),
 							),
 						},
 					},
@@ -131,7 +131,7 @@ func TestCustomAttributes(t *testing.T) {
 							Attributes: attribute.NewSet(
 								semconv.DBSystemRedis,
 								attribute.String("type", "command"),
-								attribute.String("status", "error"),
+								attribute.String("status", "ok"),
 								attribute.String("custom", "value"),
 							),
 						},

From f376e01c43445fe84dca575346a8433a381323c7 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Thu, 16 Jan 2025 20:00:16 +0530
Subject: [PATCH 06/14] Fix tests by using specific meter providers

---
 extra/redisotel/metrics_test.go | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/extra/redisotel/metrics_test.go b/extra/redisotel/metrics_test.go
index 0c8535ace..aecf60da9 100644
--- a/extra/redisotel/metrics_test.go
+++ b/extra/redisotel/metrics_test.go
@@ -8,7 +8,6 @@ import (
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
-	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/metric"
 	"go.opentelemetry.io/otel/sdk/instrumentation"
@@ -26,8 +25,8 @@ var instrumentationScope = instrumentation.Scope{
 func setupMetrics(conf *config) (*sdkmetric.ManualReader, *redis.Client) {
 	reader := sdkmetric.NewManualReader()
 	mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
-	otel.SetMeterProvider(mp)
-
+	conf.mp = mp
+	
 	rdb := redis.NewClient(&redis.Options{
 		Addr: ":6379",
 	})
@@ -43,7 +42,7 @@ func setupMetrics(conf *config) (*sdkmetric.ManualReader, *redis.Client) {
 
 func TestMetrics(t *testing.T) {
 	reader, rdb := setupMetrics(newConfig())
-	rdb.Get(context.Background(), "key")
+	rdb.Ping(context.Background())
 
 	want := metricdata.ScopeMetrics{
 		Scope: instrumentationScope,
@@ -99,7 +98,7 @@ func TestCustomAttributes(t *testing.T) {
 	config := newConfig(WithAttributesFunc(customAttrFn))
 	reader, rdb := setupMetrics(config)
 
-	rdb.Get(context.Background(), "key")
+	rdb.Ping(context.Background())
 
 	want := metricdata.ScopeMetrics{
 		Scope: instrumentationScope,

From f5c64c0d7ea49d9d320c84163d273531ac744c35 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 4 Feb 2025 17:44:12 +0530
Subject: [PATCH 07/14] Add examples

---
 example/otel/client.go |  9 ++++++++-
 example/otel/go.mod    | 12 ++++++------
 example/otel/go.sum    | 30 +++++++++++++++++++-----------
 3 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/example/otel/client.go b/example/otel/client.go
index 984d83f09..c216771b6 100644
--- a/example/otel/client.go
+++ b/example/otel/client.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/uptrace/uptrace-go/uptrace"
 	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
 
 	"github.com/redis/go-redis/extra/redisotel/v9"
@@ -17,6 +18,11 @@ import (
 
 var tracer = otel.Tracer("github.com/redis/go-redis/example/otel")
 
+func customAttrFn(ctx context.Context) []attribute.KeyValue {
+	return []attribute.KeyValue{
+		attribute.String("custom_attr", "custom_value"),
+	}
+}
 func main() {
 	ctx := context.Background()
 
@@ -32,7 +38,8 @@ func main() {
 	rdb := redis.NewClient(&redis.Options{
 		Addr: ":6379",
 	})
-	if err := redisotel.InstrumentTracing(rdb); err != nil {
+
+	if err := redisotel.InstrumentTracing(rdb, redisotel.WithAttributesFunc(customAttrFn)); err != nil {
 		panic(err)
 	}
 	if err := redisotel.InstrumentMetrics(rdb); err != nil {
diff --git a/example/otel/go.mod b/example/otel/go.mod
index 3f1d858e1..8ad312eda 100644
--- a/example/otel/go.mod
+++ b/example/otel/go.mod
@@ -1,6 +1,6 @@
 module github.com/redis/go-redis/example/otel
 
-go 1.19
+go 1.21
 
 replace github.com/redis/go-redis/v9 => ../..
 
@@ -12,7 +12,7 @@ require (
 	github.com/redis/go-redis/extra/redisotel/v9 v9.6.2
 	github.com/redis/go-redis/v9 v9.6.2
 	github.com/uptrace/uptrace-go v1.21.0
-	go.opentelemetry.io/otel v1.22.0
+	go.opentelemetry.io/otel v1.23.0
 )
 
 require (
@@ -29,10 +29,10 @@ require (
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
 	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect
-	go.opentelemetry.io/otel/metric v1.22.0 // indirect
-	go.opentelemetry.io/otel/sdk v1.22.0 // indirect
-	go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect
-	go.opentelemetry.io/otel/trace v1.22.0 // indirect
+	go.opentelemetry.io/otel/metric v1.23.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.23.0 // indirect
+	go.opentelemetry.io/otel/sdk/metric v1.23.0 // indirect
+	go.opentelemetry.io/otel/trace v1.23.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
 	golang.org/x/net v0.33.0 // indirect
 	golang.org/x/sys v0.28.0 // indirect
diff --git a/example/otel/go.sum b/example/otel/go.sum
index e85481dbe..a97748d06 100644
--- a/example/otel/go.sum
+++ b/example/otel/go.sum
@@ -1,10 +1,13 @@
 github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
+github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
+github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
 github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -17,16 +20,19 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/uptrace/uptrace-go v1.21.0 h1:oJoUjhiVT7aiuoG6B3ClVHtJozLn3cK9hQt8U5dQO1M=
 github.com/uptrace/uptrace-go v1.21.0/go.mod h1:/aXAFGKOqeAFBqWa1xtzLnGX2xJm1GScqz9NJ0TJjLM=
 go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1 h1:m9ReioVPIffxjJlGNRd0d5poy+9oTro3D+YbiEzUDOc=
 go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1/go.mod h1:CANkrsXNzqOKXfOomu2zhOmc1/J5UZK9SGjrat6ZCG0=
-go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
-go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
+go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
+go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
@@ -35,17 +41,18 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqhe
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec=
 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E=
-go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
-go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
-go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
-go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
-go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
-go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
-go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
-go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
+go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
+go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
+go.opentelemetry.io/otel/sdk v1.23.0 h1:0KM9Zl2esnl+WSukEmlaAEjVY5HDZANOHferLq36BPc=
+go.opentelemetry.io/otel/sdk v1.23.0/go.mod h1:wUscup7byToqyKJSilEtMf34FgdCAsFpFOjXnAwFfO0=
+go.opentelemetry.io/otel/sdk/metric v1.23.0 h1:u81lMvmK6GMgN4Fty7K7S6cSKOZhMKJMK2TB+KaTs0I=
+go.opentelemetry.io/otel/sdk/metric v1.23.0/go.mod h1:2LUOToN/FdX6wtfpHybOnCZjoZ6ViYajJYMiJ1LKDtQ=
+go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
+go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
 go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
 go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
 golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
 golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
@@ -66,3 +73,4 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
 google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
 google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

From 66180a487220e259a3cfee232dc03fa883695e20 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 4 Mar 2025 19:56:07 +0530
Subject: [PATCH 08/14] add go sum

---
 extra/redisotel/go.sum | 44 ++++++++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum
index 4551c2036..87a789e10 100644
--- a/extra/redisotel/go.sum
+++ b/extra/redisotel/go.sum
@@ -1,5 +1,7 @@
 github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
+github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
+github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -7,28 +9,40 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
-github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
-go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
-go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
-go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
-go.opentelemetry.io/otel/sdk v1.23.0 h1:0KM9Zl2esnl+WSukEmlaAEjVY5HDZANOHferLq36BPc=
-go.opentelemetry.io/otel/sdk v1.23.0/go.mod h1:wUscup7byToqyKJSilEtMf34FgdCAsFpFOjXnAwFfO0=
-go.opentelemetry.io/otel/sdk/metric v1.23.0 h1:u81lMvmK6GMgN4Fty7K7S6cSKOZhMKJMK2TB+KaTs0I=
-go.opentelemetry.io/otel/sdk/metric v1.23.0/go.mod h1:2LUOToN/FdX6wtfpHybOnCZjoZ6ViYajJYMiJ1LKDtQ=
-go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
-go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
-golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
-golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
+go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

From 2fd1c2eb78756ab7d4d875506f76b63002e511b7 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 4 Mar 2025 20:28:21 +0530
Subject: [PATCH 09/14] Revert go version

---
 extra/redisotel/go.mod | 13 ++++++-------
 extra/redisotel/go.sum | 33 +++++++++++----------------------
 2 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod
index 102a0569c..d65edca74 100644
--- a/extra/redisotel/go.mod
+++ b/extra/redisotel/go.mod
@@ -12,11 +12,12 @@ require (
 	github.com/redis/go-redis/extra/rediscmd/v9 v9.7.1
 	github.com/redis/go-redis/v9 v9.7.1
 	github.com/stretchr/testify v1.10.0
-	go.opentelemetry.io/otel v1.34.0
-	go.opentelemetry.io/otel/metric v1.34.0
-	go.opentelemetry.io/otel/sdk v1.34.0
-	go.opentelemetry.io/otel/sdk/metric v1.34.0
-	go.opentelemetry.io/otel/trace v1.34.0
+	go.opentelemetry.io/otel v1.22.0
+	go.opentelemetry.io/otel/metric v1.22.0
+	go.opentelemetry.io/otel/sdk v1.22.0
+	go.opentelemetry.io/otel/sdk/metric v1.22.0
+	go.opentelemetry.io/otel/trace v1.22.0
+
 )
 
 require (
@@ -25,9 +26,7 @@ require (
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
-	github.com/google/uuid v1.6.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
 	golang.org/x/sys v0.29.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum
index 87a789e10..06bfb4b8e 100644
--- a/extra/redisotel/go.sum
+++ b/extra/redisotel/go.sum
@@ -15,34 +15,23 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
-go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
-go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
-go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
-go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
-go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
-go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
-go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
-go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
-go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
+go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
+go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
+go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
+go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
+go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
+go.opentelemetry.io/otel/sdk/metric v1.22.0 h1:ARrRetm1HCVxq0cbnaZQlfwODYJHo3gFL8Z3tSmHBcI=
+go.opentelemetry.io/otel/sdk/metric v1.22.0/go.mod h1:KjQGeMIDlBNEOo6HvjhxIec1p/69/kULDcp4gr0oLQQ=
+go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
+go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
 golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
 golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

From 9182b7e934d53a6059a8261c299c81dc06e92724 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 4 Mar 2025 20:30:36 +0530
Subject: [PATCH 10/14] Revert go version

---
 extra/redisotel/go.mod | 4 +---
 extra/redisotel/go.sum | 3 ---
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod
index d65edca74..353a08a24 100644
--- a/extra/redisotel/go.mod
+++ b/extra/redisotel/go.mod
@@ -1,8 +1,6 @@
 module github.com/redis/go-redis/extra/redisotel/v9
 
-go 1.22.0
-
-toolchain go1.23.1
+go 1.19
 
 replace github.com/redis/go-redis/v9 => ../..
 
diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum
index 06bfb4b8e..21c863c34 100644
--- a/extra/redisotel/go.sum
+++ b/extra/redisotel/go.sum
@@ -1,7 +1,5 @@
 github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
-github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
-github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -14,7 +12,6 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=

From d7f27f5f911ffa18d3ea83d7d32b3844ae43d80f Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Tue, 4 Mar 2025 20:32:24 +0530
Subject: [PATCH 11/14] Revert example go version

---
 example/otel/go.mod |  6 +++---
 example/otel/go.sum | 16 ++++------------
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/example/otel/go.mod b/example/otel/go.mod
index a0f10d0b4..54a04dedd 100644
--- a/example/otel/go.mod
+++ b/example/otel/go.mod
@@ -1,6 +1,6 @@
 module github.com/redis/go-redis/example/otel
 
-go 1.21
+go 1.19
 
 replace github.com/redis/go-redis/v9 => ../..
 
@@ -19,7 +19,7 @@ require (
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
-	github.com/go-logr/logr v1.4.1 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
@@ -35,7 +35,7 @@ require (
 	go.opentelemetry.io/otel/trace v1.23.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
 	golang.org/x/net v0.33.0 // indirect
-	golang.org/x/sys v0.28.0 // indirect
+	golang.org/x/sys v0.29.0 // indirect
 	golang.org/x/text v0.21.0 // indirect
 	google.golang.org/genproto v0.0.0-20240108191215-35c7eff3a6b1 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect
diff --git a/example/otel/go.sum b/example/otel/go.sum
index 2868e7cf6..e8cba406c 100644
--- a/example/otel/go.sum
+++ b/example/otel/go.sum
@@ -1,18 +1,15 @@
 github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
-github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
-github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
 github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
-github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -20,13 +17,10 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/uptrace/uptrace-go v1.21.0 h1:oJoUjhiVT7aiuoG6B3ClVHtJozLn3cK9hQt8U5dQO1M=
 github.com/uptrace/uptrace-go v1.21.0/go.mod h1:/aXAFGKOqeAFBqWa1xtzLnGX2xJm1GScqz9NJ0TJjLM=
 go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1 h1:m9ReioVPIffxjJlGNRd0d5poy+9oTro3D+YbiEzUDOc=
@@ -52,11 +46,10 @@ go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5Ukgg
 go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
 go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
-go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
 golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
 golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -73,4 +66,3 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
 google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
 google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

From 01d8581f95c3b49780fd462d9eb9d77d876194c7 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Sat, 8 Mar 2025 01:13:25 +0530
Subject: [PATCH 12/14] Add custom attributes to tracing

---
 extra/redisotel/tracing.go      |  2 ++
 extra/redisotel/tracing_test.go | 17 ++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/extra/redisotel/tracing.go b/extra/redisotel/tracing.go
index 33b7abac1..76135f56d 100644
--- a/extra/redisotel/tracing.go
+++ b/extra/redisotel/tracing.go
@@ -116,6 +116,7 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 		}
 
 		opts := th.spanOpts
+		opts = append(opts, trace.WithAttributes(th.conf.attrsFunc(ctx)...))
 		opts = append(opts, trace.WithAttributes(attrs...))
 
 		ctx, span := th.conf.tracer.Start(ctx, cmd.FullName(), opts...)
@@ -149,6 +150,7 @@ func (th *tracingHook) ProcessPipelineHook(
 		}
 
 		opts := th.spanOpts
+		opts = append(opts, trace.WithAttributes(th.conf.attrsFunc(ctx)...))
 		opts = append(opts, trace.WithAttributes(attrs...))
 
 		ctx, span := th.conf.tracer.Start(ctx, "redis.pipeline "+summary, opts...)
diff --git a/extra/redisotel/tracing_test.go b/extra/redisotel/tracing_test.go
index bbe828144..75b714662 100644
--- a/extra/redisotel/tracing_test.go
+++ b/extra/redisotel/tracing_test.go
@@ -117,12 +117,23 @@ func TestTracingHook_DialHook(t *testing.T) {
 	}
 }
 
+func customAttrFn(ctx context.Context) []attribute.KeyValue {
+
+	attributes := make([]attribute.KeyValue, 0)
+
+	if method, ok := ctx.Value(semconv.RPCMethodKey).(string); ok {
+		attributes = append(attributes, semconv.RPCMethodKey.String(method))
+	}
+
+	return attributes
+}
 func TestTracingHook_ProcessHook(t *testing.T) {
 	imsb := tracetest.NewInMemoryExporter()
 	provider := sdktrace.NewTracerProvider(sdktrace.WithSyncer(imsb))
 	hook := newTracingHook(
 		"redis://localhost:6379",
 		WithTracerProvider(provider),
+		WithAttributesFunc(customAttrFn),
 	)
 
 	tests := []struct {
@@ -141,7 +152,9 @@ func TestTracingHook_ProcessHook(t *testing.T) {
 			processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error {
 				return tt.errTest
 			})
-			assertEqual(t, tt.errTest, processHook(context.Background(), cmd))
+
+			ctx := context.WithValue(context.Background(), semconv.RPCMethodKey, "ping")
+			assertEqual(t, tt.errTest, processHook(ctx, cmd))
 			assertEqual(t, 1, len(imsb.GetSpans()))
 
 			spanData := imsb.GetSpans()[0]
@@ -151,6 +164,8 @@ func TestTracingHook_ProcessHook(t *testing.T) {
 			assertAttributeContains(t, spanData.Attributes, semconv.DBSystemRedis)
 			assertAttributeContains(t, spanData.Attributes, semconv.DBConnectionStringKey.String("redis://localhost:6379"))
 			assertAttributeContains(t, spanData.Attributes, semconv.DBStatementKey.String("ping"))
+			// check for custom attribute
+			assertAttributeContains(t, spanData.Attributes, semconv.RPCMethodKey.String("ping"))
 
 			if tt.errTest == nil {
 				assertEqual(t, 0, len(spanData.Events))

From 140df6f105654133e9925be95d8b58ec9d0d19a3 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Sat, 8 Mar 2025 01:18:15 +0530
Subject: [PATCH 13/14] Update example

---
 example/otel/client.go | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/example/otel/client.go b/example/otel/client.go
index c216771b6..7ea5fa86c 100644
--- a/example/otel/client.go
+++ b/example/otel/client.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"log"
+	"strconv"
 	"sync"
 	"time"
 
@@ -11,6 +12,7 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
+	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
 
 	"github.com/redis/go-redis/extra/redisotel/v9"
 	"github.com/redis/go-redis/v9"
@@ -19,9 +21,14 @@ import (
 var tracer = otel.Tracer("github.com/redis/go-redis/example/otel")
 
 func customAttrFn(ctx context.Context) []attribute.KeyValue {
-	return []attribute.KeyValue{
-		attribute.String("custom_attr", "custom_value"),
+
+	attributes := make([]attribute.KeyValue, 0)
+
+	if method, ok := ctx.Value(semconv.RPCMethodKey).(string); ok {
+		attributes = append(attributes, semconv.RPCMethodKey.String(method))
 	}
+
+	return attributes
 }
 func main() {
 	ctx := context.Background()
@@ -48,7 +55,8 @@ func main() {
 
 	for i := 0; i < 1e6; i++ {
 		ctx, rootSpan := tracer.Start(ctx, "handleRequest")
-
+		ctx = context.WithValue(ctx, semconv.RPCMethodKey, "handleRequest "+ strconv.Itoa(i))
+		
 		if err := handleRequest(ctx, rdb); err != nil {
 			rootSpan.RecordError(err)
 			rootSpan.SetStatus(codes.Error, err.Error())

From 34b5f7e59408092bd3675410ef44e6ee1cd59087 Mon Sep 17 00:00:00 2001
From: Jatin Rungta <9137405+urdarinda@users.noreply.github.com>
Date: Thu, 13 Mar 2025 18:09:26 +0530
Subject: [PATCH 14/14] Preallocate slice length instead of append

---
 extra/redisotel/metrics.go | 12 ++++++++----
 extra/redisotel/tracing.go | 13 +++++++++----
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/extra/redisotel/metrics.go b/extra/redisotel/metrics.go
index 5ec5128e9..66a5da969 100644
--- a/extra/redisotel/metrics.go
+++ b/extra/redisotel/metrics.go
@@ -214,8 +214,10 @@ func (mh *metricsHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 
 		dur := time.Since(start)
 
-		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
-		attrs = append(attrs, mh.attrsFunc(ctx)...)
+		customAttrs := mh.attrsFunc(ctx)
+		
+		attrs := make([]attribute.KeyValue, 0, len(mh.attrs) + len(customAttrs) + 2)
+		attrs = append(attrs, customAttrs...)
 		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, attribute.String("type", "command"))
 		attrs = append(attrs, statusAttr(err))
@@ -236,8 +238,10 @@ func (mh *metricsHook) ProcessPipelineHook(
 
 		dur := time.Since(start)
 
-		attrs := make([]attribute.KeyValue, 0, len(mh.attrs)+2)
-		attrs = append(attrs, mh.attrsFunc(ctx)...)
+		customAttrs := mh.attrsFunc(ctx)
+
+		attrs := make([]attribute.KeyValue, 0, len(mh.attrs) + len(customAttrs) + 2)
+		attrs = append(attrs, customAttrs...)
 		attrs = append(attrs, mh.attrs...)
 		attrs = append(attrs, attribute.String("type", "pipeline"))
 		attrs = append(attrs, statusAttr(err))
diff --git a/extra/redisotel/tracing.go b/extra/redisotel/tracing.go
index 76135f56d..decfec3ee 100644
--- a/extra/redisotel/tracing.go
+++ b/extra/redisotel/tracing.go
@@ -103,7 +103,10 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 	return func(ctx context.Context, cmd redis.Cmder) error {
 		fn, file, line := funcFileLine("github.com/redis/go-redis")
 
-		attrs := make([]attribute.KeyValue, 0, 8)
+
+		customAttrs := th.conf.attrsFunc(ctx)
+
+		attrs := make([]attribute.KeyValue, 0, len(customAttrs) + 8)
 		attrs = append(attrs,
 			semconv.CodeFunction(fn),
 			semconv.CodeFilepath(file),
@@ -116,7 +119,7 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
 		}
 
 		opts := th.spanOpts
-		opts = append(opts, trace.WithAttributes(th.conf.attrsFunc(ctx)...))
+		opts = append(opts, trace.WithAttributes(customAttrs...))
 		opts = append(opts, trace.WithAttributes(attrs...))
 
 		ctx, span := th.conf.tracer.Start(ctx, cmd.FullName(), opts...)
@@ -136,7 +139,9 @@ func (th *tracingHook) ProcessPipelineHook(
 	return func(ctx context.Context, cmds []redis.Cmder) error {
 		fn, file, line := funcFileLine("github.com/redis/go-redis")
 
-		attrs := make([]attribute.KeyValue, 0, 8)
+		customAttrs := th.conf.attrsFunc(ctx)
+		
+		attrs := make([]attribute.KeyValue, 0, len(customAttrs) + 8)
 		attrs = append(attrs,
 			semconv.CodeFunction(fn),
 			semconv.CodeFilepath(file),
@@ -150,7 +155,7 @@ func (th *tracingHook) ProcessPipelineHook(
 		}
 
 		opts := th.spanOpts
-		opts = append(opts, trace.WithAttributes(th.conf.attrsFunc(ctx)...))
+		opts = append(opts, trace.WithAttributes(customAttrs...))
 		opts = append(opts, trace.WithAttributes(attrs...))
 
 		ctx, span := th.conf.tracer.Start(ctx, "redis.pipeline "+summary, opts...)