Skip to content

Commit 39e2e43

Browse files
Merge branch 'master' into webb/stdlib/code-source-tests
2 parents 22b2886 + a4c16d7 commit 39e2e43

25 files changed

Lines changed: 1804 additions & 481 deletions

sentry_sdk/integrations/_wsgi_common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"HTTP_SET_COOKIE",
3232
"HTTP_COOKIE",
3333
"HTTP_AUTHORIZATION",
34+
"HTTP_PROXY_AUTHORIZATION",
3435
"HTTP_X_API_KEY",
3536
"HTTP_X_FORWARDED_FOR",
3637
"HTTP_X_REAL_IP",

sentry_sdk/integrations/celery/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
)
1515
from sentry_sdk.integrations.celery.utils import _now_seconds_since_epoch
1616
from sentry_sdk.integrations.logging import ignore_logger
17+
from sentry_sdk.scope import should_send_default_pii
1718
from sentry_sdk.traces import StreamedSpan
1819
from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, Span, TransactionSource
1920
from sentry_sdk.tracing_utils import Baggage, has_span_streaming_enabled
2021
from sentry_sdk.utils import (
22+
SENSITIVE_DATA_SUBSTITUTE,
2123
capture_internal_exceptions,
2224
event_from_exception,
2325
reraise,
@@ -143,8 +145,12 @@ def event_processor(event: "Event", hint: "Hint") -> "Optional[Event]":
143145
extra = event.setdefault("extra", {})
144146
extra["celery-job"] = {
145147
"task_name": task.name,
146-
"args": args,
147-
"kwargs": kwargs,
148+
"args": (
149+
args if should_send_default_pii() else SENSITIVE_DATA_SUBSTITUTE
150+
),
151+
"kwargs": (
152+
kwargs if should_send_default_pii() else SENSITIVE_DATA_SUBSTITUTE
153+
),
148154
}
149155

150156
if "exc_info" in hint:

sentry_sdk/integrations/fastapi.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sentry_sdk.scope import should_send_default_pii
88
from sentry_sdk.traces import NoOpStreamedSpan, StreamedSpan
99
from sentry_sdk.tracing import SOURCE_FOR_STYLE, TransactionSource
10+
from sentry_sdk.tracing_utils import has_span_streaming_enabled
1011
from sentry_sdk.utils import transaction_from_function
1112

1213
from typing import TYPE_CHECKING
@@ -19,6 +20,7 @@
1920
from sentry_sdk.integrations.starlette import (
2021
StarletteIntegration,
2122
StarletteRequestExtractor,
23+
_set_request_body_data_on_streaming_segment,
2224
)
2325
except DidNotEnable:
2426
raise DidNotEnable("Starlette is not installed")
@@ -109,7 +111,8 @@ def _sentry_call(*args: "Any", **kwargs: "Any") -> "Any":
109111
old_app = old_get_request_handler(*args, **kwargs)
110112

111113
async def _sentry_app(*args: "Any", **kwargs: "Any") -> "Any":
112-
integration = sentry_sdk.get_client().get_integration(FastApiIntegration)
114+
client = sentry_sdk.get_client()
115+
integration = client.get_integration(FastApiIntegration)
113116
if integration is None:
114117
return await old_app(*args, **kwargs)
115118

@@ -144,6 +147,9 @@ def event_processor(event: "Event", hint: "Dict[str, Any]") -> "Event":
144147
_make_request_event_processor(request, integration)
145148
)
146149

150+
if has_span_streaming_enabled(client.options):
151+
_set_request_body_data_on_streaming_segment(info)
152+
147153
return await old_app(*args, **kwargs)
148154

149155
return _sentry_app

sentry_sdk/integrations/graphene.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ def graphql_span(
143143

144144
_graphql_span = sentry_sdk.start_span(op=op, name=operation_name)
145145

146-
_graphql_span.set_data("graphql.document", source)
146+
if should_send_default_pii():
147+
_graphql_span.set_data("graphql.document", source)
147148
_graphql_span.set_data("graphql.operation.name", operation_name)
148149
_graphql_span.set_data("graphql.operation.type", operation_type)
149150

sentry_sdk/integrations/grpc/aio/server.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __init__(
2525
self: "ServerInterceptor",
2626
find_name: "Callable[[ServicerContext], str] | None" = None,
2727
) -> None:
28-
self._find_method_name = find_name or self._find_name
28+
self._custom_find_name = find_name
2929

3030
super().__init__()
3131

@@ -34,17 +34,21 @@ async def intercept_service(
3434
continuation: "Callable[[HandlerCallDetails], Awaitable[RpcMethodHandler]]",
3535
handler_call_details: "HandlerCallDetails",
3636
) -> "Optional[Awaitable[RpcMethodHandler]]":
37-
self._handler_call_details = handler_call_details
3837
handler = await continuation(handler_call_details)
3938
if handler is None:
4039
return None
4140

41+
method_name = handler_call_details.method
42+
custom_find_name = self._custom_find_name
43+
4244
if not handler.request_streaming and not handler.response_streaming:
4345
handler_factory = grpc.unary_unary_rpc_method_handler
4446

4547
async def wrapped(request: "Any", context: "ServicerContext") -> "Any":
4648
with sentry_sdk.isolation_scope():
47-
name = self._find_method_name(context)
49+
name = (
50+
custom_find_name(context) if custom_find_name else method_name
51+
)
4852
if not name:
4953
return await handler(request, context)
5054

@@ -96,6 +100,3 @@ async def wrapped(request: "Any", context: "ServicerContext") -> "Any": # type:
96100
request_deserializer=handler.request_deserializer,
97101
response_serializer=handler.response_serializer,
98102
)
99-
100-
def _find_name(self, context: "ServicerContext") -> str:
101-
return self._handler_call_details.method

sentry_sdk/integrations/rq.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from sentry_sdk.api import continue_trace
66
from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration
77
from sentry_sdk.integrations.logging import ignore_logger
8+
from sentry_sdk.scope import should_send_default_pii
89
from sentry_sdk.tracing import TransactionSource
910
from sentry_sdk.utils import (
11+
SENSITIVE_DATA_SUBSTITUTE,
1012
capture_internal_exceptions,
1113
ensure_integration_enabled,
1214
event_from_exception,
@@ -140,8 +142,16 @@ def event_processor(event: "Event", hint: "dict[str, Any]") -> "Event":
140142
rq_job = {
141143
"job_id": job.id,
142144
"func": job.func_name,
143-
"args": job.args,
144-
"kwargs": job.kwargs,
145+
"args": (
146+
job.args
147+
if should_send_default_pii()
148+
else SENSITIVE_DATA_SUBSTITUTE
149+
),
150+
"kwargs": (
151+
job.kwargs
152+
if should_send_default_pii()
153+
else SENSITIVE_DATA_SUBSTITUTE
154+
),
145155
"description": job.description,
146156
}
147157

sentry_sdk/integrations/sqlalchemy.py

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
from sentry_sdk.consts import SPANSTATUS, SPANDATA
22
from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
3-
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
3+
from sentry_sdk.tracing_utils import (
4+
add_query_source,
5+
record_sql_queries_supporting_streaming,
6+
)
47
from sentry_sdk.utils import (
58
capture_internal_exceptions,
69
ensure_integration_enabled,
710
parse_version,
811
)
12+
from sentry_sdk.traces import StreamedSpan, SpanStatus
13+
from sentry_sdk.tracing import Span
914

1015
try:
1116
from sqlalchemy.engine import Engine # type: ignore
@@ -20,8 +25,7 @@
2025
from typing import Any
2126
from typing import ContextManager
2227
from typing import Optional
23-
24-
from sentry_sdk.tracing import Span
28+
from typing import Union
2529

2630

2731
class SqlalchemyIntegration(Integration):
@@ -48,7 +52,7 @@ def _before_cursor_execute(
4852
executemany: bool,
4953
*args: "Any",
5054
) -> None:
51-
ctx_mgr = record_sql_queries(
55+
ctx_mgr = record_sql_queries_supporting_streaming(
5256
cursor,
5357
statement,
5458
parameters,
@@ -78,12 +82,19 @@ def _after_cursor_execute(
7882
context, "_sentry_sql_span_manager", None
7983
)
8084

85+
# Record query source immediately before span is finished: accurate end timestamp and before the span is flushed.
86+
span: "Optional[Union[Span, StreamedSpan]]" = getattr(
87+
context, "_sentry_sql_span", None
88+
)
89+
if isinstance(span, StreamedSpan):
90+
with capture_internal_exceptions():
91+
add_query_source(span)
92+
8193
if ctx_mgr is not None:
8294
context._sentry_sql_span_manager = None
8395
ctx_mgr.__exit__(None, None, None)
8496

85-
span: "Optional[Span]" = getattr(context, "_sentry_sql_span", None)
86-
if span is not None:
97+
if isinstance(span, Span):
8798
with capture_internal_exceptions():
8899
add_query_source(span)
89100

@@ -96,7 +107,10 @@ def _handle_error(context: "Any", *args: "Any") -> None:
96107
span: "Optional[Span]" = getattr(execution_context, "_sentry_sql_span", None)
97108

98109
if span is not None:
99-
span.set_status(SPANSTATUS.INTERNAL_ERROR)
110+
if isinstance(span, StreamedSpan):
111+
span.status = SpanStatus.ERROR
112+
else:
113+
span.set_status(SPANSTATUS.INTERNAL_ERROR)
100114

101115
# _after_cursor_execute does not get called for crashing SQL stmts. Judging
102116
# from SQLAlchemy codebase it does seem like any error coming into this
@@ -132,29 +146,43 @@ def _get_db_system(name: str) -> "Optional[str]":
132146
return None
133147

134148

135-
def _set_db_data(span: "Span", conn: "Any") -> None:
149+
def _set_db_data(span: "Union[Span, StreamedSpan]", conn: "Any") -> None:
136150
db_system = _get_db_system(conn.engine.name)
137-
if db_system is not None:
138-
span.set_data(SPANDATA.DB_SYSTEM, db_system)
151+
152+
if isinstance(span, StreamedSpan):
153+
if db_system is not None:
154+
span.set_attribute(SPANDATA.DB_SYSTEM_NAME, db_system)
155+
else:
156+
if db_system is not None:
157+
span.set_data(SPANDATA.DB_SYSTEM, db_system)
158+
159+
if isinstance(span, StreamedSpan):
160+
set_on_span = span.set_attribute
161+
else:
162+
set_on_span = span.set_data
139163

140164
try:
141165
driver = conn.dialect.driver
142166
if driver:
143-
span.set_data(SPANDATA.DB_DRIVER_NAME, driver)
167+
set_on_span(SPANDATA.DB_DRIVER_NAME, driver)
144168
except Exception:
145169
pass
146170

147171
if conn.engine.url is None:
148172
return
149173

150174
db_name = conn.engine.url.database
151-
if db_name is not None:
152-
span.set_data(SPANDATA.DB_NAME, db_name)
175+
if isinstance(span, StreamedSpan):
176+
if db_name is not None:
177+
span.set_attribute(SPANDATA.DB_NAMESPACE, db_name)
178+
else:
179+
if db_name is not None:
180+
span.set_data(SPANDATA.DB_NAME, db_name)
153181

154182
server_address = conn.engine.url.host
155183
if server_address is not None:
156-
span.set_data(SPANDATA.SERVER_ADDRESS, server_address)
184+
set_on_span(SPANDATA.SERVER_ADDRESS, server_address)
157185

158186
server_port = conn.engine.url.port
159187
if server_port is not None:
160-
span.set_data(SPANDATA.SERVER_PORT, server_port)
188+
set_on_span(SPANDATA.SERVER_PORT, server_port)

0 commit comments

Comments
 (0)