Skip to content

Commit b6e7b72

Browse files
feat: Remove string truncation for events
1 parent b6c2b16 commit b6e7b72

10 files changed

Lines changed: 192 additions & 153 deletions

File tree

sentry_sdk/consts.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
from enum import Enum
33
from typing import TYPE_CHECKING
44

5-
# up top to prevent circular import due to integration import
6-
# This is more or less an arbitrary large-ish value for now, so that we allow
7-
# pretty long strings (like LLM prompts), but still have *some* upper limit
8-
# until we verify that removing the trimming completely is safe.
9-
DEFAULT_MAX_VALUE_LENGTH = 100_000
5+
DEFAULT_MAX_VALUE_LENGTH = None
106

117
DEFAULT_MAX_STACK_FRAMES = 100
128
DEFAULT_ADD_FULL_STACK = False
@@ -1233,7 +1229,7 @@ def __init__(
12331229
],
12341230
functions_to_trace: "Sequence[Dict[str, str]]" = [], # noqa: B006
12351231
event_scrubber: "Optional[sentry_sdk.scrubber.EventScrubber]" = None,
1236-
max_value_length: int = DEFAULT_MAX_VALUE_LENGTH,
1232+
max_value_length: "Optional[int]" = DEFAULT_MAX_VALUE_LENGTH,
12371233
enable_backpressure_handling: bool = True,
12381234
error_sampler: "Optional[Callable[[Event, Hint], Union[float, bool]]]" = None,
12391235
enable_db_query_source: bool = True,

sentry_sdk/serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def serialize(event: "Dict[str, Any]", **kwargs: "Any") -> "Dict[str, Any]":
103103
* Annotating the payload with the _meta field whenever trimming happens.
104104
105105
:param max_request_body_size: If set to "always", will never trim request bodies.
106-
:param max_value_length: The max length to strip strings to, defaults to sentry_sdk.consts.DEFAULT_MAX_VALUE_LENGTH
106+
:param max_value_length: The max length to strip strings to, or None to disable string truncation. Defaults to None.
107107
:param is_vars: If we're serializing vars early, we want to repr() things that are JSON-serializable to make their type more apparent. For example, it's useful to see the difference between a unicode-string and a bytestring when viewing a stacktrace.
108108
:param custom_repr: A custom repr function that runs before safe_repr on the object to be serialized. If it returns None or throws internally, we will fallback to safe_repr.
109109

sentry_sdk/utils.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
from sentry_sdk.consts import (
4141
DEFAULT_ADD_FULL_STACK,
4242
DEFAULT_MAX_STACK_FRAMES,
43-
DEFAULT_MAX_VALUE_LENGTH,
4443
EndpointType,
4544
)
4645

@@ -754,7 +753,7 @@ def single_exception_from_error_tuple(
754753
if client_options is None:
755754
include_local_variables = True
756755
include_source_context = True
757-
max_value_length = DEFAULT_MAX_VALUE_LENGTH # fallback
756+
max_value_length = None # fallback
758757
custom_repr = None
759758
else:
760759
include_local_variables = client_options["include_local_variables"]
@@ -1268,12 +1267,9 @@ def _get_size_in_bytes(value: str) -> "Optional[int]":
12681267
def strip_string(
12691268
value: str, max_length: "Optional[int]" = None
12701269
) -> "Union[AnnotatedValue, str]":
1271-
if not value:
1270+
if not value or max_length is None:
12721271
return value
12731272

1274-
if max_length is None:
1275-
max_length = DEFAULT_MAX_VALUE_LENGTH
1276-
12771273
byte_size = _get_size_in_bytes(value)
12781274
text_size = len(value)
12791275

tests/integrations/bottle/test_bottle.py

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from werkzeug.wrappers import Response
1010

1111
from sentry_sdk import capture_message
12-
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
1312
from sentry_sdk.integrations.bottle import BottleIntegration
1413
from sentry_sdk.integrations.logging import LoggingIntegration
1514
from sentry_sdk.serializer import MAX_DATABAG_BREADTH
@@ -122,10 +121,17 @@ def index():
122121
assert event["exception"]["values"][0]["mechanism"]["handled"] is False
123122

124123

125-
def test_large_json_request(sentry_init, capture_events, app, get_client):
126-
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")
124+
@pytest.mark.parametrize("max_value_length", [1024, None])
125+
def test_large_json_request(
126+
sentry_init, capture_events, app, get_client, max_value_length
127+
):
128+
sentry_init(
129+
integrations=[BottleIntegration()],
130+
max_request_body_size="always",
131+
max_value_length=max_value_length,
132+
)
127133

128-
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}
134+
data = {"foo": {"bar": "a" * (1034)}}
129135

130136
@app.route("/", method="POST")
131137
def index():
@@ -145,15 +151,17 @@ def index():
145151
assert response[1] == "200 OK"
146152

147153
(event,) = events
148-
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
149-
"": {
150-
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
151-
"rem": [
152-
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
153-
],
154+
155+
if max_value_length:
156+
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
157+
"": {
158+
"len": 1034,
159+
"rem": [["!limit", "x", 1021, 1024]],
160+
}
154161
}
155-
}
156-
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH
162+
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
163+
else:
164+
assert len(event["request"]["data"]["foo"]["bar"]) == 1034
157165

158166

159167
@pytest.mark.parametrize("data", [{}, []], ids=["empty-dict", "empty-list"])
@@ -180,10 +188,17 @@ def index():
180188
assert event["request"]["data"] == data
181189

182190

183-
def test_medium_formdata_request(sentry_init, capture_events, app, get_client):
184-
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")
191+
@pytest.mark.parametrize("max_value_length", [1024, None])
192+
def test_medium_formdata_request(
193+
sentry_init, capture_events, app, get_client, max_value_length
194+
):
195+
sentry_init(
196+
integrations=[BottleIntegration()],
197+
max_request_body_size="always",
198+
max_value_length=max_value_length,
199+
)
185200

186-
data = {"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}
201+
data = {"foo": "a" * (1034)}
187202

188203
@app.route("/", method="POST")
189204
def index():
@@ -200,15 +215,17 @@ def index():
200215
assert response[1] == "200 OK"
201216

202217
(event,) = events
203-
assert event["_meta"]["request"]["data"]["foo"] == {
204-
"": {
205-
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
206-
"rem": [
207-
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
208-
],
218+
219+
if max_value_length:
220+
assert event["_meta"]["request"]["data"]["foo"] == {
221+
"": {
222+
"len": 1034,
223+
"rem": [["!limit", "x", 1021, 1024]],
224+
}
209225
}
210-
}
211-
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH
226+
assert len(event["request"]["data"]["foo"]) == 1024
227+
else:
228+
assert len(event["request"]["data"]["foo"]) == 1034
212229

213230

214231
@pytest.mark.parametrize("input_char", ["a", b"a"])
@@ -242,11 +259,16 @@ def index():
242259
assert not event["request"]["data"]
243260

244261

245-
def test_files_and_form(sentry_init, capture_events, app, get_client):
246-
sentry_init(integrations=[BottleIntegration()], max_request_body_size="always")
262+
@pytest.mark.parametrize("max_value_length", [1024, None])
263+
def test_files_and_form(sentry_init, capture_events, app, get_client, max_value_length):
264+
sentry_init(
265+
integrations=[BottleIntegration()],
266+
max_request_body_size="always",
267+
max_value_length=max_value_length,
268+
)
247269

248270
data = {
249-
"foo": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10),
271+
"foo": "a" * (1034),
250272
"file": (BytesIO(b"hello"), "hello.txt"),
251273
}
252274

@@ -267,15 +289,16 @@ def index():
267289
assert response[1] == "200 OK"
268290

269291
(event,) = events
270-
assert event["_meta"]["request"]["data"]["foo"] == {
271-
"": {
272-
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
273-
"rem": [
274-
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
275-
],
292+
if max_value_length:
293+
assert event["_meta"]["request"]["data"]["foo"] == {
294+
"": {
295+
"len": 1034,
296+
"rem": [["!limit", "x", 1021, 1024]],
297+
}
276298
}
277-
}
278-
assert len(event["request"]["data"]["foo"]) == DEFAULT_MAX_VALUE_LENGTH
299+
assert len(event["request"]["data"]["foo"]) == 1024
300+
else:
301+
assert len(event["request"]["data"]["foo"]) == 1034
279302

280303
assert event["_meta"]["request"]["data"]["file"] == {
281304
"": {

tests/integrations/falcon/test_falcon.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import pytest
66

77
import sentry_sdk
8-
from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH
98
from sentry_sdk.integrations.falcon import FalconIntegration
109
from sentry_sdk.integrations.logging import LoggingIntegration
1110
from sentry_sdk.utils import parse_version
@@ -206,10 +205,15 @@ def on_get(self, req, resp):
206205
assert len(events) == 0
207206

208207

209-
def test_falcon_large_json_request(sentry_init, capture_events):
210-
sentry_init(integrations=[FalconIntegration()], max_request_body_size="always")
208+
@pytest.mark.parametrize("max_value_length", [1024, None])
209+
def test_falcon_large_json_request(sentry_init, capture_events, max_value_length):
210+
sentry_init(
211+
integrations=[FalconIntegration()],
212+
max_request_body_size="always",
213+
max_value_length=max_value_length,
214+
)
211215

212-
data = {"foo": {"bar": "a" * (DEFAULT_MAX_VALUE_LENGTH + 10)}}
216+
data = {"foo": {"bar": "a" * (1034)}}
213217

214218
class Resource:
215219
def on_post(self, req, resp):
@@ -227,15 +231,16 @@ def on_post(self, req, resp):
227231
assert response.status == falcon.HTTP_200
228232

229233
(event,) = events
230-
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
231-
"": {
232-
"len": DEFAULT_MAX_VALUE_LENGTH + 10,
233-
"rem": [
234-
["!limit", "x", DEFAULT_MAX_VALUE_LENGTH - 3, DEFAULT_MAX_VALUE_LENGTH]
235-
],
234+
if max_value_length:
235+
assert event["_meta"]["request"]["data"]["foo"]["bar"] == {
236+
"": {
237+
"len": 1034,
238+
"rem": [["!limit", "x", 1021, 1024]],
239+
}
236240
}
237-
}
238-
assert len(event["request"]["data"]["foo"]["bar"]) == DEFAULT_MAX_VALUE_LENGTH
241+
assert len(event["request"]["data"]["foo"]["bar"]) == 1024
242+
else:
243+
assert len(event["request"]["data"]["foo"]["bar"]) == 1034
239244

240245

241246
@pytest.mark.parametrize("data", [{}, []], ids=["empty-dict", "empty-list"])

0 commit comments

Comments
 (0)