Skip to content

Instantly share code, notes, and snippets.

@skrawcz
Last active October 8, 2021 22:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skrawcz/e7f9c01030cfd9f9d91567672e7183ef to your computer and use it in GitHub Desktop.
Save skrawcz/e7f9c01030cfd9f9d91567672e7183ef to your computer and use it in GitHub Desktop.
JSON Structured Logger
import json
import logging
import sys
logger = logging.getLogger(__name__)
class PyBayFormatter(logging.Formatter):
"""Implementation of JSON structured logging that works for most handlers."""
def format(self, record: logging.LogRecord) -> str:
"""Overrides parent format function.
:param record: logging.LogRecord object
:return: JSON string
"""
payload = self.make_structured_dict(record)
if hasattr(record, 'exc_info') and record.exc_info: # adds stack traces!
payload['stack_trace'] = self.formatException(record.exc_info)
return json.dumps(payload)
@staticmethod
def make_structured_dict(record: logging.LogRecord) -> dict:
"""Creates dictionary that we want to JSON-ify.
:param record: the LogRecord object.
:return: dict
"""
message_str = record.getMessage() # this interpolates it with '%'.
if isinstance(record.args, dict): # handles case for backwards compatibility of people passing multiple args.
user_payload = record.args
else:
user_payload = {'value': repr(record.args)}
return {
'payload': user_payload,
'message': message_str,
'version': '0.0.1', # always good to have a schema version field
'meta': {
'level': record.levelname,
'name': record.name,
'pid': record.process,
'code': {
'file_name': record.filename,
'file_url': record.pathname,
# etc ...
},
}
}
if __name__ == '__main__':
ch = logging.StreamHandler(sys.stdout)
logger.addHandler(ch)
ch.setFormatter(PyBayFormatter())
logger.setLevel(logging.INFO)
client_id = 3
shipment_id = 11110
item_id = 120001
logger.info('Computing scores for item_id: [%(item_id)s] client_id: [%(client_id)s] shipment_id: [%(shipment_id)s]',
{'client_id': client_id, 'item_id': item_id, 'shipment_id': shipment_id})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment