8000 fix(sqlalchemy): Change context manager type to avoid race in threads… · tinylambda/sentry-python@de0bc50 · GitHub
[go: up one dir, main page]

Skip to content

Commit de0bc50

Browse files
authored
fix(sqlalchemy): Change context manager type to avoid race in threads (getsentry#1368)
1 parent a6cec41 commit de0bc50

File tree

3 files changed

+57
-49
lines changed

3 files changed

+57
-49
lines changed

sentry_sdk/integrations/django/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sentry_sdk.hub import Hub, _should_send_default_pii
1010
from sentry_sdk.scope import add_global_event_processor
1111
from sentry_sdk.serializer import add_global_repr_processor
12-
from sentry_sdk.tracing_utils import record_sql_queries
12+
from sentry_sdk.tracing_utils import RecordSqlQueries
1313
from sentry_sdk.utils import (
1414
HAS_REAL_CONTEXTVARS,
1515
CONTEXTVARS_ERROR_MESSAGE,
@@ -539,7 +539,7 @@ def execute(self, sql, params=None):
539539
if hub.get_integration(DjangoIntegration) is None:
540540
return real_execute(self, sql, params)
541541

542-
with record_sql_queries(
542+
with RecordSqlQueries(
543543
hub, self.cursor, sql, params, paramstyle="format", executemany=False
544544
):
545545
return real_execute(self, sql, params)
@@ -550,7 +550,7 @@ def executemany(self, sql, param_list):
550550
if hub.get_integration(DjangoIntegration) is None:
551551
return real_executemany(self, sql, param_list)
552552

553-
with record_sql_queries(
553+
with RecordSqlQueries(
554554
hub, self.cursor, sql, param_list, paramstyle="format", executemany=True
555555
):
556556
return real_executemany(self, sql, param_list)

sentry_sdk/integrations/sqlalchemy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from sentry_sdk._types import MYPY
44
from sentry_sdk.hub import Hub
55
from sentry_sdk.integrations import Integration, DidNotEnable
6-
from sentry_sdk.tracing_utils import record_sql_queries
6+
from sentry_sdk.tracing_utils import RecordSqlQueries
77

88
try:
99
from sqlalchemy.engine import Engine # type: ignore
@@ -50,7 +50,7 @@ def _before_cursor_execute(
5050
if hub.get_integration(SqlalchemyIntegration) is None:
5151
return
5252

53-
ctx_mgr = record_sql_queries(
53+
ctx_mgr = RecordSqlQueries(
5454
hub,
5555
cursor,
5656
statement,

sentry_sdk/tracing_utils.py

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import re
2-
import contextlib
32
import json
43
import math
54

@@ -106,6 +105,58 @@ def __iter__(self):
106105
yield k[len(self.prefix) :]
107106

108107

108+
class RecordSqlQueries:
109+
def __init__(
110+
self,
111+
hub, # type: sentry_sdk.Hub
112+
cursor, # type: Any
113+
query, # type: Any
114+
params_list, # type: Any
115+
paramstyle, # type: Optional[str]
116+
executemany, # type: bool
117+
):
118+
# type: (...) -> None
119+
# TODO: Bring back capturing of params by default
120+
self._hub = hub
121+
if self._hub.client and self._hub.client.options["_experiments"].get(
122+
"record_sql_params", False
123+
):
124+
if not params_list or params_list == [None]:
125+
params_list = None
126+
127+
if paramstyle == "pyformat":
128+
paramstyle = "format"
129+
else:
130+
params_list = None
131+
paramstyle = None
132+
133+
self._query = _format_sql(cursor, query)
134+
135+
self._data = {}
136+
if params_list is not None:
137+
self._data["db.params"] = params_list
138+
if paramstyle is not None:
139+
self._data["db.paramstyle"] = paramstyle
140+
if executemany:
141+
self._data["db.executemany"] = True
142+
143+
def __enter__(self):
144+
# type: () -> Span
145+
with capture_internal_exceptions():
146+
self._hub.add_breadcrumb(
147+
message=self._query, category="query", data=self._data
148+
)
149+
150+
with self._hub.start_span(op="db", description=self._query) as span:
151+
for k, v in self._data.items():
152+
span.set_data(k, v)
153+
return span
154+
155+
def __exit__(self, exc_type, exc_val, exc_tb):
156+
# type: (Any, Any, Any) -> None
157+
pass
158+
159+
109160
def has_tracing_enabled(options):
110161
# type: (Dict[str, Any]) -> bool
111162
"""
@@ -150,49 +201,6 @@ def is_valid_sample_rate(rate):
150201
return True
151202

152203

153-
@contextlib.contextmanager
154-
def record_sql_queries(
155-
hub, # type: sentry_sdk.Hub
156-
cursor, # type: Any
157-
query, # type: Any
158-
params_list, # type: Any
159-
paramstyle, # type: Optional[str]
160-
executemany, # type: bool
161-
):
162-
# type: (...) -> Generator[Span, None, None]
163-
164-
# TODO: Bring back capturing of params by default
165-
if hub.client and hub.client.options["_experiments"].get(
166-
"record_sql_params", False
167-
):
168-
if not params_list or params_list == [None]:
169-
params_list = None
170-
171-
if paramstyle == "pyformat":
172-
paramstyle = "format"
173-
else:
174-
params_list = None
175-
paramstyle = None
176-
177-
query = _format_sql(cursor, query)
178-
179-
data = {}
180-
if params_list is not None:
181-
data["db.params"] = params_list
182-
if paramstyle is not None:
183-
data["db.paramstyle"] = paramstyle
184-
if executemany:
185-
data["db.executemany"] = True
186-
187-
with capture_internal_exceptions():
188-
hub.add_breadcrumb(message=query, category="query", data=data)
189-
190-
with hub.start_span(op="db", description=query) as span:
191-
for k, v in data.items():
192-
span.set_data(k, v)
193-
yield span
194-
195-
196204
def maybe_create_breadcrumbs_from_span(hub, span):
197205
# type: (sentry_sdk.Hub, Span) -> None
198206
if span.op == "redis":

0 commit comments

Comments
 (0)
0