From ce7ee4f61e07b0f1483f9ec7e139506cdf5e120b Mon Sep 17 00:00:00 2001 From: alliasgher Date: Tue, 14 Apr 2026 22:25:09 +0500 Subject: [PATCH 1/2] fix(redis): extract ClusterPipeline commands from _execution_strategy in redis-py 6+ redis-py 6 refactored ClusterPipeline so that commands are appended to _execution_strategy.command_queue instead of instance.command_stack. The latter still exists but is never populated, causing pipeline spans to always show an empty command list. Prefer _execution_strategy.command_queue when it exists, falling back to the old command_stack / _command_stack attributes for older versions and non-cluster pipelines. Fixes #4084 Signed-off-by: alliasgher --- .../opentelemetry/instrumentation/redis/util.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py index 320758f842..e63379dd48 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/util.py @@ -184,11 +184,17 @@ def _build_span_meta_data_for_pipeline( instance: PipelineInstance | AsyncPipelineInstance, ) -> tuple[list[Any], str, str]: try: - command_stack = ( - instance.command_stack - if hasattr(instance, "command_stack") - else instance._command_stack - ) + # redis-py 6+ ClusterPipeline stores commands on _execution_strategy. + # Fall back to command_stack / _command_stack for older versions and + # non-cluster pipelines. + if hasattr(instance, "_execution_strategy") and hasattr( + instance._execution_strategy, "command_queue" + ): + command_stack = instance._execution_strategy.command_queue + elif hasattr(instance, "command_stack"): + command_stack = instance.command_stack + else: + command_stack = instance._command_stack cmds = [ _format_command_args(c.args if hasattr(c, "args") else c[0]) From 584168215e6dcc82b4e93fe7e9cb525e00a2e019 Mon Sep 17 00:00:00 2001 From: Ali Date: Thu, 16 Apr 2026 01:20:46 +0500 Subject: [PATCH 2/2] chore: add CHANGELOG entry for #4436 Signed-off-by: Ali --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8818f8b070..21d1620fa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `pylint` to `4.0.5` ([#4244](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4244)) +### Fixed + +- `opentelemetry-instrumentation-redis`: Extract `ClusterPipeline` commands from `_execution_strategy` in redis-py 6+ so span attributes include the pipelined commands instead of being empty + ([#4436](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4436)) + ### Breaking changes - Drop Python 3.9 support