@@ -61,6 +61,30 @@ func WithDBStatement(f StatementFunc) Option {
61
61
// StatementFunc is a the function that maps a command's tokens to a string to put in the db.statement attribute
62
62
type StatementFunc func (cmdTokens []string ) string
63
63
64
+ type commandMetrics struct {
65
+ duration metric.Float64Histogram
66
+ errors metric.Int64Counter
67
+ addOpts []metric.AddOption
68
+ recordOpts []metric.RecordOption
69
+ }
70
+
71
+ func (c commandMetrics ) recordDuration (ctx context.Context , op string ) func () {
72
+ now := time .Now ()
73
+ return func () {
74
+ opts := append (c .recordOpts , metric .WithAttributes (attribute .String ("operation" , op )))
75
+ c .duration .Record (ctx , time .Since (now ).Seconds (), opts ... )
76
+ }
77
+ }
78
+
79
+ func (c commandMetrics ) recordError (ctx context.Context , op string , err error ) {
80
+ opts := append (c .addOpts , metric .WithAttributes (attribute .String ("operation" , op )))
81
+ if err != nil && ! rueidis .IsRedisNil (err ) {
82
+ c .errors .Add (ctx , 1 , opts ... )
83
+ } else {
84
+ c .errors .Add (ctx , 0 , opts ... )
85
+ }
86
+ }
87
+
64
88
type otelclient struct {
65
89
client rueidis.Client
66
90
meterProvider metric.MeterProvider
@@ -74,50 +98,66 @@ type otelclient struct {
74
98
addOpts []metric.AddOption
75
99
recordOpts []metric.RecordOption
76
100
histogramOption HistogramOption
101
+ * commandMetrics
77
102
}
78
103
79
104
func (o * otelclient ) B () rueidis.Builder {
80
105
return o .client .B ()
81
106
}
82
107
83
108
func (o * otelclient ) Do (ctx context.Context , cmd rueidis.Completed ) (resp rueidis.RedisResult ) {
84
- ctx , span := o .start (ctx , first (cmd .Commands ()), sum (cmd .Commands ()))
109
+ op := first (cmd .Commands ())
110
+ defer o .recordDuration (ctx , op )()
111
+ ctx , span := o .start (ctx , op , sum (cmd .Commands ()))
85
112
if o .dbStmtFunc != nil {
86
113
span .SetAttributes (dbstmt .String (o .dbStmtFunc (cmd .Commands ())))
87
114
}
88
115
89
116
resp = o .client .Do (ctx , cmd )
90
117
o .end (span , resp .Error ())
118
+ o .recordError (ctx , op , resp .Error ())
91
119
return
92
120
}
93
121
94
122
func (o * otelclient ) DoMulti (ctx context.Context , multi ... rueidis.Completed ) (resp []rueidis.RedisResult ) {
95
- ctx , span := o .start (ctx , multiFirst (multi ), multiSum (multi ))
123
+ op := multiFirst (multi )
124
+ defer o .recordDuration (ctx , op )()
125
+ ctx , span := o .start (ctx , op , multiSum (multi ))
96
126
resp = o .client .DoMulti (ctx , multi ... )
97
- o .end (span , firstError (resp ))
127
+ err := firstError (resp )
128
+ o .end (span , err )
129
+ o .recordError (ctx , op , err )
98
130
return
99
131
}
100
132
101
133
func (o * otelclient ) DoStream (ctx context.Context , cmd rueidis.Completed ) (resp rueidis.RedisResultStream ) {
102
- ctx , span := o .start (ctx , first (cmd .Commands ()), sum (cmd .Commands ()))
134
+ op := first (cmd .Commands ())
135
+ defer o .recordDuration (ctx , op )()
136
+ ctx , span := o .start (ctx , op , sum (cmd .Commands ()))
103
137
if o .dbStmtFunc != nil {
104
138
span .SetAttributes (dbstmt .String (o .dbStmtFunc (cmd .Commands ())))
105
139
}
106
140
107
141
resp = o .client .DoStream (ctx , cmd )
108
142
o .end (span , resp .Error ())
143
+ o .recordError (ctx , op , resp .Error ())
109
144
return
110
145
}
111
146
112
147
func (o * otelclient ) DoMultiStream (ctx context.Context , multi ... rueidis.Completed ) (resp rueidis.MultiRedisResultStream ) {
113
- ctx , span := o .start (ctx , multiFirst (multi ), multiSum (multi ))
148
+ op := multiFirst (multi )
149
+ defer o .recordDuration (ctx , op )()
150
+ ctx , span := o .start (ctx , op , multiSum (multi ))
114
151
resp = o .client .DoMultiStream (ctx , multi ... )
115
152
o .end (span , resp .Error ())
153
+ o .recordError (ctx , op , resp .Error ())
116
154
return
117
155
}
118
156
119
157
func (o * otelclient ) DoCache (ctx context.Context , cmd rueidis.Cacheable , ttl time.Duration ) (resp rueidis.RedisResult ) {
120
- ctx , span := o .start (ctx , first (cmd .Commands ()), sum (cmd .Commands ()))
158
+ op := first (cmd .Commands ())
159
+ defer o .recordDuration (ctx , op )()
160
+ ctx , span := o .start (ctx , op , sum (cmd .Commands ()))
121
161
if o .dbStmtFunc != nil {
122
162
span .SetAttributes (dbstmt .String (o .dbStmtFunc (cmd .Commands ())))
123
163
}
@@ -131,11 +171,14 @@ func (o *otelclient) DoCache(ctx context.Context, cmd rueidis.Cacheable, ttl tim
131
171
}
132
172
}
133
173
o .end (span , resp .Error ())
174
+ o .recordError (ctx , op , resp .Error ())
134
175
return
135
176
}
136
177
137
178
func (o * otelclient ) DoMultiCache (ctx context.Context , multi ... rueidis.CacheableTTL ) (resps []rueidis.RedisResult ) {
138
- ctx , span := o .start (ctx , multiCacheableFirst (multi ), multiCacheableSum (multi ))
179
+ op := multiCacheableFirst (multi )
180
+ defer o .recordDuration (ctx , op )()
181
+ ctx , span := o .start (ctx , op , multiCacheableSum (multi ))
139
182
resps = o .client .DoMultiCache (ctx , multi ... )
140
183
for _ , resp := range resps {
141
184
if resp .NonRedisError () == nil {
@@ -146,28 +189,32 @@ func (o *otelclient) DoMultiCache(ctx context.Context, multi ...rueidis.Cacheabl
146
189
}
147
190
}
148
191
}
149
- o .end (span , firstError (resps ))
192
+ err := firstError (resps )
193
+ o .end (span , err )
194
+ o .recordError (ctx , op , err )
150
195
return
151
196
}
152
197
153
198
func (o * otelclient ) Dedicated (fn func (rueidis.DedicatedClient ) error ) (err error ) {
154
199
return o .client .Dedicated (func (client rueidis.DedicatedClient ) error {
155
200
return fn (& dedicated {
156
- client : client ,
157
- tAttrs : o .tAttrs ,
158
- tracer : o .tracer ,
159
- dbStmtFunc : o .dbStmtFunc ,
201
+ client : client ,
202
+ tAttrs : o .tAttrs ,
203
+ tracer : o .tracer ,
204
+ dbStmtFunc : o .dbStmtFunc ,
205
+ commandMetrics : o .commandMetrics ,
160
206
})
161
207
})
162
208
}
163
209
164
210
func (o * otelclient ) Dedicate () (rueidis.DedicatedClient , func ()) {
165
211
client , cancel := o .client .Dedicate ()
166
212
return & dedicated {
167
- client : client ,
168
- tAttrs : o .tAttrs ,
169
- tracer : o .tracer ,
170
- dbStmtFunc : o .dbStmtFunc ,
213
+ client : client ,
214
+ tAttrs : o .tAttrs ,
215
+ tracer : o .tracer ,
216
+ dbStmtFunc : o .dbStmtFunc ,
217
+ commandMetrics : o .commandMetrics ,
171
218
}, cancel
172
219
}
173
220
@@ -198,6 +245,7 @@ func (o *otelclient) Nodes() map[string]rueidis.Client {
198
245
tAttrs : o .tAttrs ,
199
246
histogramOption : o .histogramOption ,
200
247
dbStmtFunc : o .dbStmtFunc ,
248
+ commandMetrics : o .commandMetrics ,
201
249
}
202
250
}
203
251
return nodes
@@ -218,27 +266,35 @@ type dedicated struct {
218
266
tracer trace.Tracer
219
267
tAttrs trace.SpanStartEventOption
220
268
dbStmtFunc StatementFunc
269
+ * commandMetrics
221
270
}
222
271
223
272
func (d * dedicated ) B () rueidis.Builder {
224
273
return d .client .B ()
225
274
}
226
275
227
276
func (d * dedicated ) Do (ctx context.Context , cmd rueidis.Completed ) (resp rueidis.RedisResult ) {
228
- ctx , span := d .start (ctx , first (cmd .Commands ()), sum (cmd .Commands ()))
277
+ op := first (cmd .Commands ())
278
+ defer d .recordDuration (ctx , op )()
279
+ ctx , span := d .start (ctx , op , sum (cmd .Commands ()))
229
280
if d .dbStmtFunc != nil {
230
281
span .SetAttributes (dbstmt .String (d .dbStmtFunc (cmd .Commands ())))
231
282
}
232
283
233
284
resp = d .client .Do (ctx , cmd )
234
285
d .end (span , resp .Error ())
286
+ d .recordError (ctx , op , resp .Error ())
235
287
return
236
288
}
237
289
238
290
func (d * dedicated ) DoMulti (ctx context.Context , multi ... rueidis.Completed ) (resp []rueidis.RedisResult ) {
239
- ctx , span := d .start (ctx , multiFirst (multi ), multiSum (multi ))
291
+ op := multiFirst (multi )
292
+ defer d .recordDuration (ctx , op )()
293
+ ctx , span := d .start (ctx , op , multiSum (multi ))
240
294
resp = d .client .DoMulti (ctx , multi ... )
241
- d .end (span , firstError (resp ))
295
+ err := firstError (resp )
296
+ d .end (span , err )
297
+ d .recordError (ctx , op , err )
242
298
return
243
299
}
244
300
0 commit comments