Skip to content

Commit 3da615b

Browse files
authored
ref: Remove serializer class (getsentry#518)
* ref: Remove serializer class * fix: Fix tests * fix: Fix one bug in Memo about reentrance, fix debuggability of internal crashes * fix: Fix concurrency bug * fix: Work around pytest bugs * ref: Add opt-in JS-style serializer behavior * fix: Rename serialize_databag to partial_serialize * fix: Fix tests * ref: Invoke partial_serialize everywhere * ref: Remove defaults from consts * fix: Fix mypy build * fix: Remove double-import
1 parent de4afa9 commit 3da615b

20 files changed

+364
-226
lines changed

sentry_sdk/client.py

+27-26
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
get_type_name,
1111
capture_internal_exceptions,
1212
current_stacktrace,
13+
disable_capture_event,
1314
logger,
1415
)
15-
from sentry_sdk.serializer import Serializer
16+
from sentry_sdk.serializer import serialize, partial_serialize
1617
from sentry_sdk.transport import make_transport
1718
from sentry_sdk.consts import DEFAULT_OPTIONS, SDK_INFO, ClientConstructor
1819
from sentry_sdk.integrations import setup_integrations
@@ -31,7 +32,6 @@
3132

3233

3334
_client_init_debug = ContextVar("client_init_debug")
34-
_client_in_capture_event = ContextVar("client_in_capture_event")
3535

3636

3737
def _get_options(*args, **kwargs):
@@ -123,8 +123,13 @@ def _prepare_event(
123123
scope, # type: Optional[Scope]
124124
):
125125
# type: (...) -> Optional[Event]
126+
127+
client = self # type: Client # type: ignore
128+
126129
if event.get("timestamp") is None:
127-
event["timestamp"] = datetime.utcnow()
130+
event["timestamp"] = partial_serialize(
131+
client, datetime.utcnow(), is_databag=False, should_repr_strings=False
132+
)
128133

129134
hint = dict(hint or ()) # type: Hint
130135

@@ -170,8 +175,10 @@ def _prepare_event(
170175

171176
# Postprocess the event here so that annotated types do
172177
# generally not surface in before_send
173-
if event is not None:
174-
event = Serializer().serialize_event(event)
178+
if event is not None and not self.options["_experiments"].get(
179+
"fast_serialize", False
180+
):
181+
event = serialize(event)
175182

176183
before_send = self.options["before_send"]
177184
if before_send is not None:
@@ -241,29 +248,23 @@ def capture_event(
241248
242249
:returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
243250
"""
244-
is_recursive = _client_in_capture_event.get(False)
245-
if is_recursive:
251+
if disable_capture_event.get(False):
246252
return None
247253

248-
_client_in_capture_event.set(True)
249-
250-
try:
251-
if self.transport is None:
252-
return None
253-
if hint is None:
254-
hint = {}
255-
event_id = event.get("event_id")
256-
if event_id is None:
257-
event["event_id"] = event_id = uuid.uuid4().hex
258-
if not self._should_capture(event, hint, scope):
259-
return None
260-
event_opt = self._prepare_event(event, hint, scope)
261-
if event_opt is None:
262-
return None
263-
self.transport.capture_event(event_opt)
264-
return event_id
265-
finally:
266-
_client_in_capture_event.set(False)
254+
if self.transport is None:
255+
return None
256+
if hint is None:
257+
hint = {}
258+
event_id = event.get("event_id")
259+
if event_id is None:
260+
event["event_id"] = event_id = uuid.uuid4().hex
261+
if not self._should_capture(event, hint, scope):
262+
return None
263+
event_opt = self._prepare_event(event, hint, scope)
264+
if event_opt is None:
265+
return None
266+
self.transport.capture_event(event_opt)
267+
return event_id
267268

268269
def close(
269270
self,

sentry_sdk/hub.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from sentry_sdk.scope import Scope
1212
from sentry_sdk.client import Client
1313
from sentry_sdk.tracing import Span
14+
from sentry_sdk.serializer import partial_serialize
1415
from sentry_sdk.utils import (
1516
exc_info_from_error,
1617
event_from_exception,
@@ -332,7 +333,14 @@ def capture_message(
332333
return None
333334
if level is None:
334335
level = "info"
335-
return self.capture_event({"message": message, "level": level})
336+
return self.capture_event(
337+
{
338+
"message": partial_serialize(
339+
self.client, message, should_repr_strings=False
340+
),
341+
"level": level,
342+
}
343+
)
336344

337345
def capture_exception(
338346
self, error=None # type: Optional[Union[BaseException, ExcInfo]]
@@ -404,6 +412,8 @@ def add_breadcrumb(
404412
if crumb.get("type") is None:
405413
crumb["type"] = "default"
406414

415+
crumb = partial_serialize(client, crumb, should_repr_strings=False)
416+
407417
if client.options["before_breadcrumb"] is not None:
408418
new_crumb = client.options["before_breadcrumb"](crumb, hint)
409419
else:

sentry_sdk/integrations/_wsgi_common.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22

3+
from sentry_sdk.serializer import partial_serialize
34
from sentry_sdk.hub import Hub, _should_send_default_pii
45
from sentry_sdk.utils import AnnotatedValue
56
from sentry_sdk._compat import text_type, iteritems
@@ -42,7 +43,7 @@ def extract_into_event(self, event):
4243
data = None # type: Optional[Union[AnnotatedValue, Dict[str, Any]]]
4344

4445
content_length = self.content_length()
45-
request_info = event.setdefault("request", {})
46+
request_info = event.get("request", {})
4647

4748
if _should_send_default_pii():
4849
request_info["cookies"] = dict(self.cookies())
@@ -67,9 +68,12 @@ def extract_into_event(self, event):
6768
{"rem": [["!raw", "x", 0, content_length]], "len": content_length},
6869
)
6970
else:
70-
return
71+
data = None
7172

72-
request_info["data"] = data
73+
if data is not None:
74+
request_info["data"] = data
75+
76+
event["request"] = partial_serialize(client, request_info)
7377

7478
def content_length(self):
7579
# type: () -> int

sentry_sdk/integrations/aiohttp.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sentry_sdk.integrations import Integration
77
from sentry_sdk.integrations.logging import ignore_logger
88
from sentry_sdk.integrations._wsgi_common import _filter_headers
9+
from sentry_sdk.serializer import partial_serialize
910
from sentry_sdk.utils import (
1011
capture_internal_exceptions,
1112
event_from_exception,
@@ -130,7 +131,11 @@ def aiohttp_processor(
130131
request_info["query_string"] = request.query_string
131132
request_info["method"] = request.method
132133
request_info["env"] = {"REMOTE_ADDR": request.remote}
133-
request_info["headers"] = _filter_headers(dict(request.headers))
134+
request_info["headers"] = partial_serialize(
135+
Hub.current.client,
136+
_filter_headers(dict(request.headers)),
137+
should_repr_strings=False,
138+
)
134139

135140
return event
136141

sentry_sdk/integrations/asgi.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from sentry_sdk._types import MYPY
1111
from sentry_sdk.hub import Hub, _should_send_default_pii
1212
from sentry_sdk.integrations._wsgi_common import _filter_headers
13+
from sentry_sdk.serializer import partial_serialize
1314
from sentry_sdk.utils import ContextVar, event_from_exception, transaction_from_function
1415
from sentry_sdk.tracing import Span
1516

@@ -96,7 +97,7 @@ async def _run_app(self, scope, callback):
9697

9798
def event_processor(self, event, hint, asgi_scope):
9899
# type: (Event, Hint, Any) -> Optional[Event]
99-
request_info = event.setdefault("request", {})
100+
request_info = event.get("request", {})
100101

101102
if asgi_scope["type"] in ("http", "websocket"):
102103
request_info["url"] = self.get_url(asgi_scope)
@@ -112,6 +113,11 @@ def event_processor(self, event, hint, asgi_scope):
112113
# done, which is sometime after the request has started. If we have
113114
# an endpoint, overwrite our path-based transaction name.
114115
event["transaction"] = self.get_transaction(asgi_scope)
116+
117+
event["request"] = partial_serialize(
118+
Hub.current.client, request_info, should_repr_strings=False
119+
)
120+
115121
return event
116122

117123
def get_url(self, scope):

sentry_sdk/integrations/aws_lambda.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from sentry_sdk.hub import Hub, _should_send_default_pii
44
from sentry_sdk._compat import reraise
5+
from sentry_sdk.serializer import partial_serialize
56
from sentry_sdk.utils import (
67
AnnotatedValue,
78
capture_internal_exceptions,
@@ -169,7 +170,7 @@ def event_processor(event, hint):
169170
"aws_request_id": aws_context.aws_request_id,
170171
}
171172

172-
request = event.setdefault("request", {})
173+
request = event.get("request", {})
173174

174175
if "httpMethod" in aws_event:
175176
request["method"] = aws_event["httpMethod"]
@@ -198,6 +199,10 @@ def event_processor(event, hint):
198199
if ip is not None:
199200
user_info["ip_address"] = ip
200201

202+
event["request"] = partial_serialize(
203+
Hub.current.client, request, should_repr_strings=False
204+
)
205+
201206
return event
202207

203208
return event_processor

sentry_sdk/integrations/celery.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
)
1212

1313
from sentry_sdk.hub import Hub
14+
from sentry_sdk.serializer import partial_serialize
1415
from sentry_sdk.utils import capture_internal_exceptions, event_from_exception
1516
from sentry_sdk.tracing import Span
1617
from sentry_sdk._compat import reraise
@@ -162,11 +163,11 @@ def event_processor(event, hint):
162163
# type: (Event, Hint) -> Optional[Event]
163164
with capture_internal_exceptions():
164165
extra = event.setdefault("extra", {})
165-
extra["celery-job"] = {
166-
"task_name": task.name,
167-
"args": args,
168-
"kwargs": kwargs,
169-
}
166+
extra["celery-job"] = partial_serialize(
167+
Hub.current.client,
168+
{"task_name": task.name, "args": args, "kwargs": kwargs},
169+
should_repr_strings=False,
170+
)
170171

171172
if "exc_info" in hint:
172173
with capture_internal_exceptions():

sentry_sdk/integrations/logging.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import datetime
55

66
from sentry_sdk.hub import Hub
7+
from sentry_sdk.serializer import partial_serialize
78
from sentry_sdk.utils import (
89
to_string,
910
event_from_exception,
@@ -204,7 +205,9 @@ def _emit(self, record):
204205
event["level"] = _logging_to_event_level(record.levelname)
205206
event["logger"] = record.name
206207
event["logentry"] = {"message": to_string(record.msg), "params": record.args}
207-
event["extra"] = _extra_from_record(record)
208+
event["extra"] = partial_serialize(
209+
Hub.current.client, _extra_from_record(record), should_repr_strings=False
210+
)
208211

209212
hub.capture_event(event, hint=hint)
210213

sentry_sdk/integrations/rq.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from sentry_sdk.hub import Hub
66
from sentry_sdk.integrations import Integration
77
from sentry_sdk.tracing import Span
8+
from sentry_sdk.serializer import partial_serialize
89
from sentry_sdk.utils import capture_internal_exceptions, event_from_exception
910

1011
from rq.timeouts import JobTimeoutException
@@ -101,13 +102,17 @@ def event_processor(event, hint):
101102
if job is not None:
102103
with capture_internal_exceptions():
103104
extra = event.setdefault("extra", {})
104-
extra["rq-job"] = {
105-
"job_id": job.id,
106-
"func": job.func_name,
107-
"args": job.args,
108-
"kwargs": job.kwargs,
109-
"description": job.description,
110-
}
105+
extra["rq-job"] = partial_serialize(
106+
Hub.current.client,
107+
{
108+
"job_id": job.id,
109+
"func": job.func_name,
110+
"args": job.args,
111+
"kwargs": job.kwargs,
112+
"description": job.description,
113+
},
114+
should_repr_strings=False,
115+
)
111116

112117
if "exc_info" in hint:
113118
with capture_internal_exceptions():

sentry_sdk/integrations/tornado.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from inspect import iscoroutinefunction
33

44
from sentry_sdk.hub import Hub, _should_send_default_pii
5+
from sentry_sdk.serializer import partial_serialize
56
from sentry_sdk.utils import (
67
HAS_REAL_CONTEXTVARS,
78
event_from_exception,
@@ -151,7 +152,9 @@ def tornado_processor(event, hint):
151152
request.path,
152153
)
153154

154-
request_info["query_string"] = request.query
155+
request_info["query_string"] = partial_serialize(
156+
Hub.current.client, request.query, should_repr_strings=False
157+
)
155158
request_info["method"] = request.method
156159
request_info["env"] = {"REMOTE_ADDR": request.remote_ip}
157160
request_info["headers"] = _filter_headers(dict(request.headers))

sentry_sdk/scope.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
from functools import wraps
44
from itertools import chain
55

6+
import sentry_sdk
7+
68
from sentry_sdk.utils import logger, capture_internal_exceptions
9+
from sentry_sdk.serializer import partial_serialize
10+
711

812
from sentry_sdk._types import MYPY
913

@@ -162,7 +166,9 @@ def set_tag(
162166
):
163167
# type: (...) -> None
164168
"""Sets a tag for a key to a specific value."""
165-
self._tags[key] = value
169+
self._tags[key] = partial_serialize(
170+
sentry_sdk.Hub.current.client, value, should_repr_strings=False
171+
)
166172

167173
def remove_tag(
168174
self, key # type: str
@@ -178,7 +184,9 @@ def set_context(
178184
):
179185
# type: (...) -> None
180186
"""Binds a context at a certain key to a specific value."""
181-
self._contexts[key] = value
187+
self._contexts[key] = partial_serialize(
188+
sentry_sdk.Hub.current.client, value, should_repr_strings=False
189+
)
182190

183191
def remove_context(
184192
self, key # type: str
@@ -194,7 +202,9 @@ def set_extra(
194202
):
195203
# type: (...) -> None
196204
"""Sets an extra key to a specific value."""
197-
self._extras[key] = value
205+
self._extras[key] = partial_serialize(
206+
sentry_sdk.Hub.current.client, value, should_repr_strings=False
207+
)
198208

199209
def remove_extra(
200210
self, key # type: str

0 commit comments

Comments
 (0)