Skip to content

Commit 78ff303

Browse files
committed
feat: add _meta annotations for breadcrumb truncataion
1 parent 968b362 commit 78ff303

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

sentry_sdk/scope.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
Transaction,
3030
)
3131
from sentry_sdk.utils import (
32+
AnnotatedValue,
3233
capture_internal_exception,
3334
capture_internal_exceptions,
3435
ContextVar,
@@ -181,6 +182,7 @@ class Scope:
181182
"_contexts",
182183
"_extras",
183184
"_breadcrumbs",
185+
"_breadcrumb_info",
184186
"_event_processors",
185187
"_error_processors",
186188
"_should_capture",
@@ -205,6 +207,7 @@ def __init__(self, ty=None, client=None):
205207

206208
self._name = None # type: Optional[str]
207209
self._propagation_context = None # type: Optional[PropagationContext]
210+
self._breadcrumb_info = 0 # type: int
208211

209212
self.client = NonRecordingClient() # type: sentry_sdk.client.BaseClient
210213

@@ -238,6 +241,7 @@ def __copy__(self):
238241
rv._extras = dict(self._extras)
239242

240243
rv._breadcrumbs = copy(self._breadcrumbs)
244+
rv._breadcrumb_info = copy(self._breadcrumb_info)
241245
rv._event_processors = list(self._event_processors)
242246
rv._error_processors = list(self._error_processors)
243247
rv._propagation_context = self._propagation_context
@@ -906,6 +910,7 @@ def clear_breadcrumbs(self):
906910
# type: () -> None
907911
"""Clears breadcrumb buffer."""
908912
self._breadcrumbs = deque() # type: Deque[Breadcrumb]
913+
self._breadcrumb_info = 0
909914

910915
def add_attachment(
911916
self,
@@ -973,6 +978,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
973978

974979
while len(self._breadcrumbs) > max_breadcrumbs:
975980
self._breadcrumbs.popleft()
981+
self._breadcrumb_info += 1
976982

977983
def start_transaction(
978984
self,
@@ -1339,6 +1345,12 @@ def _apply_breadcrumbs_to_event(self, event, hint, options):
13391345
logger.debug("Error when sorting breadcrumbs", exc_info=err)
13401346
pass
13411347

1348+
# Add annotation that breadcrumbs were truncated
1349+
original_length = len(event["breadcrumbs"]["values"]) + self._breadcrumb_info
1350+
event["breadcrumbs"]["values"] = AnnotatedValue.truncated_breadcrumbs(
1351+
event["breadcrumbs"]["values"], original_length
1352+
)
1353+
13421354
def _apply_user_to_event(self, event, hint, options):
13431355
# type: (Event, Hint, Optional[Dict[str, Any]]) -> None
13441356
if event.get("user") is None and self._user is not None:

sentry_sdk/scrubber.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,14 @@ def scrub_breadcrumbs(self, event):
146146
with capture_internal_exceptions():
147147
if "breadcrumbs" in event:
148148
if "values" in event["breadcrumbs"]:
149-
for value in event["breadcrumbs"]["values"]:
150-
if "data" in value:
151-
self.scrub_dict(value["data"])
149+
if isinstance(event["breadcrumbs"]["values"], AnnotatedValue):
150+
for value in event["breadcrumbs"]["values"].value:
151+
if "data" in value:
152+
self.scrub_dict(value["data"])
153+
else:
154+
for value in event["breadcrumbs"]["values"]:
155+
if "data" in value:
156+
self.scrub_dict(value["data"])
152157

153158
def scrub_frames(self, event):
154159
# type: (Event) -> None

sentry_sdk/utils.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
from gevent.hub import Hub
6060

61-
from sentry_sdk._types import Event, ExcInfo
61+
from sentry_sdk._types import Breadcrumb, Event, ExcInfo
6262

6363
P = ParamSpec("P")
6464
R = TypeVar("R")
@@ -474,6 +474,15 @@ def substituted_because_contains_sensitive_data(cls):
474474
},
475475
)
476476

477+
@classmethod
478+
def truncated_breadcrumbs(cls, breadcrumbs, n_truncated):
479+
# type: (list[Breadcrumb], int) -> AnnotatedValue
480+
"""Breadcrumbs were removed because the number of breadcrumbs exceeded their maximum limit."""
481+
return AnnotatedValue(
482+
value=breadcrumbs,
483+
metadata={"len": [n_truncated]}, # Remark
484+
)
485+
477486

478487
if TYPE_CHECKING:
479488
from typing import TypeVar

tests/test_client.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
set_tag,
2323
)
2424
from sentry_sdk.spotlight import DEFAULT_SPOTLIGHT_URL
25-
from sentry_sdk.utils import capture_internal_exception
25+
from sentry_sdk.utils import AnnotatedValue, capture_internal_exception
2626
from sentry_sdk.integrations.executing import ExecutingIntegration
2727
from sentry_sdk.transport import Transport
2828
from sentry_sdk.serializer import MAX_DATABAG_BREADTH
@@ -1058,8 +1058,10 @@ def test_max_breadcrumbs_option(
10581058
add_breadcrumb({"type": "sourdough"})
10591059

10601060
capture_message("dogs are great")
1061-
1062-
assert len(events[0]["breadcrumbs"]["values"]) == expected_breadcrumbs
1061+
if isinstance(events[0]["breadcrumbs"]["values"], AnnotatedValue):
1062+
assert len(events[0]["breadcrumbs"]["values"].value) == expected_breadcrumbs
1063+
else:
1064+
assert len(events[0]["breadcrumbs"]["values"]) == expected_breadcrumbs
10631065

10641066

10651067
def test_multiple_positional_args(sentry_init):

tests/test_scrubber.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ def test_breadcrumb_extra_scrubbing(sentry_init, capture_events):
137137

138138
assert event["_meta"]["extra"]["auth"] == {"": {"rem": [["!config", "s"]]}}
139139
assert event["_meta"]["breadcrumbs"] == {
140-
"values": {"0": {"data": {"password": {"": {"rem": [["!config", "s"]]}}}}}
140+
"values": {
141+
"": {"len": [1]},
142+
"0": {"data": {"password": {"": {"rem": [["!config", "s"]]}}}},
143+
}
141144
}
142145

143146

0 commit comments

Comments
 (0)