Skip to content

feat(redis): Support streaming spans#6083

Draft
sentrivana wants to merge 8 commits intomasterfrom
ivana/port-redis-to-span-first
Draft

feat(redis): Support streaming spans#6083
sentrivana wants to merge 8 commits intomasterfrom
ivana/port-redis-to-span-first

Conversation

@sentrivana
Copy link
Copy Markdown
Contributor

@sentrivana sentrivana commented Apr 16, 2026

Description

Support span streaming in the Redis integration(s).

  • support creating streamed spans
  • move data and tags to attributes
  • make sure attributes are in semantic conventions
  • add tests

Issues

Reminders

@linear-code
Copy link
Copy Markdown

linear-code bot commented Apr 16, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 16, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 16, 2026

Codecov Results 📊

142 passed | Total: 142 | Pass Rate: 100% | Execution Time: 24.90s

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +116
Passed Tests 📈 +116
Failed Tests
Skipped Tests

All tests are passing successfully.

❌ Patch coverage is 7.37%. Project has 14189 uncovered lines.
✅ Project coverage is 33.67%. Comparing base (base) to head (head).

Files with missing lines (6)
File Patch % Lines
utils.py 15.12% ⚠️ 73 Missing
_async_common.py 0.00% ⚠️ 63 Missing
_sync_common.py 18.46% ⚠️ 53 Missing
caches.py 17.46% ⚠️ 52 Missing
queries.py 22.50% ⚠️ 31 Missing
redis_cluster.py 26.47% ⚠️ 25 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    27.67%    33.67%       +6%
==========================================
  Files          190       190         —
  Lines        21351     21391       +40
  Branches      7066      7098       +32
==========================================
+ Hits          5908      7202     +1294
- Misses       15443     14189     -1254
- Partials       564       700      +136

Generated by Codecov Action

Comment thread sentry_sdk/integrations/redis/_async_common.py
db_span.__exit__(None, None, None)
if cache_span:
with capture_internal_exceptions():
_set_cache_data(cache_span, self, cache_properties, value)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NameError raised when Redis command fails with exception

In sentry_patched_execute_command, when old_execute_command raises an exception, the value variable is never assigned. The finally block then attempts to use value in _set_cache_data(cache_span, self, cache_properties, value), causing a NameError. While capture_internal_exceptions() catches this, it results in unnecessary internal exception noise and obscures the real error from monitoring.

Verification

Read the full file at _sync_common.py, traced through the try/finally block logic. Verified that value is only assigned on line 152 inside the try block. If an exception is raised, execution jumps to finally where line 158 references value which would be undefined.

Identified by Warden code-review · XZX-J22

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix attempt detected (commit 032c7e2)

The commit reorganized code into a try-finally block and wrapped the problematic _set_cache_data call with capture_internal_exceptions(), but the core issue persists: if old_execute_command raises an exception, value remains undefined when accessed on line 158, causing the same NameError (just silently caught rather than fixed)

The original issue appears unresolved. Please review and try again.

Evaluated by Warden

) -> None:
span.set_tag("redis.is_cluster", is_cluster)
span.set_tag("redis.transaction", is_transaction)
if isinstance(span, Span):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NameError: Span is only imported under TYPE_CHECKING but used at runtime

The Span class is imported only under TYPE_CHECKING (line 17), which means it's not available at runtime. However, isinstance(span, Span) is called at line 115, which will raise NameError: name 'Span' is not defined whenever _set_pipeline_data is called with any span type.

Verification

Read lines 1-17 of utils.py confirming Span is imported inside if TYPE_CHECKING: block. Verified no other imports of Span exist outside TYPE_CHECKING. The isinstance check at line 115 will fail at runtime.

Suggested fix: Import Span at runtime or invert the logic to check for StreamedSpan first (which is already imported at runtime on line 10)

Suggested change
if isinstance(span, Span):
if not isinstance(span, StreamedSpan):

Identified by Warden code-review · VKW-3W2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate redis to span first

1 participant