Repository navigation
Preserve exception tracebacks in Beeper JSON logs - #66
Conversation
|
| "time": round(record.created, 2), | ||
| } | ||
| if record.exc_info and record.exc_info[0]: | ||
| event["exc_traceback"] = self.formatException(record.exc_info) |
There was a problem hiding this comment.
⚪️ Nit · No test for the new exc_traceback field
JsonFormatter and GcpJsonFormatter both have exception tests (test_with_exception, test_gcp_json_with_exception), but nothing tests BeeperTerseJsonFormatter. I ran the formatter by hand and it works: chained traceback present, one line per record, nothing emitted for exc_info=True with no active exception. A test would keep that behavior from regressing when upstream changes to JsonFormatter._format get merged in.
I noticed that
BeeperTerseJsonFormatterdrops the useful part of an exception. Callers passexc_info=(type, value, traceback), but the shared JSON formatter only emitsexc_typeandexc_value. AKeyErrortherefore tells us which key was missing without showing the file, function, or line that tried to read it.This adds an
exc_tracebackfield to the Beeper formatter using Python's existingformatException. The original fields and request metadata stay intact, and traceback newlines are JSON-escaped so each record remains one physical log line. Ordinary records are unchanged. The upstream JSON formatters and the GCP formatter are left alone.I exercised the actual formatter with an ordinary record, a chained
KeyError/RuntimeError, andexc_info=Truewithout an active exception. The chained traceback survived JSON decoding, all three records remained single-line JSON, and local-variable values were not captured. The existing Trial formatter suite could not start locally because Twisted is not installed.The first CI image build failed before building Python: the workflow used the branch name verbatim as a Docker tag, and
/is not valid in a tag. I also normalized branch-name slashes to-in that step; release-version tags are unchanged.