Skip to content

Commit bb68a4f

Browse files
authored
chore(er): max frame setting (#11851)
We add the setting option to specifiy the maximum number of frames to capture while collecting exception replay data. By default this is infinite. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [ ] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
1 parent f594752 commit bb68a4f

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

ddtrace/debugging/_exception/replay.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from ddtrace.internal.rate_limiter import BudgetRateLimiterWithJitter as RateLimiter
2222
from ddtrace.internal.rate_limiter import RateLimitExceeded
2323
from ddtrace.internal.utils.time import HourGlass
24+
from ddtrace.settings.exception_replay import config
2425

2526

2627
log = get_logger(__name__)
@@ -225,15 +226,17 @@ def on_span_exception(
225226

226227
seq = count(1) # 1-based sequence number
227228

228-
while chain:
229+
frames_captured = 0
230+
231+
while chain and frames_captured <= config.max_frames:
229232
exc, _tb = chain.pop() # LIFO: reverse the chain
230233

231234
if _tb is None or _tb.tb_frame is None:
232235
# If we don't have a traceback there isn't much we can do
233236
continue
234237

235238
# DEV: We go from the handler up to the root exception
236-
while _tb:
239+
while _tb and frames_captured <= config.max_frames:
237240
frame = _tb.tb_frame
238241
code = frame.f_code
239242
seq_nr = next(seq)
@@ -263,6 +266,9 @@ def on_span_exception(
263266
# Memoize
264267
frame.f_locals[SNAPSHOT_KEY] = snapshot_id = snapshot.uuid
265268

269+
# Count
270+
frames_captured += 1
271+
266272
# Add correlation tags on the span
267273
span.set_tag_str(FRAME_SNAPSHOT_ID_TAG % seq_nr, snapshot_id)
268274
span.set_tag_str(FRAME_FUNCTION_TAG % seq_nr, code.co_name)

ddtrace/settings/exception_replay.py

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ class ExceptionReplayConfig(En):
1414
help="Enable automatic capturing of exception debugging information",
1515
deprecations=[("debugging.enabled", None, "3.0")],
1616
)
17+
max_frames = En.v(
18+
int,
19+
"replay.capture_max_frames",
20+
default=8,
21+
help_type="int",
22+
help="The maximum number of frames to capture for each exception",
23+
)
1724

1825

1926
config = ExceptionReplayConfig()

tests/telemetry/test_writer.py

+1
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ def test_app_started_event_configuration_override(test_agent_session, run_python
354354
{"name": "DD_DYNAMIC_INSTRUMENTATION_UPLOAD_FLUSH_INTERVAL", "origin": "default", "value": 1.0},
355355
{"name": "DD_DYNAMIC_INSTRUMENTATION_UPLOAD_TIMEOUT", "origin": "default", "value": 30},
356356
{"name": "DD_ENV", "origin": "default", "value": None},
357+
{"name": "DD_EXCEPTION_REPLAY_CAPTURE_MAX_FRAMES", "origin": "default", "value": 8},
357358
{"name": "DD_EXCEPTION_REPLAY_ENABLED", "origin": "env_var", "value": True},
358359
{"name": "DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED", "origin": "default", "value": False},
359360
{"name": "DD_HTTP_CLIENT_TAG_QUERY_STRING", "origin": "default", "value": None},

0 commit comments

Comments
 (0)