@@ -145,7 +145,15 @@ export class RedisInstrumentationV4_V5 extends InstrumentationBase<RedisInstrume
145145 this . _wrap (
146146 redisClientMultiCommandPrototype ,
147147 'exec' ,
148- this . _getPatchMultiCommandsExec ( )
148+ this . _getPatchMultiCommandsExec ( false )
149+ ) ;
150+ if ( isWrapped ( redisClientMultiCommandPrototype ?. execAsPipeline ) ) {
151+ this . _unwrap ( redisClientMultiCommandPrototype , 'execAsPipeline' ) ;
152+ }
153+ this . _wrap (
154+ redisClientMultiCommandPrototype ,
155+ 'execAsPipeline' ,
156+ this . _getPatchMultiCommandsExec ( true )
149157 ) ;
150158
151159 if ( isWrapped ( redisClientMultiCommandPrototype ?. addCommand ) ) {
@@ -277,36 +285,36 @@ export class RedisInstrumentationV4_V5 extends InstrumentationBase<RedisInstrume
277285 } ;
278286 }
279287
280- private _getPatchMultiCommandsExec ( ) {
288+ private _getPatchMultiCommandsExec ( isPipeline : boolean ) {
281289 const plugin = this ;
282290 return function execPatchWrapper ( original : Function ) {
283291 return function execPatch ( this : any ) {
284292 const execRes = original . apply ( this , arguments ) ;
285293 if ( typeof execRes ?. then !== 'function' ) {
286294 plugin . _diag . error (
287- 'got non promise result when patching RedisClientMultiCommand. exec'
295+ 'non- promise result when patching exec/execAsPipeline '
288296 ) ;
289297 return execRes ;
290298 }
291299
292300 return execRes
293301 . then ( ( redisRes : unknown [ ] ) => {
294302 const openSpans = this [ OTEL_OPEN_SPANS ] ;
295- plugin . _endSpansWithRedisReplies ( openSpans , redisRes ) ;
303+ plugin . _endSpansWithRedisReplies ( openSpans , redisRes , isPipeline ) ;
296304 return redisRes ;
297305 } )
298306 . catch ( ( err : Error ) => {
299307 const openSpans = this [ OTEL_OPEN_SPANS ] ;
300308 if ( ! openSpans ) {
301309 plugin . _diag . error (
302- 'cannot find open spans to end for redis multi command '
310+ 'cannot find open spans to end for multi/pipeline '
303311 ) ;
304312 } else {
305313 const replies =
306314 err . constructor . name === 'MultiErrorReply'
307315 ? ( err as MultiErrorReply ) . replies
308316 : new Array ( openSpans . length ) . fill ( err ) ;
309- plugin . _endSpansWithRedisReplies ( openSpans , replies ) ;
317+ plugin . _endSpansWithRedisReplies ( openSpans , replies , isPipeline ) ;
310318 }
311319 return Promise . reject ( err ) ;
312320 } ) ;
@@ -472,27 +480,40 @@ export class RedisInstrumentationV4_V5 extends InstrumentationBase<RedisInstrume
472480
473481 private _endSpansWithRedisReplies (
474482 openSpans : Array < MutliCommandInfo > ,
475- replies : unknown [ ]
483+ replies : unknown [ ] ,
484+ isPipeline = false
476485 ) {
477486 if ( ! openSpans ) {
478487 return this . _diag . error (
479- 'cannot find open spans to end for redis multi command '
488+ 'cannot find open spans to end for redis multi/pipeline '
480489 ) ;
481490 }
482491 if ( replies . length !== openSpans . length ) {
483492 return this . _diag . error (
484493 'number of multi command spans does not match response from redis'
485494 ) ;
486495 }
496+ // Determine a single operation name for the batch of commands.
497+ // If all commands are identical, include the command name (e.g., "MULTI SET").
498+ // Otherwise, use a generic "MULTI" or "PIPELINE" label for the span.
499+ const allCommands = openSpans . map ( s => s . commandName ) ;
500+ const allSameCommand = allCommands . every ( cmd => cmd === allCommands [ 0 ] ) ;
501+ const operationName = allSameCommand
502+ ? ( isPipeline ? 'PIPELINE ' : 'MULTI ' ) + allCommands [ 0 ]
503+ : isPipeline
504+ ? 'PIPELINE'
505+ : 'MULTI' ;
487506
488507 for ( let i = 0 ; i < openSpans . length ; i ++ ) {
489- const { span, commandName , commandArgs } = openSpans [ i ] ;
508+ const { span, commandArgs } = openSpans [ i ] ;
490509 const currCommandRes = replies [ i ] ;
491510 const [ res , err ] =
492511 currCommandRes instanceof Error
493512 ? [ null , currCommandRes ]
494513 : [ currCommandRes , undefined ] ;
495- this . _endSpanWithResponse ( span , commandName , commandArgs , res , err ) ;
514+ span . setAttribute ( ATTR_DB_OPERATION_NAME , operationName ) ;
515+
516+ this . _endSpanWithResponse ( span , allCommands [ i ] , commandArgs , res , err ) ;
496517 }
497518 }
498519
0 commit comments