Skip to content

Commit 731258f

Browse files
committed
Update redisotel to use semconv and add operation
1 parent e63669e commit 731258f

File tree

5 files changed

+78
-78
lines changed

5 files changed

+78
-78
lines changed

extra/redisotel/go.mod

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module github.com/redis/go-redis/extra/redisotel/v9
22

3-
go 1.19
3+
go 1.22
4+
5+
toolchain go1.23.1
46

57
replace github.com/redis/go-redis/v9 => ../..
68

@@ -9,20 +11,19 @@ replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd
911
require (
1012
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.2
1113
github.com/redis/go-redis/v9 v9.6.2
12-
go.opentelemetry.io/otel v1.22.0
13-
go.opentelemetry.io/otel/metric v1.22.0
14-
go.opentelemetry.io/otel/sdk v1.22.0
15-
go.opentelemetry.io/otel/trace v1.22.0
14+
go.opentelemetry.io/otel v1.32.0
15+
go.opentelemetry.io/otel/metric v1.32.0
16+
go.opentelemetry.io/otel/sdk v1.32.0
17+
go.opentelemetry.io/otel/trace v1.32.0
1618
)
1719

1820
require (
1921
github.com/cespare/xxhash/v2 v2.2.0 // indirect
2022
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
21-
github.com/go-logr/logr v1.4.1 // indirect
23+
github.com/go-logr/logr v1.4.2 // indirect
2224
github.com/go-logr/stdr v1.2.2 // indirect
23-
golang.org/x/sys v0.16.0 // indirect
25+
github.com/google/uuid v1.6.0 // indirect
26+
golang.org/x/sys v0.27.0 // indirect
2427
)
2528

26-
retract (
27-
v9.5.3 // This version was accidentally released.
28-
)
29+
retract v9.5.3 // This version was accidentally released.

extra/redisotel/go.sum

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
2+
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
23
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
4+
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
35
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
46
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
57
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
69
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
710
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
811
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
9-
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
10-
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
12+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
13+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
1114
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
1215
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
1316
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
17+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
18+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
19+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
1420
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
15-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
16-
go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
17-
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
18-
go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
19-
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
20-
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
21-
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
22-
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
23-
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
24-
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
25-
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
21+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
22+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
23+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
24+
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
25+
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
26+
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
27+
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
28+
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
29+
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
30+
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
31+
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
32+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
33+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2634
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
35+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

extra/redisotel/metrics.go

+33-28
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"go.opentelemetry.io/otel"
1010
"go.opentelemetry.io/otel/attribute"
1111
"go.opentelemetry.io/otel/metric"
12+
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
1213

1314
"github.com/redis/go-redis/v9"
1415
)
@@ -36,8 +37,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error {
3637
opt := rdb.Options()
3738
conf.poolName = opt.Addr
3839
}
39-
conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName))
40-
40+
conf.attrs = append(conf.attrs,semconv.DBClientConnectionPoolName(conf.poolName))
4141
if err := reportPoolStats(rdb, conf); err != nil {
4242
return err
4343
}
@@ -51,7 +51,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error {
5151
opt := rdb.Options()
5252
conf.poolName = opt.Addr
5353
}
54-
conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName))
54+
conf.attrs = append(conf.attrs, semconv.DBClientConnectionPoolName(conf.poolName))
5555

5656
if err := reportPoolStats(rdb, conf); err != nil {
5757
otel.Handle(err)
@@ -67,7 +67,7 @@ func InstrumentMetrics(rdb redis.UniversalClient, opts ...MetricsOption) error {
6767
opt := rdb.Options()
6868
conf.poolName = opt.Addr
6969
}
70-
conf.attrs = append(conf.attrs, attribute.String("pool.name", conf.poolName))
70+
conf.attrs = append(conf.attrs, semconv.DBClientConnectionPoolName(conf.poolName))
7171

7272
if err := reportPoolStats(rdb, conf); err != nil {
7373
otel.Handle(err)
@@ -88,40 +88,45 @@ func reportPoolStats(rdb *redis.Client, conf *config) error {
8888
usedAttrs := append(labels, attribute.String("state", "used"))
8989

9090
idleMax, err := conf.meter.Int64ObservableUpDownCounter(
91-
"db.client.connections.idle.max",
92-
metric.WithDescription("The maximum number of idle open connections allowed"),
91+
semconv.DBClientConnectionIdleMaxName,
92+
metric.WithDescription(semconv.DBClientConnectionIdleMaxDescription),
93+
metric.WithUnit(semconv.DBClientConnectionIdleMaxUnit),
9394
)
9495
if err != nil {
9596
return err
9697
}
9798

9899
idleMin, err := conf.meter.Int64ObservableUpDownCounter(
99-
"db.client.connections.idle.min",
100-
metric.WithDescription("The minimum number of idle open connections allowed"),
100+
semconv.DBClientConnectionIdleMinName,
101+
metric.WithDescription(semconv.DBClientConnectionIdleMinDescription),
102+
metric.WithUnit(semconv.DBClientConnectionIdleMinUnit),
101103
)
102104
if err != nil {
103105
return err
104106
}
105107

106108
connsMax, err := conf.meter.Int64ObservableUpDownCounter(
107-
"db.client.connections.max",
108-
metric.WithDescription("The maximum number of open connections allowed"),
109+
semconv.DBClientConnectionMaxName,
110+
metric.WithDescription(semconv.DBClientConnectionMaxDescription),
111+
metric.WithUnit(semconv.DBClientConnectionMaxUnit),
109112
)
110113
if err != nil {
111114
return err
112115
}
113116

114117
usage, err := conf.meter.Int64ObservableUpDownCounter(
115-
"db.client.connections.usage",
116-
metric.WithDescription("The number of connections that are currently in state described by the state attribute"),
118+
semconv.DBClientConnectionCountName,
119+
metric.WithDescription(semconv.DBClientConnectionCountDescription),
120+
metric.WithUnit(semconv.DBClientConnectionCountUnit),
117121
)
118122
if err != nil {
119123
return err
120124
}
121125

122126
timeouts, err := conf.meter.Int64ObservableUpDownCounter(
123-
"db.client.connections.timeouts",
124-
metric.WithDescription("The number of connection timeouts that have occurred trying to obtain a connection from the pool"),
127+
semconv.DBClientConnectionTimeoutsName,
128+
metric.WithDescription(semconv.DBClientConnectionTimeoutsDescription),
129+
metric.WithUnit(semconv.DBClientConnectionTimeoutsUnit),
125130
)
126131
if err != nil {
127132
return err
@@ -154,18 +159,18 @@ func reportPoolStats(rdb *redis.Client, conf *config) error {
154159

155160
func addMetricsHook(rdb *redis.Client, conf *config) error {
156161
createTime, err := conf.meter.Float64Histogram(
157-
"db.client.connections.create_time",
158-
metric.WithDescription("The time it took to create a new connection."),
159-
metric.WithUnit("ms"),
162+
semconv.DBClientConnectionCreateTimeName,
163+
metric.WithDescription(semconv.DBClientConnectionCreateTimeDescription),
164+
metric.WithUnit(semconv.DBClientConnectionCreateTimeUnit),
160165
)
161166
if err != nil {
162167
return err
163168
}
164169

165170
useTime, err := conf.meter.Float64Histogram(
166-
"db.client.connections.use_time",
167-
metric.WithDescription("The time between borrowing a connection and returning it to the pool."),
168-
metric.WithUnit("ms"),
171+
semconv.DBClientConnectionUseTimeName,
172+
metric.WithDescription(semconv.DBClientConnectionUseTimeDescription),
173+
metric.WithUnit(semconv.DBClientConnectionUseTimeUnit),
169174
)
170175
if err != nil {
171176
return err
@@ -199,7 +204,7 @@ func (mh *metricsHook) DialHook(hook redis.DialHook) redis.DialHook {
199204
attrs = append(attrs, mh.attrs...)
200205
attrs = append(attrs, statusAttr(err))
201206

202-
mh.createTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...))
207+
mh.createTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...))
203208
return conn, err
204209
}
205210
}
@@ -216,8 +221,8 @@ func (mh *metricsHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
216221
attrs = append(attrs, mh.attrs...)
217222
attrs = append(attrs, attribute.String("type", "command"))
218223
attrs = append(attrs, statusAttr(err))
219-
220-
mh.useTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...))
224+
attrs = append(attrs, semconv.DBOperationName(cmd.FullName()))
225+
mh.useTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...))
221226

222227
return err
223228
}
@@ -237,17 +242,17 @@ func (mh *metricsHook) ProcessPipelineHook(
237242
attrs = append(attrs, mh.attrs...)
238243
attrs = append(attrs, attribute.String("type", "pipeline"))
239244
attrs = append(attrs, statusAttr(err))
245+
if len(cmds) > 0 {
246+
attrs = append(attrs, semconv.DBOperationName(cmds[0].FullName()))
247+
attrs = append(attrs, semconv.DBOperationBatchSize(len(cmds)))
248+
}
240249

241-
mh.useTime.Record(ctx, milliseconds(dur), metric.WithAttributes(attrs...))
250+
mh.useTime.Record(ctx, dur.Seconds(), metric.WithAttributes(attrs...))
242251

243252
return err
244253
}
245254
}
246255

247-
func milliseconds(d time.Duration) float64 {
248-
return float64(d) / float64(time.Millisecond)
249-
}
250-
251256
func statusAttr(err error) attribute.KeyValue {
252257
if err != nil {
253258
return attribute.String("status", "error")

extra/redisotel/redisotel_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"testing"
66

7-
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
7+
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
88

99
"go.opentelemetry.io/otel"
1010
sdktrace "go.opentelemetry.io/otel/sdk/trace"
@@ -27,7 +27,7 @@ func TestNewWithTracerProvider(t *testing.T) {
2727
return otel.GetTracerProvider()
2828
})
2929

30-
_ = newTracingHook("redis-hook", WithTracerProvider(tp.TracerProvider("redis-test")))
30+
_ = newTracingHook(WithTracerProvider(tp.TracerProvider("redis-test")))
3131

3232
if !invoked {
3333
t.Fatalf("did not call custom TraceProvider")
@@ -37,7 +37,6 @@ func TestNewWithTracerProvider(t *testing.T) {
3737
func TestWithDBStatement(t *testing.T) {
3838
provider := sdktrace.NewTracerProvider()
3939
hook := newTracingHook(
40-
"",
4140
WithTracerProvider(provider),
4241
WithDBStatement(false),
4342
)
@@ -48,7 +47,7 @@ func TestWithDBStatement(t *testing.T) {
4847
processHook := hook.ProcessHook(func(ctx context.Context, cmd redis.Cmder) error {
4948
attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes()
5049
for _, attr := range attrs {
51-
if attr.Key == semconv.DBStatementKey {
50+
if attr.Key == semconv.DBQueryTextKey {
5251
t.Fatal("Attribute with db statement should not exist")
5352
}
5453
}

extra/redisotel/tracing.go

+9-23
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
"go.opentelemetry.io/otel/attribute"
1212
"go.opentelemetry.io/otel/codes"
13-
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
13+
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
1414
"go.opentelemetry.io/otel/trace"
1515

1616
"github.com/redis/go-redis/extra/rediscmd/v9"
@@ -25,28 +25,25 @@ func InstrumentTracing(rdb redis.UniversalClient, opts ...TracingOption) error {
2525
switch rdb := rdb.(type) {
2626
case *redis.Client:
2727
opt := rdb.Options()
28-
connString := formatDBConnString(opt.Network, opt.Addr)
2928
opts = addServerAttributes(opts, opt.Addr)
30-
rdb.AddHook(newTracingHook(connString, opts...))
29+
rdb.AddHook(newTracingHook(opts...))
3130
return nil
3231
case *redis.ClusterClient:
33-
rdb.AddHook(newTracingHook("", opts...))
32+
rdb.AddHook(newTracingHook(opts...))
3433

3534
rdb.OnNewNode(func(rdb *redis.Client) {
3635
opt := rdb.Options()
3736
opts = addServerAttributes(opts, opt.Addr)
38-
connString := formatDBConnString(opt.Network, opt.Addr)
39-
rdb.AddHook(newTracingHook(connString, opts...))
37+
rdb.AddHook(newTracingHook(opts...))
4038
})
4139
return nil
4240
case *redis.Ring:
43-
rdb.AddHook(newTracingHook("", opts...))
41+
rdb.AddHook(newTracingHook(opts...))
4442

4543
rdb.OnNewNode(func(rdb *redis.Client) {
4644
opt := rdb.Options()
4745
opts = addServerAttributes(opts, opt.Addr)
48-
connString := formatDBConnString(opt.Network, opt.Addr)
49-
rdb.AddHook(newTracingHook(connString, opts...))
46+
rdb.AddHook(newTracingHook(opts...))
5047
})
5148
return nil
5249
default:
@@ -62,7 +59,7 @@ type tracingHook struct {
6259

6360
var _ redis.Hook = (*tracingHook)(nil)
6461

65-
func newTracingHook(connString string, opts ...TracingOption) *tracingHook {
62+
func newTracingHook(opts ...TracingOption) *tracingHook {
6663
baseOpts := make([]baseOption, len(opts))
6764
for i, opt := range opts {
6865
baseOpts[i] = opt
@@ -75,10 +72,6 @@ func newTracingHook(connString string, opts ...TracingOption) *tracingHook {
7572
trace.WithInstrumentationVersion("semver:"+redis.Version()),
7673
)
7774
}
78-
if connString != "" {
79-
conf.attrs = append(conf.attrs, semconv.DBConnectionString(connString))
80-
}
81-
8275
return &tracingHook{
8376
conf: conf,
8477

@@ -116,7 +109,7 @@ func (th *tracingHook) ProcessHook(hook redis.ProcessHook) redis.ProcessHook {
116109

117110
if th.conf.dbStmtEnabled {
118111
cmdString := rediscmd.CmdString(cmd)
119-
attrs = append(attrs, semconv.DBStatement(cmdString))
112+
attrs = append(attrs, semconv.DBQueryText(cmdString))
120113
}
121114

122115
opts := th.spanOpts
@@ -149,7 +142,7 @@ func (th *tracingHook) ProcessPipelineHook(
149142

150143
summary, cmdsString := rediscmd.CmdsString(cmds)
151144
if th.conf.dbStmtEnabled {
152-
attrs = append(attrs, semconv.DBStatement(cmdsString))
145+
attrs = append(attrs, semconv.DBQueryText(cmdsString))
153146
}
154147

155148
opts := th.spanOpts
@@ -173,13 +166,6 @@ func recordError(span trace.Span, err error) {
173166
}
174167
}
175168

176-
func formatDBConnString(network, addr string) string {
177-
if network == "tcp" {
178-
network = "redis"
179-
}
180-
return fmt.Sprintf("%s://%s", network, addr)
181-
}
182-
183169
func funcFileLine(pkg string) (string, string, int) {
184170
const depth = 16
185171
var pcs [depth]uintptr

0 commit comments

Comments
 (0)