Skip to content

Commit

Permalink
When saving a traceback, shorten very large locals
Browse files Browse the repository at this point in the history
A traceback in `log.txt` can be very large, especially when saving
locals like a huge set of result or junit XML. Adding a level of
traceback verbosity, `locals`, which will log locals, but shorten the
very long ones. `full` will keep showing everything on terminal.
  • Loading branch information
happz committed Jan 14, 2025
1 parent 778d53d commit 1134196
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions tmt/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ def configure_constant(default: int, envvar: str) -> int:
log = fmf.utils.Logging('tmt').logger


#: How many leading characters to display in tracebacks with
#: ``TMT_SHOW_TRACEBACK=2``.
TRACEBACK_LOCALS_TRIM = 1024

# Default workdir root and max
WORKDIR_ROOT = Path('/var/tmp/tmt') # noqa: S108 insecure usage of temporary dir
WORKDIR_MAX = 1000
Expand Down Expand Up @@ -2399,7 +2403,12 @@ class TracebackVerbosity(enum.Enum):
DEFAULT = '0'
#: Render also call stack for exception and each of its causes.
VERBOSE = '1'
#: Render also call stack and local variables for exception and each of its causes.
#: Render also call stack for exception and each of its causes,
#: plus all local variables in each frame, trimmed to first 1024
#: characters of their values.
LOCALS = '2'
#: Render everything that can be show: all causes, their call
#: stacks, all frames and all locals in their completeness.
FULL = 'full'

@classmethod
Expand Down Expand Up @@ -2554,11 +2563,16 @@ def render_exception_stack(
yield f'File {Y(frame.filename)}, line {Y(str(frame.lineno))}, in {Y(frame.name)}'
yield f' {B(frame.line)}'

if traceback_verbosity is TracebackVerbosity.FULL and frame.locals:
if frame.locals:
yield ''

for k, v in frame.locals.items():
yield f' {B(k)} = {Y(v)}'
if traceback_verbosity is TracebackVerbosity.LOCALS:
for k, v in frame.locals.items():
yield f' {B(k)} = {Y(v[:TRACEBACK_LOCALS_TRIM])}'

elif traceback_verbosity is TracebackVerbosity.FULL:
for k, v in frame.locals.items():
yield f' {B(k)} = {Y(v)}'

yield ''

Expand Down Expand Up @@ -2657,7 +2671,7 @@ def _render_exception(traceback_verbosity: TracebackVerbosity) -> Iterator[str]:
GeneralError(f"Cannot log error into logfile '{path}'.", causes=[exc]),
include_logfiles=False)

for line in _render_exception(traceback_verbosity=TracebackVerbosity.FULL):
for line in _render_exception(traceback_verbosity=TracebackVerbosity.LOCALS):
for stream in logfile_streams:
logger.print(line, file=stream)

Expand Down

0 comments on commit 1134196

Please sign in to comment.