Skip to content

Commit 9ad6332

Browse files
author
Matt Curtis
committed
Format logs with call ID and one-line exceptions
Python exception backtraces were sent as multiple separate lines. This is inconvenient for logging services like Papertrail and OCI Logging which create a record for each line. This patch formats the backtrace as a single line. The Call ID is logged with all log lines. This makes it easier to identify which log lines belong to which call. The current time is no longer logged. Log destinations such as Papertrail and OCI Logging record and display the log event time, so this information is redundant.
1 parent 79cbfd1 commit 9ad6332

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

fdk/log.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@
1515
import logging
1616
import os
1717
import sys
18+
from contextvars import ContextVar
19+
20+
21+
__fn_request_id__ = ContextVar("fn_request_id", default=None)
22+
23+
24+
def set_request_id(rid):
25+
__fn_request_id__.set(rid)
26+
27+
28+
class RequestFormatter(logging.Formatter):
29+
def format(self, record):
30+
record.fn_request_id = __fn_request_id__.get()
31+
return super().format(record)
1832

1933

2034
def __setup_logger():
@@ -27,8 +41,8 @@ def __setup_logger():
2741
root.setLevel(logging.DEBUG)
2842

2943
ch = logging.StreamHandler(sys.stderr)
30-
formatter = logging.Formatter(
31-
'%(asctime)s - '
44+
formatter = RequestFormatter(
45+
'%(fn_request_id)s - '
3246
'%(name)s - '
3347
'%(levelname)s - '
3448
'%(message)s'
@@ -48,3 +62,10 @@ def get_logger():
4862

4963
def log(message):
5064
__log__.debug(message)
65+
66+
67+
__request_log__ = logging.getLogger('fn')
68+
69+
70+
def get_request_log():
71+
return __request_log__

fdk/runner.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ async def handle_request(handler_code, format_def, **kwargs):
8181
"""
8282
log.log("in handle_request")
8383
ctx, body = context.context_from_format(format_def, **kwargs)
84+
log.set_request_id(ctx.CallID())
8485
log.log("context provisioned")
8586
try:
8687
response_data = await with_deadline(ctx, handler_code, body)
@@ -96,5 +97,8 @@ async def handle_request(handler_code, format_def, **kwargs):
9697

9798
except (Exception, TimeoutError) as ex:
9899
log.log("exception appeared: {0}".format(ex))
99-
traceback.print_exc(file=sys.stderr)
100+
(exctype, value, tb) = sys.exc_info()
101+
tb_flat = ''.join(
102+
s.replace('\n', '\\n') for s in traceback.format_tb(tb))
103+
log.get_request_log().error('{}:{}'.format(value, tb_flat))
100104
return errors.DispatchException(ctx, 502, str(ex)).response()

0 commit comments

Comments
 (0)