Skip to content

Commit b4183bd

Browse files
committed
Merge branch 'master' into feat/new-scopes
2 parents a17cb67 + 64c42ca commit b4183bd

File tree

14 files changed

+212
-48
lines changed

14 files changed

+212
-48
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@
44

55
### Various fixes & improvements
66

7+
- Add support for cluster clients from Redis SDK (#2394) by @md384
78
- Improve location reporting for timer metrics (#2552) by @mitsuhiko
9+
- Fix Celery `TypeError` with no-argument `apply_async` (#2575) by @szokeasaurusrex
10+
- Fix Lambda integration with EventBridge source (#2546) by @davidcroda
11+
- Add max tries to Spotlight (#2571) by @hazAT
12+
- Handle `os.path.devnull` access issues (#2579) by @sentrivana
13+
- Change `code.filepath` frame picking logic (#2568) by @sentrivana
14+
- Trigger AWS Lambda tests on label (#2538) by @sentrivana
15+
- Run permissions step on pull_request_target but not push (#2548) by @sentrivana
16+
- Hash AWS Lambda test functions based on current revision (#2557) by @sentrivana
17+
- Update Django version in tests (#2562) by @sentrivana
18+
- Make metrics tests non-flaky (#2572) by @antonpirker
819

920
## 1.38.0
1021

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
copyright = "2019-{}, Sentry Team and Contributors".format(datetime.now().year)
3131
author = "Sentry Team and Contributors"
3232

33-
release = "1.38.0"
33+
release = "1.39.0"
3434
version = ".".join(release.split(".")[:2]) # The short X.Y version.
3535

3636

sentry_sdk/client.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -469,20 +469,28 @@ def _should_sample_error(
469469
hint, # type: Hint
470470
):
471471
# type: (...) -> bool
472-
sampler = self.options.get("error_sampler", None)
472+
error_sampler = self.options.get("error_sampler", None)
473473

474-
if callable(sampler):
474+
if callable(error_sampler):
475475
with capture_internal_exceptions():
476-
sample_rate = sampler(event, hint)
476+
sample_rate = error_sampler(event, hint)
477477
else:
478478
sample_rate = self.options["sample_rate"]
479479

480480
try:
481481
not_in_sample_rate = sample_rate < 1.0 and random.random() >= sample_rate
482+
except NameError:
483+
logger.warning(
484+
"The provided error_sampler raised an error. Defaulting to sampling the event."
485+
)
486+
487+
# If the error_sampler raised an error, we should sample the event, since the default behavior
488+
# (when no sample_rate or error_sampler is provided) is to sample all events.
489+
not_in_sample_rate = False
482490
except TypeError:
483491
parameter, verb = (
484492
("error_sampler", "returned")
485-
if callable(sampler)
493+
if callable(error_sampler)
486494
else ("sample_rate", "contains")
487495
)
488496
logger.warning(

sentry_sdk/consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,4 @@ def _get_default_options():
316316
del _get_default_options
317317

318318

319-
VERSION = "1.38.0"
319+
VERSION = "1.39.0"

sentry_sdk/integrations/aiohttp.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,13 @@
4444

4545
if TYPE_CHECKING:
4646
from aiohttp.web_request import Request
47-
from aiohttp.abc import AbstractMatchInfo
47+
from aiohttp.web_urldispatcher import UrlMappingMatchInfo
4848
from aiohttp import TraceRequestStartParams, TraceRequestEndParams
4949
from types import SimpleNamespace
5050
from typing import Any
5151
from typing import Dict
5252
from typing import Optional
5353
from typing import Tuple
54-
from typing import Callable
5554
from typing import Union
5655

5756
from sentry_sdk.utils import ExcInfo
@@ -113,8 +112,9 @@ async def sentry_app_handle(self, request, *args, **kwargs):
113112
scope.clear_breadcrumbs()
114113
scope.add_event_processor(_make_request_processor(weak_request))
115114

115+
headers = dict(request.headers)
116116
transaction = continue_trace(
117-
request.headers,
117+
headers,
118118
op=OP.HTTP_SERVER,
119119
# If this transaction name makes it to the UI, AIOHTTP's
120120
# URL resolver did not find a route or died trying.
@@ -141,12 +141,12 @@ async def sentry_app_handle(self, request, *args, **kwargs):
141141
transaction.set_http_status(response.status)
142142
return response
143143

144-
Application._handle = sentry_app_handle
144+
Application._handle = sentry_app_handle # type: ignore[method-assign]
145145

146146
old_urldispatcher_resolve = UrlDispatcher.resolve
147147

148148
async def sentry_urldispatcher_resolve(self, request):
149-
# type: (UrlDispatcher, Request) -> AbstractMatchInfo
149+
# type: (UrlDispatcher, Request) -> UrlMappingMatchInfo
150150
rv = await old_urldispatcher_resolve(self, request)
151151

152152
hub = Hub.current
@@ -173,12 +173,12 @@ async def sentry_urldispatcher_resolve(self, request):
173173

174174
return rv
175175

176-
UrlDispatcher.resolve = sentry_urldispatcher_resolve
176+
UrlDispatcher.resolve = sentry_urldispatcher_resolve # type: ignore[method-assign]
177177

178178
old_client_session_init = ClientSession.__init__
179179

180180
def init(*args, **kwargs):
181-
# type: (Any, Any) -> ClientSession
181+
# type: (Any, Any) -> None
182182
hub = Hub.current
183183
if hub.get_integration(AioHttpIntegration) is None:
184184
return old_client_session_init(*args, **kwargs)
@@ -190,7 +190,7 @@ def init(*args, **kwargs):
190190
kwargs["trace_configs"] = client_trace_configs
191191
return old_client_session_init(*args, **kwargs)
192192

193-
ClientSession.__init__ = init
193+
ClientSession.__init__ = init # type: ignore[method-assign]
194194

195195

196196
def create_trace_config():
@@ -253,7 +253,7 @@ async def on_request_end(session, trace_config_ctx, params):
253253

254254

255255
def _make_request_processor(weak_request):
256-
# type: (Callable[[], Request]) -> EventProcessor
256+
# type: (weakref.ReferenceType[Request]) -> EventProcessor
257257
def aiohttp_processor(
258258
event, # type: Dict[str, Any]
259259
hint, # type: Dict[str, Tuple[type, BaseException, Any]]

sentry_sdk/integrations/asyncpg.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from sentry_sdk.consts import OP, SPANDATA
99
from sentry_sdk.integrations import Integration, DidNotEnable
1010
from sentry_sdk.tracing import Span
11-
from sentry_sdk.tracing_utils import record_sql_queries
11+
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
1212
from sentry_sdk.utils import parse_version, capture_internal_exceptions
1313

1414
try:
@@ -66,8 +66,14 @@ async def _inner(*args: Any, **kwargs: Any) -> T:
6666
return await f(*args, **kwargs)
6767

6868
query = args[1]
69-
with record_sql_queries(hub, None, query, None, None, executemany=False):
69+
with record_sql_queries(
70+
hub, None, query, None, None, executemany=False
71+
) as span:
7072
res = await f(*args, **kwargs)
73+
74+
with capture_internal_exceptions():
75+
add_query_source(hub, span)
76+
7177
return res
7278

7379
return _inner
@@ -118,6 +124,7 @@ async def _inner(*args: Any, **kwargs: Any) -> T:
118124
with _record(hub, None, query, params_list, executemany=executemany) as span:
119125
_set_db_data(span, args[0])
120126
res = await f(*args, **kwargs)
127+
121128
return res
122129

123130
return _inner

sentry_sdk/integrations/django/__init__.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from sentry_sdk.scope import add_global_event_processor
1616
from sentry_sdk.serializer import add_global_repr_processor
1717
from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_URL
18-
from sentry_sdk.tracing_utils import record_sql_queries
18+
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
1919
from sentry_sdk.utils import (
2020
AnnotatedValue,
2121
HAS_REAL_CONTEXTVARS,
@@ -638,7 +638,12 @@ def execute(self, sql, params=None):
638638
self.mogrify,
639639
options,
640640
)
641-
return real_execute(self, sql, params)
641+
result = real_execute(self, sql, params)
642+
643+
with capture_internal_exceptions():
644+
add_query_source(hub, span)
645+
646+
return result
642647

643648
def executemany(self, sql, param_list):
644649
# type: (CursorWrapper, Any, List[Any]) -> Any
@@ -650,7 +655,13 @@ def executemany(self, sql, param_list):
650655
hub, self.cursor, sql, param_list, paramstyle="format", executemany=True
651656
) as span:
652657
_set_db_data(span, self)
653-
return real_executemany(self, sql, param_list)
658+
659+
result = real_executemany(self, sql, param_list)
660+
661+
with capture_internal_exceptions():
662+
add_query_source(hub, span)
663+
664+
return result
654665

655666
def connect(self):
656667
# type: (BaseDatabaseWrapper) -> None

sentry_sdk/integrations/sqlalchemy.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
from sentry_sdk.db.explain_plan.sqlalchemy import attach_explain_plan_to_span
77
from sentry_sdk.hub import Hub
88
from sentry_sdk.integrations import Integration, DidNotEnable
9-
from sentry_sdk.tracing_utils import record_sql_queries
10-
11-
from sentry_sdk.utils import parse_version
9+
from sentry_sdk.tracing_utils import add_query_source, record_sql_queries
10+
from sentry_sdk.utils import capture_internal_exceptions, parse_version
1211

1312
try:
1413
from sqlalchemy.engine import Engine # type: ignore
@@ -84,6 +83,10 @@ def _before_cursor_execute(
8483

8584
def _after_cursor_execute(conn, cursor, statement, parameters, context, *args):
8685
# type: (Any, Any, Any, Any, Any, *Any) -> None
86+
hub = Hub.current
87+
if hub.get_integration(SqlalchemyIntegration) is None:
88+
return
89+
8790
ctx_mgr = getattr(
8891
context, "_sentry_sql_span_manager", None
8992
) # type: Optional[ContextManager[Any]]
@@ -92,6 +95,11 @@ def _after_cursor_execute(conn, cursor, statement, parameters, context, *args):
9295
context._sentry_sql_span_manager = None
9396
ctx_mgr.__exit__(None, None, None)
9497

98+
span = context._sentry_sql_span
99+
if span is not None:
100+
with capture_internal_exceptions():
101+
add_query_source(hub, span)
102+
95103

96104
def _handle_error(context, *args):
97105
# type: (Any, *Any) -> None

sentry_sdk/tracing.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,6 @@ def finish(self, hub=None, end_timestamp=None):
488488
self.timestamp = datetime_utcnow()
489489

490490
maybe_create_breadcrumbs_from_span(hub, self)
491-
add_additional_span_data(hub, self)
492491

493492
return None
494493

@@ -1021,7 +1020,6 @@ async def my_async_function():
10211020
from sentry_sdk.tracing_utils import (
10221021
Baggage,
10231022
EnvironHeaders,
1024-
add_additional_span_data,
10251023
extract_sentrytrace_data,
10261024
has_tracing_enabled,
10271025
maybe_create_breadcrumbs_from_span,

sentry_sdk/tracing_utils.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import contextlib
2+
import os
23
import re
34
import sys
45

@@ -11,6 +12,7 @@
1112
to_string,
1213
is_sentry_url,
1314
_is_external_source,
15+
_module_in_list,
1416
)
1517
from sentry_sdk._compat import PY2, iteritems
1618
from sentry_sdk._types import TYPE_CHECKING
@@ -190,29 +192,44 @@ def add_query_source(hub, span):
190192
return
191193

192194
project_root = client.options["project_root"]
195+
in_app_include = client.options.get("in_app_include")
196+
in_app_exclude = client.options.get("in_app_exclude")
193197

194198
# Find the correct frame
195199
frame = sys._getframe() # type: Union[FrameType, None]
196200
while frame is not None:
197201
try:
198202
abs_path = frame.f_code.co_filename
203+
if abs_path and PY2:
204+
abs_path = os.path.abspath(abs_path)
199205
except Exception:
200206
abs_path = ""
201207

202208
try:
203-
namespace = frame.f_globals.get("__name__")
209+
namespace = frame.f_globals.get("__name__") # type: Optional[str]
204210
except Exception:
205211
namespace = None
206212

207213
is_sentry_sdk_frame = namespace is not None and namespace.startswith(
208214
"sentry_sdk."
209215
)
216+
217+
should_be_included = not _is_external_source(abs_path)
218+
if namespace is not None:
219+
if in_app_exclude and _module_in_list(namespace, in_app_exclude):
220+
should_be_included = False
221+
if in_app_include and _module_in_list(namespace, in_app_include):
222+
# in_app_include takes precedence over in_app_exclude, so doing it
223+
# at the end
224+
should_be_included = True
225+
210226
if (
211227
abs_path.startswith(project_root)
212-
and not _is_external_source(abs_path)
228+
and should_be_included
213229
and not is_sentry_sdk_frame
214230
):
215231
break
232+
216233
frame = frame.f_back
217234
else:
218235
frame = None
@@ -250,15 +267,6 @@ def add_query_source(hub, span):
250267
span.set_data(SPANDATA.CODE_FUNCTION, frame.f_code.co_name)
251268

252269

253-
def add_additional_span_data(hub, span):
254-
# type: (sentry_sdk.Hub, sentry_sdk.tracing.Span) -> None
255-
"""
256-
Adds additional data to the span
257-
"""
258-
if span.op == OP.DB:
259-
add_query_source(hub, span)
260-
261-
262270
def extract_sentrytrace_data(header):
263271
# type: (Optional[str]) -> Optional[Dict[str, Union[str, bool, None]]]
264272
"""

0 commit comments

Comments
 (0)