Skip to content

Commit

Permalink
ref: Remove serializer class (#518)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
untitaker committed Oct 1, 2019
1 parent de4afa9 commit 3da615b
Show file tree
Hide file tree
Showing 20 changed files with 364 additions and 226 deletions.
53 changes: 27 additions & 26 deletions sentry_sdk/client.py
Expand Up @@ -10,9 +10,10 @@
get_type_name,
capture_internal_exceptions,
current_stacktrace,
disable_capture_event,
logger,
)
from sentry_sdk.serializer import Serializer
from sentry_sdk.serializer import serialize, partial_serialize
from sentry_sdk.transport import make_transport
from sentry_sdk.consts import DEFAULT_OPTIONS, SDK_INFO, ClientConstructor
from sentry_sdk.integrations import setup_integrations
Expand All @@ -31,7 +32,6 @@


_client_init_debug = ContextVar("client_init_debug")
_client_in_capture_event = ContextVar("client_in_capture_event")


def _get_options(*args, **kwargs):
Expand Down Expand Up @@ -123,8 +123,13 @@ def _prepare_event(
scope, # type: Optional[Scope]
):
# type: (...) -> Optional[Event]

client = self # type: Client # type: ignore

if event.get("timestamp") is None:
event["timestamp"] = datetime.utcnow()
event["timestamp"] = partial_serialize(
client, datetime.utcnow(), is_databag=False, should_repr_strings=False
)

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

Expand Down Expand Up @@ -170,8 +175,10 @@ def _prepare_event(

# Postprocess the event here so that annotated types do
# generally not surface in before_send
if event is not None:
event = Serializer().serialize_event(event)
if event is not None and not self.options["_experiments"].get(
"fast_serialize", False
):
event = serialize(event)

before_send = self.options["before_send"]
if before_send is not None:
Expand Down Expand Up @@ -241,29 +248,23 @@ def capture_event(
: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.
"""
is_recursive = _client_in_capture_event.get(False)
if is_recursive:
if disable_capture_event.get(False):
return None

_client_in_capture_event.set(True)

try:
if self.transport is None:
return None
if hint is None:
hint = {}
event_id = event.get("event_id")
if event_id is None:
event["event_id"] = event_id = uuid.uuid4().hex
if not self._should_capture(event, hint, scope):
return None
event_opt = self._prepare_event(event, hint, scope)
if event_opt is None:
return None
self.transport.capture_event(event_opt)
return event_id
finally:
_client_in_capture_event.set(False)
if self.transport is None:
return None
if hint is None:
hint = {}
event_id = event.get("event_id")
if event_id is None:
event["event_id"] = event_id = uuid.uuid4().hex
if not self._should_capture(event, hint, scope):
return None
event_opt = self._prepare_event(event, hint, scope)
if event_opt is None:
return None
self.transport.capture_event(event_opt)
return event_id

def close(
self,
Expand Down
12 changes: 11 additions & 1 deletion sentry_sdk/hub.py
Expand Up @@ -11,6 +11,7 @@
from sentry_sdk.scope import Scope
from sentry_sdk.client import Client
from sentry_sdk.tracing import Span
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import (
exc_info_from_error,
event_from_exception,
Expand Down Expand Up @@ -332,7 +333,14 @@ def capture_message(
return None
if level is None:
level = "info"
return self.capture_event({"message": message, "level": level})
return self.capture_event(
{
"message": partial_serialize(
self.client, message, should_repr_strings=False
),
"level": level,
}
)

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

crumb = partial_serialize(client, crumb, should_repr_strings=False)

if client.options["before_breadcrumb"] is not None:
new_crumb = client.options["before_breadcrumb"](crumb, hint)
else:
Expand Down
10 changes: 7 additions & 3 deletions sentry_sdk/integrations/_wsgi_common.py
@@ -1,5 +1,6 @@
import json

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

content_length = self.content_length()
request_info = event.setdefault("request", {})
request_info = event.get("request", {})

if _should_send_default_pii():
request_info["cookies"] = dict(self.cookies())
Expand All @@ -67,9 +68,12 @@ def extract_into_event(self, event):
{"rem": [["!raw", "x", 0, content_length]], "len": content_length},
)
else:
return
data = None

request_info["data"] = data
if data is not None:
request_info["data"] = data

event["request"] = partial_serialize(client, request_info)

def content_length(self):
# type: () -> int
Expand Down
7 changes: 6 additions & 1 deletion sentry_sdk/integrations/aiohttp.py
Expand Up @@ -6,6 +6,7 @@
from sentry_sdk.integrations import Integration
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.integrations._wsgi_common import _filter_headers
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import (
capture_internal_exceptions,
event_from_exception,
Expand Down Expand Up @@ -130,7 +131,11 @@ def aiohttp_processor(
request_info["query_string"] = request.query_string
request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote}
request_info["headers"] = _filter_headers(dict(request.headers))
request_info["headers"] = partial_serialize(
Hub.current.client,
_filter_headers(dict(request.headers)),
should_repr_strings=False,
)

return event

Expand Down
8 changes: 7 additions & 1 deletion sentry_sdk/integrations/asgi.py
Expand Up @@ -10,6 +10,7 @@
from sentry_sdk._types import MYPY
from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.integrations._wsgi_common import _filter_headers
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import ContextVar, event_from_exception, transaction_from_function
from sentry_sdk.tracing import Span

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

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

if asgi_scope["type"] in ("http", "websocket"):
request_info["url"] = self.get_url(asgi_scope)
Expand All @@ -112,6 +113,11 @@ def event_processor(self, event, hint, asgi_scope):
# done, which is sometime after the request has started. If we have
# an endpoint, overwrite our path-based transaction name.
event["transaction"] = self.get_transaction(asgi_scope)

event["request"] = partial_serialize(
Hub.current.client, request_info, should_repr_strings=False
)

return event

def get_url(self, scope):
Expand Down
7 changes: 6 additions & 1 deletion sentry_sdk/integrations/aws_lambda.py
Expand Up @@ -2,6 +2,7 @@

from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk._compat import reraise
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import (
AnnotatedValue,
capture_internal_exceptions,
Expand Down Expand Up @@ -169,7 +170,7 @@ def event_processor(event, hint):
"aws_request_id": aws_context.aws_request_id,
}

request = event.setdefault("request", {})
request = event.get("request", {})

if "httpMethod" in aws_event:
request["method"] = aws_event["httpMethod"]
Expand Down Expand Up @@ -198,6 +199,10 @@ def event_processor(event, hint):
if ip is not None:
user_info["ip_address"] = ip

event["request"] = partial_serialize(
Hub.current.client, request, should_repr_strings=False
)

return event

return event_processor
Expand Down
11 changes: 6 additions & 5 deletions sentry_sdk/integrations/celery.py
Expand Up @@ -11,6 +11,7 @@
)

from sentry_sdk.hub import Hub
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import capture_internal_exceptions, event_from_exception
from sentry_sdk.tracing import Span
from sentry_sdk._compat import reraise
Expand Down Expand Up @@ -162,11 +163,11 @@ def event_processor(event, hint):
# type: (Event, Hint) -> Optional[Event]
with capture_internal_exceptions():
extra = event.setdefault("extra", {})
extra["celery-job"] = {
"task_name": task.name,
"args": args,
"kwargs": kwargs,
}
extra["celery-job"] = partial_serialize(
Hub.current.client,
{"task_name": task.name, "args": args, "kwargs": kwargs},
should_repr_strings=False,
)

if "exc_info" in hint:
with capture_internal_exceptions():
Expand Down
5 changes: 4 additions & 1 deletion sentry_sdk/integrations/logging.py
Expand Up @@ -4,6 +4,7 @@
import datetime

from sentry_sdk.hub import Hub
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import (
to_string,
event_from_exception,
Expand Down Expand Up @@ -204,7 +205,9 @@ def _emit(self, record):
event["level"] = _logging_to_event_level(record.levelname)
event["logger"] = record.name
event["logentry"] = {"message": to_string(record.msg), "params": record.args}
event["extra"] = _extra_from_record(record)
event["extra"] = partial_serialize(
Hub.current.client, _extra_from_record(record), should_repr_strings=False
)

hub.capture_event(event, hint=hint)

Expand Down
19 changes: 12 additions & 7 deletions sentry_sdk/integrations/rq.py
Expand Up @@ -5,6 +5,7 @@
from sentry_sdk.hub import Hub
from sentry_sdk.integrations import Integration
from sentry_sdk.tracing import Span
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import capture_internal_exceptions, event_from_exception

from rq.timeouts import JobTimeoutException
Expand Down Expand Up @@ -101,13 +102,17 @@ def event_processor(event, hint):
if job is not None:
with capture_internal_exceptions():
extra = event.setdefault("extra", {})
extra["rq-job"] = {
"job_id": job.id,
"func": job.func_name,
"args": job.args,
"kwargs": job.kwargs,
"description": job.description,
}
extra["rq-job"] = partial_serialize(
Hub.current.client,
{
"job_id": job.id,
"func": job.func_name,
"args": job.args,
"kwargs": job.kwargs,
"description": job.description,
},
should_repr_strings=False,
)

if "exc_info" in hint:
with capture_internal_exceptions():
Expand Down
5 changes: 4 additions & 1 deletion sentry_sdk/integrations/tornado.py
Expand Up @@ -2,6 +2,7 @@
from inspect import iscoroutinefunction

from sentry_sdk.hub import Hub, _should_send_default_pii
from sentry_sdk.serializer import partial_serialize
from sentry_sdk.utils import (
HAS_REAL_CONTEXTVARS,
event_from_exception,
Expand Down Expand Up @@ -151,7 +152,9 @@ def tornado_processor(event, hint):
request.path,
)

request_info["query_string"] = request.query
request_info["query_string"] = partial_serialize(
Hub.current.client, request.query, should_repr_strings=False
)
request_info["method"] = request.method
request_info["env"] = {"REMOTE_ADDR": request.remote_ip}
request_info["headers"] = _filter_headers(dict(request.headers))
Expand Down
16 changes: 13 additions & 3 deletions sentry_sdk/scope.py
Expand Up @@ -3,7 +3,11 @@
from functools import wraps
from itertools import chain

import sentry_sdk

from sentry_sdk.utils import logger, capture_internal_exceptions
from sentry_sdk.serializer import partial_serialize


from sentry_sdk._types import MYPY

Expand Down Expand Up @@ -162,7 +166,9 @@ def set_tag(
):
# type: (...) -> None
"""Sets a tag for a key to a specific value."""
self._tags[key] = value
self._tags[key] = partial_serialize(
sentry_sdk.Hub.current.client, value, should_repr_strings=False
)

def remove_tag(
self, key # type: str
Expand All @@ -178,7 +184,9 @@ def set_context(
):
# type: (...) -> None
"""Binds a context at a certain key to a specific value."""
self._contexts[key] = value
self._contexts[key] = partial_serialize(
sentry_sdk.Hub.current.client, value, should_repr_strings=False
)

def remove_context(
self, key # type: str
Expand All @@ -194,7 +202,9 @@ def set_extra(
):
# type: (...) -> None
"""Sets an extra key to a specific value."""
self._extras[key] = value
self._extras[key] = partial_serialize(
sentry_sdk.Hub.current.client, value, should_repr_strings=False
)

def remove_extra(
self, key # type: str
Expand Down

0 comments on commit 3da615b

Please sign in to comment.