Skip to content

feat(boto3): Support span streaming#6193

Open
alexander-alderman-webb wants to merge 18 commits intomasterfrom
webb/boto3/span-first
Open

feat(boto3): Support span streaming#6193
alexander-alderman-webb wants to merge 18 commits intomasterfrom
webb/boto3/span-first

Conversation

@alexander-alderman-webb
Copy link
Copy Markdown
Contributor

@alexander-alderman-webb alexander-alderman-webb commented May 4, 2026

Description

In the streaming path, use

  • http.request.method instead of http.method
  • url.full instead of `url
  • url.query instead of aws.request.url
  • url.fragment instead of http.fragment
  • rpc.method instead of both aws.service_id and aws.operation_name

Adapting Tests

sed commands used for converting transaction context managers:

  • sed -i '' 's/sentry_sdk.start_transaction()/sentry_sdk.traces.start_span(name="custom parent")/g'
  • sed -i '' 's/sentry_sdk.start_transaction() as transaction/sentry_sdk.traces.start_span(name="custom parent") as span/g'
  • sed -i '' 's/start_transaction() as transaction/sentry_sdk.traces.start_span(name="custom parent") as span/g'

sed commands used for converting specific attributes:

  • sed -i '' 's/http.method/http.request.method/g'
  • sed -i '' 's/aws.request.url/url.full/g'
  • sed -i '' 's/http.fragment/url.fragment/g'
  • sed -i '' 's/http.query/url.query/g'

sed commands used for converting event capture:

  • sed -i '' 's/assert len(spans) == 2/assert len(spans) == 3/g'
  • sed -i '' 's/assert len(spans) == 1/assert len(spans) == 2/g'
  • sed -i '' 's/(event, ) = (item.payload for item in items if item.type == "span")/spans = [item.payload for item in items if item.type == "span"]/g'
  • sed -i '' 's/event["spans"]/spans/g'
  • sed -i '' '/assert event["type"] == "transaction"/d'
  • sed -i '' 's/transaction.finish()/span.finish()/g'
  • sed -i '' 's/(event,) = events/(event, ) = (item.payload for item in items if item.type == "span")/g'
  • sed -i '' 's/events = capture_events()/items = capture_items("event", "transaction", "span")/g'
  • sed -i '' 's/capture_events,/capture_items,/g'

sed commands used for converting op:

  • sed -i '' 's/["op"]/["attributes"]["sentry.op"]/g'

sed commands used for converting origin:

  • sed -i '' 's/["origin"]/["attributes"]["sentry.origin"]/g'

sed commands used for converting description:

  • sed -i '' 's/description/name/g'

sed commands used for converting data to attributes:

  • sed -i '' 's/["data"]/["attributes"]/g'

Issues

Reminders

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Codecov Results 📊

146 passed | Total: 146 | Pass Rate: 100% | Execution Time: 21.64s

All tests are passing successfully.

❌ Patch coverage is 9.09%. Project has 14148 uncovered lines.

Files with missing lines (2)
File Patch % Lines
boto3.py 13.13% ⚠️ 86 Missing
consts.py 99.48% ⚠️ 2 Missing

Generated by Codecov Action

Comment thread tests/integrations/boto3/test_s3.py Outdated
Comment thread sentry_sdk/integrations/boto3.py
Comment thread tests/integrations/boto3/test_s3.py
Comment thread sentry_sdk/integrations/boto3.py
Comment thread sentry_sdk/integrations/boto3.py Outdated
Comment thread sentry_sdk/integrations/boto3.py
Comment thread sentry_sdk/integrations/boto3.py Outdated
@alexander-alderman-webb alexander-alderman-webb marked this pull request as ready for review May 5, 2026 12:22
@alexander-alderman-webb alexander-alderman-webb requested a review from a team as a code owner May 5, 2026 12:22
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7e39d58. Configure here.

Comment thread sentry_sdk/integrations/boto3.py Outdated
Comment thread tests/integrations/boto3/test_s3.py Outdated
Comment thread sentry_sdk/integrations/boto3.py Outdated
Comment thread sentry_sdk/integrations/boto3.py
Comment thread sentry_sdk/integrations/boto3.py
description = "aws.%s.%s" % (service_id.hyphenize(), operation_name)

client = sentry_sdk.get_client()
span_streaming = has_span_streaming_enabled(client.options)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For variable names capturing states (like this one), naming it like a noun/a thing makes it harder to read in isolation in other areas of the code.

Something that leverages a verb/predicate, along the lines of is_span_streaming_enabled, is generally better for values/variables like this.

span.set_attribute(SPANDATA.URL_QUERY, parsed_url.query)
span.set_attribute(SPANDATA.URL_FRAGMENT, parsed_url.fragment)

span.set_attribute(SPANDATA.RPC_METHOD, f"{service_id}/{operation_name}")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Because this is set outside of any conditionals within this block, you could move this up into the attributes dict passed in start_span above

span.set_attribute(SPANDATA.URL_FRAGMENT, parsed_url.fragment)

span.set_attribute(SPANDATA.RPC_METHOD, f"{service_id}/{operation_name}")
if request.method is not None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I noticed that the legacy approach doesn't have this guard, and I assume it's because set_data is typed more permissively in that it accepts None where set_attribute does not.

This makes me wonder - are we currently sending None values within the envelope for legacy spans for the HTTP_METHOD on line 106? I wonder if we should also guard that in order to remove an unnecessary value being added 🤔

origin=Boto3Integration.origin,
)
streaming_span: "Union[Span, StreamedSpan]"
if isinstance(span, StreamedSpan):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As this is currently written, NoOpStreamedSpan spans will evaluate to true and enter this block. It doesn't look like it'll cause the application to crash as it does have a name property (although it's an empty string), but wanted to call this out in case this is unintentional.

If you only care about StreamedSpans entering this block, then this will need to be updated to type(span) is StreamedSpan.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants