Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
4d1d3f5
ref(boto3): split integration into internal modules
pabloDeputter Sep 18, 2026
0c23830
ref(boto3): Move consts to
pabloDeputter Sep 21, 2026
b45f76c
fix(boto3): Move imports
pabloDeputter Sep 21, 2026
ab843bc
ref(boto3): Remove dupliocate `_check_minimum_version()`
pabloDeputter Sep 30, 2026
b21b888
ref(boto3): Update integration checks to use IDENTIFIER constant
pabloDeputter Sep 30, 2026
f91d311
fix(boto3): harden StreamingBody span finalization
pabloDeputter Sep 18, 2026
ec2a236
lint
pabloDeputter Sep 18, 2026
3b53fa4
ref(boto3): renaming vars
pabloDeputter Sep 21, 2026
eea1fc1
ref(boto3): Add specific comment on why we initialize with
pabloDeputter Sep 21, 2026
364f547
fix(boto3): ensure span finishes correctly when reading streaming body
pabloDeputter Sep 21, 2026
4f3cfce
fix(boto3): trace the complete client-call lifecycle
pabloDeputter Sep 21, 2026
644aff8
fix merging issues
pabloDeputter Sep 21, 2026
608ee4a
review changes
pabloDeputter Sep 21, 2026
ec8cef7
add test for when `StreamingBody` instrumentation setup fails
pabloDeputter Sep 21, 2026
3a60fb9
fix(boto3): finish streaming spans before legacy boto spans
pabloDeputter Sep 21, 2026
9c2f329
add permalink
pabloDeputter Sep 21, 2026
f9755ca
add some more comments
pabloDeputter Sep 21, 2026
a9e87f5
ref(boto3): use permalink
pabloDeputter Sep 29, 2026
2647da1
ref(boto3): fix grammar in comments
pabloDeputter Sep 29, 2026
8518c62
feat(boto3): improve boto3 integration
pabloDeputter Sep 21, 2026
7bf92dd
lint
pabloDeputter Sep 21, 2026
606c630
fix(boto3): overwrite server attributes when request URL is resolved
pabloDeputter Sep 22, 2026
74083ab
ref(boto3): move `aws-api` to `consts.py`
pabloDeputter Sep 29, 2026
7e5ba86
tests(boto3): move `span_streaming` inside method call
pabloDeputter Sep 29, 2026
6868ffd
ref(boto3): move `DEFAULT_PORTS` to `consts.py`
pabloDeputter Sep 29, 2026
d32a43f
ref(boto3): simplify client span lifecycle and header handling
pabloDeputter Sep 18, 2026
822438b
feat(boto3): add attributes to `consts.py`
pabloDeputter Sep 14, 2026
46d24b2
merge changes
pabloDeputter Sep 15, 2026
30d1e3f
add tests
pabloDeputter Sep 17, 2026
250699d
patch correct methods
pabloDeputter Sep 15, 2026
d9edef5
lint
pabloDeputter Sep 18, 2026
90383dc
use ordered search for request id and hist id
pabloDeputter Sep 18, 2026
d482500
ref(boto3): remove redundant span checks during enrichment
pabloDeputter Sep 18, 2026
26fdcb1
fix duplicates when merging
pabloDeputter Sep 18, 2026
eeac30a
use consts and string lookup for `client.getintegration`
pabloDeputter Sep 21, 2026
8b61aac
lint
pabloDeputter Sep 22, 2026
308eb5f
ruff
pabloDeputter Sep 22, 2026
8e4ce5a
ref(boto3): add permalinks
pabloDeputter Sep 29, 2026
832d90d
fix(boto3): add `error.type` to both span kinds
pabloDeputter Sep 29, 2026
0ee5f14
ref(boto3): specify docstring for `_set_span_attributes()` further
pabloDeputter Sep 29, 2026
a8f521e
ref(boto3): use f-string instead
pabloDeputter Sep 29, 2026
2d92b4e
ref(boto3): remove comment regarding `HTTP_REQUEST_RESEND_COUNT`
pabloDeputter Sep 29, 2026
12dd5e6
ref(boto3): remove `else` block
pabloDeputter Sep 29, 2026
21794bf
tests(boto3): remove uncessary testcases
pabloDeputter Sep 29, 2026
7859e97
ref(boto3): remove uncessary defensive conditionals
pabloDeputter Sep 29, 2026
1f4e936
fix flaky test
pabloDeputter Sep 30, 2026
02a8fa1
add base `ServiceExtension` class
pabloDeputter Sep 18, 2026
ee7e768
feat(boto3): Add service registry
pabloDeputter Sep 18, 2026
4d9ae30
add missing `__init__.py` file
pabloDeputter Sep 18, 2026
e90b407
simplify `_resolve_service()` logic
pabloDeputter Sep 18, 2026
af519a0
add service extension logic to `_instrumentation.py`
pabloDeputter Sep 18, 2026
98cc2a4
combine span-config extraction and validation in `_start_client_span()`
pabloDeputter Sep 18, 2026
ca7e449
add service extension logic to `_client.py`
pabloDeputter Sep 30, 2026
f95f4fe
add tests
pabloDeputter Sep 18, 2026
b0b9f0c
fix(boto3): Remove "hardcoded" origin
pabloDeputter Sep 22, 2026
7d645b4
feat(boto3): Add `sentry.kind` attribute to boto span
pabloDeputter Sep 22, 2026
64e1464
ref(boto3): Add comment explaining
pabloDeputter Sep 22, 2026
f221d72
Update sentry_sdk/integrations/boto3/_services/base.py
pabloDeputter Sep 29, 2026
a106f76
fix(boto3): correct `AWS_RPC_SYSTEM_NAME` constant
pabloDeputter Sep 29, 2026
032eff3
ref(boto3): refactor `get_span_config()` into `get_span_op()` and `ge…
pabloDeputter Sep 29, 2026
b1d9551
ref(boto3): remove attribute-precedence
pabloDeputter Sep 29, 2026
c2f4f6b
ref(boto3): remove lazy-loading approach; replace with static map
pabloDeputter Sep 30, 2026
a928e74
fix(boto3): make logic clearer
pabloDeputter Sep 30, 2026
2d85548
ref(boto3): change comment's and simplify logic
pabloDeputter Sep 30, 2026
9d2bd96
ref(boto3): remove defensive checks
pabloDeputter Sep 30, 2026
b65c0ca
ref(boto3): remove defensive checks and cleanup comments
pabloDeputter Sep 30, 2026
1270b49
cleanup tests
pabloDeputter Sep 30, 2026
91c9bdb
remove AI comment
pabloDeputter Sep 30, 2026
f2a2bc6
feat(attributes): Add s3 relevant attributes to `SPANDATA`
pabloDeputter Sep 22, 2026
0e948cb
feat(boto3): Register s3 to `_SERVICE_EXTENSIONS`
pabloDeputter Sep 30, 2026
a3629db
feat(boto3): Add attribute extraction helpers
pabloDeputter Sep 22, 2026
7c39a6c
feat(boto3): Add S3 extensio
pabloDeputter Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ref(boto3): refactor get_span_config() into get_span_op() and `ge…
…t_span_origin()`
  • Loading branch information
pabloDeputter committed Sep 30, 2026
commit 032eff31a5872eaa8cccaabea2bcda5641e60358
15 changes: 8 additions & 7 deletions sentry_sdk/integrations/boto3/_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,14 @@ def _start_client_span(

if service_ext is not None:
with capture_internal_exceptions():
config = service_ext.get_span_config(ctx)
if config is not None:
service_op, service_origin = config
if isinstance(service_op, str) and service_op:
span_op = service_op
if isinstance(service_origin, str) and service_origin:
span_origin = service_origin
service_op = service_ext.get_span_op(ctx)
if service_op is not None:
span_op = service_op

with capture_internal_exceptions():
service_origin = service_ext.get_span_origin(ctx)
if service_origin is not None:
span_origin = service_origin

with capture_internal_exceptions():
attributes.update(service_ext.get_request_attributes(ctx))
Expand Down
12 changes: 7 additions & 5 deletions sentry_sdk/integrations/boto3/_services/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Any, Optional, Tuple
from typing import Any, Optional

from sentry_sdk._types import Attributes
from sentry_sdk.integrations.boto3._context import AwsCallContext
Expand All @@ -14,10 +14,12 @@ class _ServiceExtension:

__slots__ = ()

def get_span_config(
self, ctx: "AwsCallContext"
) -> "Optional[Tuple[Optional[str], Optional[str]]]":
"""Return an optional `(op, origin)` override for the client span."""
def get_span_op(self, ctx: "AwsCallContext") -> "Optional[str]":
"""Return an optional `sentry.op` override for the client span."""
return None

def get_span_origin(self, ctx: "AwsCallContext") -> "Optional[str]":
"""Return an optional `sentry.origin` override for the client span."""
return None

def get_request_attributes(self, ctx: "AwsCallContext") -> "Attributes":
Expand Down
26 changes: 21 additions & 5 deletions tests/integrations/boto3/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,12 @@ def respond(request, **kwargs):
return request_span_ids


def _capture_boto3_spans_by_op(invoke_client_method, capture_items, span_streaming):
def _capture_bot^o3_spans_by_op(
invoke_client_method,
capture_items,
span_streaming,
expected_origin=ORIGIN,
):
items = capture_items()

if span_streaming:
Expand All @@ -333,14 +338,17 @@ def _capture_boto3_spans_by_op(invoke_client_method, capture_items, span_streami
item.payload
for item in items
if item.type == "span"
and item.payload["attributes"].get(SPANDATA.SENTRY_ORIGIN) == ORIGIN
and item.payload["attributes"].get(SPANDATA.SENTRY_ORIGIN)
== expected_origin
]
else:
with sentry_sdk.start_transaction():
invoke_client_method()

transaction = next(item.payload for item in items if item.type == "transaction")
spans = [span for span in transaction["spans"] if span["origin"] == ORIGIN]
spans = [
span for span in transaction["spans"] if span["origin"] == expected_origin
]

spans_by_op = {}
for span in spans:
Expand Down Expand Up @@ -398,8 +406,11 @@ def test_service_extension_customizes_client_span(
span_streaming,
):
class TestServiceExtension(_ServiceExtension):
def get_span_config(self, ctx):
return ("aws.test", None)
def get_span_op(self, ctx):
return "aws.test"

def get_span_origin(self, ctx):
return "auto.aws.test"

def get_request_attributes(self, ctx):
return {
Expand Down Expand Up @@ -437,6 +448,7 @@ def get_response_attributes(self, ctx, response):
lambda: client.head_object(**api_params),
capture_items,
span_streaming,
expected_origin="auto.aws.test",
)

spans = spans_by_op.get("aws.test", [])
Expand All @@ -447,6 +459,10 @@ def get_response_attributes(self, ctx, response):
assert attributes[SPANDATA.SENTRY_KIND] == "producer"
assert attributes[SPANDATA.RPC_METHOD] == "HeadObject"
assert attributes[SPANDATA.HTTP_STATUS_CODE] == 200
if span_streaming:
assert attributes[SPANDATA.SENTRY_ORIGIN] == "auto.aws.test"
else:
assert spans[0]["origin"] == "auto.aws.test"


@pytest.mark.parametrize("span_streaming", [True, False])
Expand Down