Skip to content

Commit 1210c2c

Browse files
authored
Fix error reporting formatting (#98)
The stacktrace for an error was formatted as: ${message} ${stacktrace} I'm pretty sure I saw that documented in Google Cloud's documentation when I initially implemented this feature, but I can't find it anymore and the current documentation from https://cloud.google.com/error-reporting/docs/formatting-error-messages#log-error now says: > To log an error event that is a stack trace, write the error event as > one of these types: > [...] > > * A `jsonPayload` that includes a `message`, `stack_trace`, or > `exception` field. > > You can specify more than one of those fields. If more than one of > those fields is specified, then the order of evaluation is: `stack_trace`, > then `exception`, and then `message`. > > If the `message` field is evaluated and if it isn't empty, then the > stack trace is captured only when the field contains a stack trace in > one of the supported programming language formats. The stack trace isn't > captured by Error Reporting when an unsupported format is used. > > If your error event is formatted as a `ReportedErrorEvent` object, > then copy its fields to the `jsonPayload`. For more information and an > example, see Log an error that is formatted as a ReportedErrorEvent > object. There's no mention of this weird `${message}\n${stacktrace}` anymore, so let's get rid of it.
1 parent 94c3ce8 commit 1210c2c

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

structlog_gcp/error_reporting.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ def __call__(
2929
event_dict[CLOUD_LOGGING_KEY]["@type"] = ERROR_EVENT_TYPE
3030

3131
# https://cloud.google.com/error-reporting/docs/formatting-error-messages
32-
message = event_dict[CLOUD_LOGGING_KEY]["message"]
33-
error_message = f"{message}\n{exception}"
34-
event_dict[CLOUD_LOGGING_KEY]["stack_trace"] = error_message
32+
event_dict[CLOUD_LOGGING_KEY]["stack_trace"] = exception
3533

3634
return event_dict
3735

tests/fakes.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from typing import Collection
44

5-
from structlog.processors import CallsiteParameter
5+
from structlog._frames import _format_exception
6+
from structlog.processors import CallsiteParameter, _figure_out_exc_info
67
from structlog.typing import EventDict, WrappedLogger
78

89

@@ -34,7 +35,16 @@ def __call__(
3435
def format_exc_info(
3536
logger: WrappedLogger, method_name: str, event_dict: EventDict
3637
) -> EventDict:
37-
exc_info = event_dict.pop("exc_info", None)
38+
exc_info = _figure_out_exc_info(event_dict.pop("exc_info", None))
39+
3840
if exc_info:
39-
event_dict["exception"] = "Traceback blabla"
41+
exception = _format_exception(exc_info)
42+
# Format the exception, but only keep the "Traceback ..." and the
43+
# actual exception line, and skip all the rest.
44+
# We need to skip the middle lines as they contain the path to the
45+
# files, which differs depending on which path the library is tested
46+
# from.
47+
head = exception.splitlines()[0]
48+
tail = exception.splitlines()[-1]
49+
event_dict["exception"] = f"{head}\n...\n{tail}"
4050
return event_dict

tests/test_log.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_exception(stdout: T_stdout, logger: WrappedLogger) -> None:
5757
"foo": "bar",
5858
"severity": "ERROR",
5959
"message": "oh noes",
60-
"stack_trace": "oh noes\nTraceback blabla",
60+
"stack_trace": "Traceback (most recent call last):\n...\nZeroDivisionError: division by zero",
6161
"time": "2023-04-01T08:00:00.000000Z",
6262
}
6363
assert msg == expected
@@ -191,7 +191,7 @@ def test_core_processors_only(
191191
assert "" == output.err
192192
msg = output.out.strip()
193193

194-
# No JSON formmating, no contextvars
194+
# No JSON formatting, no contextvars
195195
expected = "message='test' time='2023-04-01T08:00:00.000000Z' severity='INFO' logging.googleapis.com/sourceLocation={'file': '/app/test.py', 'line': '42', 'function': 'test:test123'}"
196196

197197
assert expected == msg
@@ -225,7 +225,7 @@ def test_exception_different_level(stdout: T_stdout, logger: WrappedLogger) -> N
225225
},
226226
"severity": "WARNING",
227227
"message": "oh no; anyways",
228-
"stack_trace": "oh no; anyways\ndivision by zero",
228+
"stack_trace": "ZeroDivisionError('division by zero')",
229229
"time": "2023-04-01T08:00:00.000000Z",
230230
}
231231
assert msg == expected

0 commit comments

Comments
 (0)