Skip to content

[instrumentation-redis] Commands run as part of a transaction not showing up when connecting to a cluster #3369

@mderriey

Description

@mderriey

What version of OpenTelemetry are you using?

v1.9.0

What version of Node are you using?

v24.11.1

What did you do?

Some context: we've been using the Redis instrumentation for several years and it's been great, thanks a lot!

Lately, we've moved from Azure Cache for Redis (standalone server) to Azure Managed Redis, which runs a Redis OSS cluster.

Code-wise, we've had to change our use of @redis/client from createClient to createCluster to accommodate the changes.

We perform some operations in a transaction using the client.multi() function:

// .multi() / .exec() performs the operations as a transaction
// See https://github.com/redis/node-redis/blob/master/docs/transactions.md
const [_, cost] = await redisClient
  .multi()
  // Remove members from the sorted set which are older than the period
  // https://redis.io/docs/latest/commands/zremrangebyscore/
  .ZREMRANGEBYSCORE(key, '-inf', startRange)
  // Get the number of members in the sorted set
  // https://redis.io/docs/latest/commands/zcard/
  .ZCARD(key)
  .execTyped()

We also perform other less critical operations in a pipeline, where we issue the commands in a single request, but they're not guaranteed to run in a certain order, and other operations could run in between.

// Use pipelining instead of a transaction here: https://github.com/redis/node-redis/blob/master/packages/redis/README.md#auto-pipelining
// Pipelining sends multiple commands over a single request to Redis, however they're not guaranteed to be processed in order,
// or that other commands won't be processed in between.
// Adding the members to the sorted set and updating the expiry are not critical operations, and wouldn't benefit
// from the overhead of a transaction.
await Promise.all([
  // Add member to the sorted set
  // https://redis.io/docs/latest/commands/zadd/
  redisClient.ZADD(key, members),
  // Mark the key for expiry so Redis removes it if this user doesn't make a request within the defined period
  // https://redis.io/docs/latest/commands/expire/
  redisClient.EXPIRE(key, periodInSeconds),
])

Before moving to Azure Managed Redis / createCluster, we saw spans for every single command, see example below:

Image

What did you expect to see?

One span for each command.

What did you see instead?

We can't see spans for the commands issued in a transaction, ZREMRANGEBYSCORE and ZCARD, see example below:

Image

Additional context

I created a repro repo at https://github.com/mderriey/repro-instrumentation-redis-multi-cluster.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p2Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions