Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/httpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sentry_sdk.tracing_utils import (
add_http_breadcrumb,
add_http_request_source,
get_url_attributes,
get_url_attributes_legacy,
propagate_trace_headers,
)
from sentry_sdk.utils import (
Expand Down Expand Up @@ -59,7 +59,7 @@ def send(self: "Client", request: "Request", **kwargs: "Any") -> "Response":
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes = get_url_attributes(client, parsed_url)
url_attributes = get_url_attributes_legacy(client, parsed_url)

if sentry_sdk.get_current_span() is None:
span_ctx = nullcontext()
Expand Down Expand Up @@ -148,7 +148,7 @@ async def send(
},
)

url_attributes = get_url_attributes(client, parsed_url)
url_attributes = get_url_attributes_legacy(client, parsed_url)

with span_ctx as span:
propagate_trace_headers(client, request)
Expand Down
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/httpx2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sentry_sdk.tracing_utils import (
add_http_breadcrumb,
add_http_request_source,
get_url_attributes,
get_url_attributes_legacy,
propagate_trace_headers,
)
from sentry_sdk.utils import (
Expand Down Expand Up @@ -59,7 +59,7 @@ def send(self: "Client", request: "Request", **kwargs: "Any") -> "Response":
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes = get_url_attributes(client, parsed_url)
url_attributes = get_url_attributes_legacy(client, parsed_url)

if sentry_sdk.get_current_span() is None:
span_ctx = nullcontext()
Expand Down Expand Up @@ -148,7 +148,7 @@ async def send(
},
)

url_attributes = get_url_attributes(client, parsed_url)
url_attributes = get_url_attributes_legacy(client, parsed_url)

with span_ctx as span:
propagate_trace_headers(client, request)
Expand Down
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/pyreqwest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sentry_sdk.tracing_utils import (
add_http_breadcrumb,
add_http_request_source,
get_url_attributes,
get_url_attributes_legacy,
propagate_trace_headers,
)
from sentry_sdk.utils import (
Expand Down Expand Up @@ -155,7 +155,7 @@ async def sentry_async_middleware(
# after the request has been sent
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes = get_url_attributes(sentry_sdk.get_client(), parsed_url)
url_attributes = get_url_attributes_legacy(sentry_sdk.get_client(), parsed_url)

response = None
with _sentry_pyreqwest_span(request, url_attributes) as span:
Expand Down Expand Up @@ -193,7 +193,7 @@ def sentry_sync_middleware(
# after the request has been sent
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes = get_url_attributes(sentry_sdk.get_client(), parsed_url)
url_attributes = get_url_attributes_legacy(sentry_sdk.get_client(), parsed_url)

response = None
with _sentry_pyreqwest_span(request, url_attributes) as span:
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
EnvironHeaders,
add_http_breadcrumb,
add_http_request_source,
get_url_attributes,
get_url_attributes_legacy,
should_propagate_trace,
)
from sentry_sdk.utils import (
Expand Down Expand Up @@ -274,7 +274,7 @@ def putrequest(
span: "Optional[Span]" = None
breadcrumb: "dict[str, Any]" = {}

url_attributes = get_url_attributes(client, parsed_url)
url_attributes = get_url_attributes_legacy(client, parsed_url)

breadcrumb[SPANDATA.HTTP_REQUEST_METHOD] = method
breadcrumb.update(url_attributes)
Expand Down
39 changes: 37 additions & 2 deletions sentry_sdk/tracing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ def add_http_breadcrumb(status_code: "Optional[int]", data: "dict[str, Any]") ->
sentry_sdk.add_breadcrumb(**kwargs)


def get_url_attributes(
client: "sentry_sdk.client.BaseClient", parsed_url: "Optional[ParsedUrl]"
def get_url_attributes_legacy(
client: "sentry_sdk.client.BaseClient",
parsed_url: "Optional[ParsedUrl]",
) -> "Attributes":
"""Build the `url.*` span attributes for an outgoing HTTP request.

Expand Down Expand Up @@ -231,6 +232,40 @@ def get_url_attributes(
return attributes


def get_url_attributes(
client: "sentry_sdk.client.BaseClient",
parsed_url: "Optional[ParsedUrl]",
) -> "Attributes":
"""Build the `url.*` span attributes for an outgoing HTTP request.

The query string is filtered through the resolved `data_collection`
settings.
"""
attributes: "Attributes" = {}
if parsed_url is None:
return attributes

query: "Optional[str]" = None
if parsed_url.query:
query = _apply_data_collection_filtering_to_query_string(
query_string=parsed_url.query,
behaviour=client.options["data_collection"]["url_query_params"],
)

url_full = parsed_url.url
if query:
attributes[SPANDATA.URL_QUERY] = query
url_full += "?" + query

if parsed_url.fragment:
attributes[SPANDATA.URL_FRAGMENT] = parsed_url.fragment
url_full += "#" + parsed_url.fragment

attributes[SPANDATA.URL_FULL] = url_full

return attributes


def _get_frame_module_abs_path(frame: "FrameType") -> "Optional[str]":
try:
return frame.f_code.co_filename
Expand Down
69 changes: 15 additions & 54 deletions tests/integrations/boto3/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,11 @@ def test_basic(
assert span["name"] == "aws.s3.ListObjects"


@pytest.mark.parametrize("send_default_pii", [True, False])
def test_streaming(
sentry_init,
capture_events,
capture_items,
send_default_pii,
):
def test_streaming(sentry_init, capture_events, capture_items):
sentry_init(
traces_sample_rate=1.0,
integrations=[Boto3Integration()],
send_default_pii=send_default_pii,
data_collection={},
)

s3 = session.resource("s3")
Expand Down Expand Up @@ -101,15 +95,11 @@ def test_streaming(
"thread.id": mock.ANY,
"thread.name": mock.ANY,
}
if send_default_pii:
expected_attrs["url.full"] = "https://bucket.s3.amazonaws.com/foo.pdf"
expected_attrs["url.full"] = "https://bucket.s3.amazonaws.com/foo.pdf"
assert span1["attributes"] == ApproxDict(expected_attrs)

assert "url.fragment" not in span1["attributes"]
assert "url.query" not in span1["attributes"]
if not send_default_pii:
assert "url.full" not in span1["attributes"]

span2 = spans[1]
assert span2["attributes"]["sentry.op"] == "http.client.stream"
assert span2["name"] == "aws.s3.GetObject"
Expand Down Expand Up @@ -157,7 +147,7 @@ def test_omit_url_data_if_parsing_fails(
sentry_init(
traces_sample_rate=1.0,
integrations=[Boto3Integration()],
send_default_pii=True,
data_collection={},
)

s3 = session.resource("s3")
Expand Down Expand Up @@ -228,12 +218,11 @@ def test_span_origin(
assert spans[0]["attributes"]["sentry.origin"] == "auto.http.boto3"


@pytest.mark.parametrize("send_default_pii", [True, False])
def test_breadcrumb(sentry_init, capture_events, send_default_pii):
def test_breadcrumb(sentry_init, capture_events):
sentry_init(
integrations=[Boto3Integration()],
default_integrations=False,
send_default_pii=send_default_pii,
data_collection={},
)

s3 = session.resource("s3")
Expand All @@ -253,24 +242,14 @@ def test_breadcrumb(sentry_init, capture_events, send_default_pii):
assert crumb["type"] == "http"
assert crumb["category"] == "httplib"

if send_default_pii:
assert crumb["data"] == ApproxDict(
{
SPANDATA.URL_FULL: mock.ANY,
SPANDATA.HTTP_REQUEST_METHOD: "GET",
SPANDATA.URL_QUERY: mock.ANY,
}
)
assert SPANDATA.URL_FRAGMENT not in crumb["data"]
else:
assert crumb["data"] == ApproxDict(
{
SPANDATA.HTTP_REQUEST_METHOD: "GET",
}
)
assert SPANDATA.URL_FULL not in crumb["data"]
assert SPANDATA.URL_QUERY not in crumb["data"]
assert SPANDATA.URL_FRAGMENT not in crumb["data"]
assert crumb["data"] == ApproxDict(
{
SPANDATA.URL_FULL: mock.ANY,
SPANDATA.HTTP_REQUEST_METHOD: "GET",
SPANDATA.URL_QUERY: mock.ANY,
}
)
assert SPANDATA.URL_FRAGMENT not in crumb["data"]


BUCKET_URL = "https://bucket.s3.amazonaws.com/"
Expand All @@ -279,19 +258,9 @@ def test_breadcrumb(sentry_init, capture_events, send_default_pii):
# means the URL is recorded without a query string.
# Structure of the parameters is "init_kwargs, expected_query"
URL_QUERY_PARAMS = [
pytest.param(
{"send_default_pii": True},
"list-type=2&prefix=foo&continuation-token=abc&encoding-type=url",
id="send_default_pii_true",
),
pytest.param(
{"send_default_pii": False},
None,
id="send_default_pii_false",
),
pytest.param(
{},
None,
"list-type=2&prefix=foo&continuation-token=%5BFiltered%5D&encoding-type=url",
id="defaults",
),
pytest.param(
Expand Down Expand Up @@ -334,14 +303,6 @@ def test_breadcrumb(sentry_init, capture_events, send_default_pii):
"",
id="data_collection_off",
),
pytest.param(
{
"send_default_pii": True,
"data_collection": {"url_query_params": {"mode": "off"}},
},
"",
id="data_collection_wins_over_send_default_pii",
),
]


Expand Down
Loading