Skip to content

Commit 27dd403

Browse files
committed
feat: use already calculated exc_text
The logging module sets the traceback string to `record.exc_text` and doesn't caluclate it again. This allows also to log exceptions, when we are not in the stack-context anymore and have no `exc_info` tuple. For example, in some cases, only the textual representation of a traceback is stored because the traceback object would be a memory leak and prevent garbage collection. Use case is therefor: `formatter.format(record)` where `exc_text` was already created by another earlier formatter or filter.
1 parent 4cb4158 commit 27dd403

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

src/logfmter/formatter.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,7 @@ def format_exc_info(cls, exc_info: ExcInfo) -> str:
106106
except Exception:
107107
logging.exception()
108108
"""
109-
# Tracebacks have a single trailing newline that we don't need.
110-
value = "".join(traceback.format_exception(*exc_info)).rstrip("\n")
111-
112-
return cls.format_string(value)
109+
return "".join(traceback.format_exception(*exc_info))
113110

114111
@classmethod
115112
def format_params(cls, params: dict) -> str:
@@ -242,10 +239,15 @@ def format(self, record: logging.LogRecord) -> str:
242239
if formatted_params:
243240
tokens.append(formatted_params)
244241

245-
if record.exc_info:
242+
if record.exc_info and not record.exc_text:
246243
# Cast exc_info to its not null variant to make mypy happy.
247244
exc_info = cast(ExcInfo, record.exc_info)
248-
tokens.append(f"exc_info={self.format_exc_info(exc_info)}")
245+
record.exc_text = self.format_exc_info(exc_info)
246+
247+
if record.exc_text:
248+
# Tracebacks have a single trailing newline that we don't need.
249+
exc_text = record.exc_text.rstrip("\n")
250+
tokens.append(f"exc_info={self.format_string(exc_text)}")
249251

250252
if record.stack_info:
251253
stack_info = self.formatStack(record.stack_info).rstrip("\n")

0 commit comments

Comments
 (0)