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
219 changes: 66 additions & 153 deletions sentry_sdk/integrations/httpx2.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
add_http_breadcrumb,
add_http_request_source,
get_url_attributes,
has_span_streaming_enabled,
propagate_trace_headers,
)
from sentry_sdk.utils import (
Expand All @@ -22,8 +21,6 @@
if TYPE_CHECKING:
from typing import Any

from sentry_sdk._types import Attributes


try:
from httpx2 import AsyncClient, Client, Request, Response
Expand Down Expand Up @@ -57,104 +54,62 @@ def _install_httpx2_client() -> None:
@ensure_integration_enabled(Httpx2Integration, real_send)
def send(self: "Client", request: "Request", **kwargs: "Any") -> "Response":
client = sentry_sdk.get_client()
is_span_streaming_enabled = has_span_streaming_enabled(client.options)

parsed_url = None
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes: "Attributes" = {}

if is_span_streaming_enabled:
if sentry_sdk.traces.get_current_span() is None:
span_ctx = nullcontext()
else:
span_ctx = sentry_sdk.traces.start_span(
name="%s %s"
% (
request.method,
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
),
attributes={
"sentry.op": OP.HTTP_CLIENT,
"sentry.origin": Httpx2Integration.origin,
"http.request.method": request.method,
},
)

url_attributes = get_url_attributes(client, parsed_url)

with span_ctx as streamed_span:
propagate_trace_headers(client, request)

try:
rv = real_send(self, request, **kwargs)

if streamed_span is not None:
streamed_span.status = (
"error" if rv.status_code >= 400 else "ok"
)
streamed_span.set_attribute(
"http.response.status_code", rv.status_code
)
finally:
if streamed_span is not None:
streamed_span.set_attributes(url_attributes)

if streamed_span is not None:
# Needs to happen within the context manager as we want to attach the
# final data before the span finishes and is sent for ingesting.
with capture_internal_exceptions():
add_http_request_source(streamed_span)
url_attributes = get_url_attributes(client, parsed_url)

if sentry_sdk.traces.get_current_span() is None:
span_ctx = nullcontext()
else:
with sentry_sdk.start_span(
op=OP.HTTP_CLIENT,
span_ctx = sentry_sdk.traces.start_span(
name="%s %s"
% (
request.method,
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
),
origin=Httpx2Integration.origin,
) as span:
span.set_data(SPANDATA.HTTP_METHOD, request.method)
if parsed_url is not None:
span.set_data("url", parsed_url.url)
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)
attributes={
"sentry.op": OP.HTTP_CLIENT,
"sentry.origin": Httpx2Integration.origin,
"http.request.method": request.method,
},
)

propagate_trace_headers(client, request)
with span_ctx as span:
propagate_trace_headers(client, request)

try:
rv = real_send(self, request, **kwargs)

span.set_http_status(rv.status_code)
span.set_data("reason", rv.reason_phrase)
if span is not None:
span.status = "error" if rv.status_code >= 400 else "ok"
span.set_attribute("http.response.status_code", rv.status_code)
finally:
if span is not None:
span.set_attributes(url_attributes)

with capture_internal_exceptions():
add_http_request_source(span)
if span is not None:
# Needs to happen within the context manager as we want to attach the
# final data before the span finishes and is sent for ingesting.
with capture_internal_exceptions():
add_http_request_source(span)

breadcrumb_data = {
SPANDATA.HTTP_METHOD: request.method,
SPANDATA.HTTP_STATUS_CODE: rv.status_code,
"reason": rv.reason_phrase,
}

if parsed_url:
if not is_span_streaming_enabled:
breadcrumb_data.update(
{
"url": parsed_url.url,
SPANDATA.HTTP_QUERY: parsed_url.query,
SPANDATA.HTTP_FRAGMENT: parsed_url.fragment,
}
)
elif url_attributes:
breadcrumb_data.update(
{
"url": url_attributes.get("url.full", ""),
SPANDATA.HTTP_QUERY: url_attributes.get("url.query", ""),
SPANDATA.HTTP_FRAGMENT: url_attributes.get("url.fragment", ""),
}
)
if parsed_url and url_attributes:
breadcrumb_data.update(
{
"url": url_attributes.get("url.full", ""),
SPANDATA.HTTP_QUERY: url_attributes.get("url.query", ""),
SPANDATA.HTTP_FRAGMENT: url_attributes.get("url.fragment", ""),
}
)

add_http_breadcrumb(rv.status_code, breadcrumb_data)

Expand All @@ -173,102 +128,60 @@ async def send(
if client.get_integration(Httpx2Integration) is None:
return await real_send(self, request, **kwargs)

is_span_streaming_enabled = has_span_streaming_enabled(client.options)
parsed_url = None
with capture_internal_exceptions():
parsed_url = parse_url(str(request.url), sanitize=False)

url_attributes: "Attributes" = {}

if is_span_streaming_enabled:
if sentry_sdk.traces.get_current_span() is None:
span_ctx = nullcontext()
else:
span_ctx = sentry_sdk.traces.start_span(
name="%s %s"
% (
request.method,
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
),
attributes={
"sentry.op": OP.HTTP_CLIENT,
"sentry.origin": Httpx2Integration.origin,
"http.request.method": request.method,
},
)

url_attributes = get_url_attributes(client, parsed_url)

with span_ctx as streamed_span:
propagate_trace_headers(client, request)

try:
rv = await real_send(self, request, **kwargs)

if streamed_span is not None:
streamed_span.status = (
"error" if rv.status_code >= 400 else "ok"
)
streamed_span.set_attribute(
"http.response.status_code", rv.status_code
)
finally:
if streamed_span is not None:
streamed_span.set_attributes(url_attributes)

if streamed_span is not None:
# Needs to happen within the context manager as we want to attach the
# final data before the span finishes and is sent for ingesting.
with capture_internal_exceptions():
add_http_request_source(streamed_span)
if sentry_sdk.traces.get_current_span() is None:
span_ctx = nullcontext()
else:
with sentry_sdk.start_span(
op=OP.HTTP_CLIENT,
span_ctx = sentry_sdk.traces.start_span(
name="%s %s"
% (
request.method,
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
),
origin=Httpx2Integration.origin,
) as span:
span.set_data(SPANDATA.HTTP_METHOD, request.method)
if parsed_url is not None:
span.set_data("url", parsed_url.url)
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)
attributes={
"sentry.op": OP.HTTP_CLIENT,
"sentry.origin": Httpx2Integration.origin,
"http.request.method": request.method,
},
)

url_attributes = get_url_attributes(client, parsed_url)

propagate_trace_headers(client, request)
with span_ctx as span:
propagate_trace_headers(client, request)

try:
rv = await real_send(self, request, **kwargs)

span.set_http_status(rv.status_code)
span.set_data("reason", rv.reason_phrase)
if span is not None:
span.status = "error" if rv.status_code >= 400 else "ok"
span.set_attribute("http.response.status_code", rv.status_code)
finally:
if span is not None:
span.set_attributes(url_attributes)

with capture_internal_exceptions():
add_http_request_source(span)
if span is not None:
# Needs to happen within the context manager as we want to attach the
# final data before the span finishes and is sent for ingesting.
with capture_internal_exceptions():
add_http_request_source(span)

breadcrumb_data = {
SPANDATA.HTTP_METHOD: request.method,
SPANDATA.HTTP_STATUS_CODE: rv.status_code,
"reason": rv.reason_phrase,
}
if parsed_url:
if not is_span_streaming_enabled:
breadcrumb_data.update(
{
"url": parsed_url.url,
SPANDATA.HTTP_QUERY: parsed_url.query,
SPANDATA.HTTP_FRAGMENT: parsed_url.fragment,
}
)
elif url_attributes:
breadcrumb_data.update(
{
"url": url_attributes.get("url.full", ""),
SPANDATA.HTTP_QUERY: url_attributes.get("url.query", ""),
SPANDATA.HTTP_FRAGMENT: url_attributes.get("url.fragment", ""),
}
)
if parsed_url and url_attributes:
breadcrumb_data.update(
{
"url": url_attributes.get("url.full", ""),
SPANDATA.HTTP_QUERY: url_attributes.get("url.query", ""),
SPANDATA.HTTP_FRAGMENT: url_attributes.get("url.fragment", ""),
}
)

add_http_breadcrumb(rv.status_code, breadcrumb_data)

Expand Down
Loading
Loading