diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index b2e30b394..139e07a68 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -1,6 +1,8 @@ module github.com/redis/go-redis/extra/redisotel/v9 -go 1.19 +go 1.22 + +toolchain go1.23.1 replace github.com/redis/go-redis/v9 => ../.. @@ -9,20 +11,19 @@ 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 + go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel/metric v1.32.0 + go.opentelemetry.io/otel/sdk v1.32.0 + go.opentelemetry.io/otel/trace v1.32.0 ) require ( github.com/cespare/xxhash/v2 v2.2.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 - golang.org/x/sys v0.16.0 // indirect + github.com/google/uuid v1.6.0 // indirect + golang.org/x/sys v0.27.0 // 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..790c9c6a4 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -1,26 +1,35 @@ 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.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= -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/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= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.go b/extra/redisotel/metrics.go index 915838f34..87adc0f89 100644 --- a/extra/redisotel/metrics.go +++ b/extra/redisotel/metrics.go @@ -9,6 +9,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" + semconv "go.opentelemetry.io/otel/semconv/v1.27.0" "github.com/redis/go-redis/v9" ) @@ -36,8 +37,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error { opt := rdb.Options() conf.poolName = opt.Addr } - conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName)) - + conf.attrs = append(conf.attrs,semconv.DBClientConnectionPoolName(conf.poolName)) if err := reportPoolStats(rdb, conf); err != nil { return err } @@ -51,7 +51,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error { opt := rdb.Options() conf.poolName = opt.Addr } - conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName)) + conf.attrs = append(conf.attrs, semconv.DBClientConnectionPoolName(conf.poolName)) if err := reportPoolStats(rdb, conf); err != nil { otel.Handle(err) @@ -67,7 +67,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error { opt := rdb.Options() conf.poolName = opt.Addr } - conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName)) + conf.attrs = append(conf.attrs, semconv.DBClientConnectionPoolName(conf.poolName)) if err := reportPoolStats(rdb, conf); err != nil { otel.Handle(err) @@ -88,40 +88,45 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { usedAttrs := append(labels, attribute.String("state", "used")) idleMax, err := conf.meter.Int64ObservableUpDownCounter( - "db.client.connections.idle.max", - metric.WithDescription("The maximum number of idle open connections allowed"), + semconv.DBClientConnectionIdleMaxName, + metric.WithDescription(semconv.DBClientConnectionIdleMaxDescription), + metric.WithUnit(semconv.DBClientConnectionIdleMaxUnit), ) if err != nil { return err } idleMin, err := conf.meter.Int64ObservableUpDownCounter( - "db.client.connections.idle.min", - metric.WithDescription("The minimum number of idle open connections allowed"), + semconv.DBClientConnectionIdleMinName, + metric.WithDescription(semconv.DBClientConnectionIdleMinDescription), + metric.WithUnit(semconv.DBClientConnectionIdleMinUnit), ) if err != nil { return err } connsMax, err := conf.meter.Int64ObservableUpDownCounter( - "db.client.connections.max", - metric.WithDescription("The maximum number of open connections allowed"), + semconv.DBClientConnectionMaxName, + metric.WithDescription(semconv.DBClientConnectionMaxDescription), + metric.WithUnit(semconv.DBClientConnectionMaxUnit), ) if err != nil { return err } usage, err := conf.meter.Int64ObservableUpDownCounter( - "db.client.connections.usage", - metric.WithDescription("The number of connections that are currently in state described by the state attribute"), + semconv.DBClientConnectionCountName, + metric.WithDescription(semconv.DBClientConnectionCountDescription), + metric.WithUnit(semconv.DBClientConnectionCountUnit), ) if err != nil { return err } timeouts, err := conf.meter.Int64ObservableUpDownCounter( - "db.client.connections.timeouts", - metric.WithDescription("The number of connection timeouts that have occurred trying to obtain a connection from the pool"), + semconv.DBClientConnectionTimeoutsName, + metric.WithDescription(semconv.DBClientConnectionTimeoutsDescription), + metric.WithUnit(semconv.DBClientConnectionTimeoutsUnit), ) if err != nil { return err @@ -154,18 +159,18 @@ func reportPoolStats(rdb *redis.Client, conf *config) error { func addMetricsHook(rdb *redis.Client, conf *config) error { createTime, err := conf.meter.Float64Histogram( - "db.client.connections.create_time", - metric.WithDescription("The time it took to create a new connection."), - metric.WithUnit("ms"), + semconv.DBClientConnectionCreateTimeName, + metric.WithDescription(semconv.DBClientConnectionCreateTimeDescription), + metric.WithUnit(semconv.DBClientConnectionCreateTimeUnit), ) if err != nil { return err } useTime, err := conf.meter.Float64Histogram( - "db.client.connections.use_time", - metric.WithDescription("The time between borrowing a connection and returning it to the pool."), - metric.WithUnit("ms"), + semconv.DBClientConnectionUseTimeName, + metric.WithDescription(semconv.DBClientConnectionUseTimeDescription), + metric.WithUnit(semconv.DBClientConnectionUseTimeUnit), ) if err != nil { return err @@ -199,7 +204,7 @@ func (mh *metricsHook) DialHook(hook redis.DialHook) redis.DialHook { attrs = append(attrs, mh.attrs...) attrs = append(attrs, statusAttr(err)) - mh.createTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...)) + mh.createTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...)) return conn, err } } @@ -216,8 +221,8 @@ func (mh *metricsHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook { attrs = append(attrs, mh.attrs...) attrs = append(attrs, attribute.String("type", "command")) attrs = append(attrs, statusAttr(err)) - - mh.useTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...)) + attrs = append(attrs, semconv.DBOperationName(cmd.FullName())) + mh.useTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...)) return err } @@ -237,17 +242,17 @@ func (mh *metricsHook) ProcessPipelineHook( attrs = append(attrs, mh.attrs...) attrs = append(attrs, attribute.String("type", "pipeline")) attrs = append(attrs, statusAttr(err)) + if len(cmds) > 0 { + attrs = append(attrs, semconv.DBOperationName(cmds[0].FullName())) + attrs = append(attrs, semconv.DBOperationBatchSize(len(cmds))) + } - mh.useTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...)) + mh.useTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...)) return err } } -func milliseconds(d time.Duration) float64 { - return float64(d) / float64(time.Millisecond) -} - func statusAttr(err error) attribute.KeyValue { if err != nil { return attribute.String("status", "error") diff --git a/extra/redisotel/redisotel_test.go b/extra/redisotel/redisotel_test.go index b1ad5ca43..4214f1493 100644 --- a/extra/redisotel/redisotel_test.go +++ b/extra/redisotel/redisotel_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + semconv "go.opentelemetry.io/otel/semconv/v1.27.0" "go.opentelemetry.io/otel" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -27,7 +27,7 @@ func TestNewWithTracerProvider(t *testing.T) { return otel.GetTracerProvider() }) - _ = newTracingHook("redis-hook", WithTracerProvider(tp.TracerProvider("redis-test"))) + _ = newTracingHook(WithTracerProvider(tp.TracerProvider("redis-test"))) if !invoked { t.Fatalf("did not call custom TraceProvider") @@ -37,7 +37,6 @@ func TestNewWithTracerProvider(t *testing.T) { func TestWithDBStatement(t *testing.T) { provider := sdktrace.NewTracerProvider() hook := newTracingHook( - "", WithTracerProvider(provider), WithDBStatement(false), ) @@ -48,7 +47,7 @@ func TestWithDBStatement(t *testing.T) { processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error { attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes() for _, attr := range attrs { - if attr.Key == semconv.DBStatementKey { + if attr.Key == semconv.DBQueryTextKey { t.Fatal("Attribute with db statement should not exist") } } diff --git a/extra/redisotel/tracing.go b/extra/redisotel/tracing.go index 3d5f3426c..abca9d94b 100644 --- a/extra/redisotel/tracing.go +++ b/extra/redisotel/tracing.go @@ -10,7 +10,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.24.0" + semconv "go.opentelemetry.io/otel/semconv/v1.27.0" "go.opentelemetry.io/otel/trace" "github.com/redis/go-redis/extra/rediscmd/v9" @@ -25,28 +25,25 @@ func InstrumentTracing(rdb redis.UniversalClient, opts ...TracingOption) error { switch rdb := rdb.(type) { case *redis.Client: opt := rdb.Options() - connString := formatDBConnString(opt.Network, opt.Addr) opts = addServerAttributes(opts, opt.Addr) - rdb.AddHook(newTracingHook(connString, opts...)) + rdb.AddHook(newTracingHook(opts...)) return nil case *redis.ClusterClient: - rdb.AddHook(newTracingHook("", opts...)) + rdb.AddHook(newTracingHook(opts...)) rdb.OnNewNode(func(rdb *redis.Client) { opt := rdb.Options() opts = addServerAttributes(opts, opt.Addr) - connString := formatDBConnString(opt.Network, opt.Addr) - rdb.AddHook(newTracingHook(connString, opts...)) + rdb.AddHook(newTracingHook(opts...)) }) return nil case *redis.Ring: - rdb.AddHook(newTracingHook("", opts...)) + rdb.AddHook(newTracingHook(opts...)) rdb.OnNewNode(func(rdb *redis.Client) { opt := rdb.Options() opts = addServerAttributes(opts, opt.Addr) - connString := formatDBConnString(opt.Network, opt.Addr) - rdb.AddHook(newTracingHook(connString, opts...)) + rdb.AddHook(newTracingHook(opts...)) }) return nil default: @@ -62,7 +59,7 @@ type tracingHook struct { var _ redis.Hook = (*tracingHook)(nil) -func newTracingHook(connString string, opts ...TracingOption) *tracingHook { +func newTracingHook(opts ...TracingOption) *tracingHook { baseOpts := make([]baseOption, len(opts)) for i, opt := range opts { baseOpts[i] = opt @@ -75,10 +72,6 @@ func newTracingHook(connString string, opts ...TracingOption) *tracingHook { trace.WithInstrumentationVersion("semver:"+redis.Version()), ) } - if connString != "" { - conf.attrs = append(conf.attrs, semconv.DBConnectionString(connString)) - } - return &tracingHook{ conf: conf, @@ -116,7 +109,7 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook { if th.conf.dbStmtEnabled { cmdString := rediscmd.CmdString(cmd) - attrs = append(attrs, semconv.DBStatement(cmdString)) + attrs = append(attrs, semconv.DBQueryText(cmdString)) } opts := th.spanOpts @@ -149,7 +142,7 @@ func (th *tracingHook) ProcessPipelineHook( summary, cmdsString := rediscmd.CmdsString(cmds) if th.conf.dbStmtEnabled { - attrs = append(attrs, semconv.DBStatement(cmdsString)) + attrs = append(attrs, semconv.DBQueryText(cmdsString)) } opts := th.spanOpts @@ -173,13 +166,6 @@ func recordError(span trace.Span, err error) { } } -func formatDBConnString(network, addr string) string { - if network == "tcp" { - network = "redis" - } - return fmt.Sprintf("%s://%s", network, addr) -} - func funcFileLine(pkg string) (string, string, int) { const depth = 16 var pcs [depth]uintptr